diff --git a/docs/docs/icicle/primitives/hash.md b/docs/docs/icicle/primitives/hash.md index a88bc996fe..4d6bc5f908 100644 --- a/docs/docs/icicle/primitives/hash.md +++ b/docs/docs/icicle/primitives/hash.md @@ -58,23 +58,27 @@ The optional `domain_tag` pointer parameter enables domain separation, allowing ### Poseidon2 [Poseidon2](https://eprint.iacr.org/2023/323.pdf) is a cryptographic hash function designed specifically for field elements. -It is an improved version of the original [Poseidon](https://eprint.iacr.org/2019/458) hash, offering better performance on modern hardware. Poseidon2 is optimized for use with elliptic curve cryptography and finite fields, making it ideal for decentralized systems like blockchain. Its main advantage is balancing strong security with efficient computation, which is crucial for applications that require fast, reliable hashing. +It is an improved version of the original [Poseidon](https://eprint.iacr.org/2019/458) hash, offering better performance on modern hardware. +Poseidon2 is optimized for use with elliptic curve cryptography and finite fields, making it ideal for decentralized systems like blockchain. +Its main advantage is balancing strong security with efficient computation, which is crucial for applications that require fast, reliable hashing. The optional `domain_tag` pointer parameter enables domain separation, allowing isolation of hash outputs across different contexts or applications. -:::info +The supported values of state size ***t*** as defined in [eprint 2023/323](https://eprint.iacr.org/2023/323.pdf) are 2, 3, 4, 8, 12, 16, 20 and 24. +Note that ***t*** sizes 8, 12, 16, 20 and 24 are supported only for small fields (babybear and m31). -The supported values of state size ***t*** as defined in [eprint 2023/323](https://eprint.iacr.org/2023/323.pdf) are 2, 3, 4, 8, 12, 16, 20 and 24. Note that ***t*** sizes 8, 12, 16, 20 and 24 are supported only for small fields (babybear and m31). +The S box power alpha, number of full rounds and partial rounds, rounds constants, MDS matrix, and partial matrix for each field and ***t*** can be +found in this [folder](https://github.com/ingonyama-zk/icicle/tree/9b1506cda9eab30fc6a8d0a338e2cfab877402f7/icicle/include/icicle/hash/poseidon2_constants/constants). -::: +There are two modes for using the Poseidon2 hash - sponge function and non-sponge (merkle tree) function. The key difference between these +modes is their execution pattern. The sponge function is inherently serial (each hash must wait for the previous hash to complete before +starting its own process), while the non-sponge function (which consists of multiple independent hashes that don't share inputs) runs in +parallel using GPU threads, with the number of threads equal to config.batch. +Another difference between two modes is that currently padding is supported for the sponge function and is not supported for the non-sponge. +For the sponge function the config.batch should be equal one. -:::info - -The S box power alpha, number of full rounds and partial rounds, rounds constants, MDS matrix, and partial matrix for each field and ***t*** can be found in this [folder](https://github.com/ingonyama-zk/icicle/tree/9b1506cda9eab30fc6a8d0a338e2cfab877402f7/icicle/include/icicle/hash/poseidon2_constants/constants). - -::: - -In the current version the padding is not supported and should be performed by the user. +The hash function automatically chooses between these modes based on the input size. It runs in sponge mode if the input size (including the +domain_tag if present) is greater than the single hash width (in this case, config.batch should be set to one). Otherwise, it uses the non-sponge mode. ## Using Hash API @@ -177,10 +181,6 @@ eIcicleErr err = keccak256.hash(input.data(), input.size() / config.batch, confi Currently the poseidon sponge mode (sponge function description could be found in Sec 2.1 of [eprint 2019/458](https://eprint.iacr.org/2019/458.pdf)) isn't implemented. -### 5. Poseidon2 sponge function - -Currently the poseidon2 is implemented in compression mode, the sponge mode discussed in [eprint 2023/323](https://eprint.iacr.org/2023/323.pdf) is not implemented. - ### Supported Bindings - [Rust](../rust-bindings/hash) diff --git a/examples/c++/polynomial-multiplication/example.cpp b/examples/c++/polynomial-multiplication/example.cpp index 49d9167762..6c95ee66b2 100644 --- a/examples/c++/polynomial-multiplication/example.cpp +++ b/examples/c++/polynomial-multiplication/example.cpp @@ -99,4 +99,4 @@ int main(int argc, char** argv) ntt_release_domain(); return 0; -} \ No newline at end of file +} diff --git a/examples/rust/arkworks-icicle-conversions/src/main.rs b/examples/rust/arkworks-icicle-conversions/src/main.rs index d4970f62d0..5b6c548878 100644 --- a/examples/rust/arkworks-icicle-conversions/src/main.rs +++ b/examples/rust/arkworks-icicle-conversions/src/main.rs @@ -4,7 +4,7 @@ use std::time::Instant; use ark_bn254::{Fq, Fr, G1Affine as ArkAffine, G1Projective as ArkProjective}; use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM}; -use ark_ff::{BigInteger, PrimeField}; +use ark_ff::{BigInteger, PrimeField, Field}; use icicle_bn254::curve::{G1Affine as IcicleAffine, G1Projective as IcicleProjective, ScalarField as IcicleScalar}; use icicle_core::{ @@ -69,10 +69,11 @@ fn incremental_ark_projective_points(size: usize) -> Vec { //============================================================================================// fn from_ark(ark: &T) -> I where - T: PrimeField, + T: Field, I: FieldImpl, { - let mut ark_bytes = Vec::with_capacity(T::BigInt::NUM_LIMBS * 8 * T::extension_degree() as usize); + + let mut ark_bytes = vec![]; for base_elem in ark.to_base_prime_field_elements() { ark_bytes.extend_from_slice( &base_elem @@ -85,7 +86,7 @@ where fn to_ark(icicle: &I) -> T where - T: PrimeField, + T: Field, I: FieldImpl, { T::from_random_bytes(&icicle.to_bytes_le()).unwrap() diff --git a/icicle/CMakeLists.txt b/icicle/CMakeLists.txt index 45d0e3db71..567022d0b0 100644 --- a/icicle/CMakeLists.txt +++ b/icicle/CMakeLists.txt @@ -37,6 +37,7 @@ option(HASH "Build hashes and tree builders" ON) option(POSEIDON "Build poseidon hash" ON) option(POSEIDON2 "Build poseidon2 hash" ON) option(SUMCHECK "Build sumcheck" ON) +option(GATEOPS "Build gateops" ON) option(SANITIZE "Enable memory address sanitizer" OFF) # address sanitizer diff --git a/icicle/backend/cpu/include/cpu_sumcheck_transcript.h b/icicle/backend/cpu/include/cpu_sumcheck_transcript.h index f634be62c3..49d89f24b8 100644 --- a/icicle/backend/cpu/include/cpu_sumcheck_transcript.h +++ b/icicle/backend/cpu/include/cpu_sumcheck_transcript.h @@ -36,7 +36,7 @@ class CpuSumcheckTranscript std::vector hash_result(hasher.output_size()); hasher.hash(hash_input.data(), hash_input.size(), m_config, hash_result.data()); m_round_idx++; - reduce_hash_result_to_field(m_prev_alpha, hash_result); + m_prev_alpha = S::from(hash_result.data(), hasher.output_size()); return m_prev_alpha; } @@ -56,15 +56,6 @@ class CpuSumcheckTranscript byte_vec.insert(byte_vec.end(), label.begin(), label.end()); } - // convert a vector of bytes to a field - void reduce_hash_result_to_field(S& alpha, const std::vector& hash_result) - { - alpha = S::zero(); - const int nof_bytes_to_copy = std::min(sizeof(alpha), hash_result.size()); - memcpy(&alpha, hash_result.data(), nof_bytes_to_copy); - alpha = alpha * S::one(); - } - // append an integer uint32_t to hash input void append_u32(std::vector& byte_vec, const uint32_t data) { diff --git a/icicle/backend/cpu/src/field/cpu_vec_ops.cpp b/icicle/backend/cpu/src/field/cpu_vec_ops.cpp index c13d877fa4..63a5c35357 100644 --- a/icicle/backend/cpu/src/field/cpu_vec_ops.cpp +++ b/icicle/backend/cpu/src/field/cpu_vec_ops.cpp @@ -25,6 +25,7 @@ enum VecOperation { VECTOR_MUL, VECTOR_DIV, VECTOR_INV, + VECTOR_INPLACE_INV, CONVERT_TO_MONTGOMERY, CONVERT_FROM_MONTGOMERY, VECTOR_SUM, @@ -453,7 +454,7 @@ cpu_vector_accumulate(const Device& device, T* vec_a, const T* vec_b, uint64_t s return cpu_2vectors_op(VecOperation::VECTOR_ADD, vec_a, vec_b, size, config, vec_a); } -REGISTER_VECTOR_ACCUMULATE_BACKEND("CPU", cpu_vector_accumulate); +REGISTER_VECTOR_MUL_ACCUMULATE_BACKEND("CPU", cpu_vector_accumulate); /*********************************** SUB ***********************************/ template @@ -475,6 +476,16 @@ eIcicleError cpu_vector_mul( REGISTER_VECTOR_MUL_BACKEND("CPU", (cpu_vector_mul)); +/*********************************** MUL ACCUMULATE ***********************************/ +template +eIcicleError +cpu_vector_mul_accumulate(const Device& device, T* vec_a, const T* vec_b, uint64_t size, const VecOpsConfig& config) +{ + return cpu_2vectors_op(VecOperation::VECTOR_MUL, vec_a, vec_b, size, config, vec_a); +} + +REGISTER_VECTOR_ACCUMULATE_BACKEND("CPU", cpu_vector_mul_accumulate); + /*********************************** DIV ***********************************/ template eIcicleError cpu_vector_div( @@ -494,6 +505,15 @@ eIcicleError cpu_vector_inv(const Device& device, const T* vec_a, uint64_t size, REGISTER_VECTOR_INV_BACKEND("CPU", cpu_vector_inv); +/*********************************** INPLACE INV ***********************************/ +template +eIcicleError cpu_vector_inplace_inv(const Device& device, T* vec_a, uint64_t size, const VecOpsConfig& config) +{ + return cpu_2vectors_op(VecOperation::VECTOR_INPLACE_INV, vec_a, vec_a, size, config, vec_a); +} + +REGISTER_VECTOR_INPLACE_INV_BACKEND("CPU", cpu_vector_inplace_inv); + /*********************************** CONVERT MONTGOMERY ***********************************/ template eIcicleError cpu_convert_montgomery( @@ -1015,6 +1035,7 @@ REGISTER_VECTOR_ADD_EXT_FIELD_BACKEND("CPU", cpu_vector_add); REGISTER_VECTOR_ACCUMULATE_EXT_FIELD_BACKEND("CPU", cpu_vector_accumulate); REGISTER_VECTOR_SUB_EXT_FIELD_BACKEND("CPU", cpu_vector_sub); REGISTER_VECTOR_MUL_EXT_FIELD_BACKEND("CPU", (cpu_vector_mul)); +REGISTER_VECTOR_MUL_ACCUMULATE_EXT_FIELD_BACKEND("CPU", (cpu_vector_mul_accumulate)); REGISTER_VECTOR_MIXED_MUL_BACKEND("CPU", (cpu_vector_mul)); REGISTER_VECTOR_DIV_EXT_FIELD_BACKEND("CPU", cpu_vector_div); REGISTER_VECTOR_INV_EXT_FIELD_BACKEND("CPU", cpu_vector_inv); diff --git a/icicle/backend/cpu/src/hash/cpu_poseidon2.cpp b/icicle/backend/cpu/src/hash/cpu_poseidon2.cpp index 7f74552769..6f5f6ff583 100644 --- a/icicle/backend/cpu/src/hash/cpu_poseidon2.cpp +++ b/icicle/backend/cpu/src/hash/cpu_poseidon2.cpp @@ -181,7 +181,7 @@ namespace icicle { s_cpu_backend_poseidon2_constants_initialized = true; return eIcicleError::SUCCESS; - } + } // static eIcicleError init_default_constants() template class Poseidon2BackendCPU : public HashBackend @@ -196,33 +196,179 @@ namespace icicle { // For merkle tree size should be equal to the arity of a single hasher multiplier by sizeof(S). // For sponge function it could be any number. + // Size parameter here is in bytes. eIcicleError hash(const std::byte* input, uint64_t size, const HashConfig& config, std::byte* output) const override { - unsigned int arity = m_use_domain_tag ? m_t - 1 : m_t; + const unsigned arity = m_use_domain_tag ? m_t - 1 : m_t; + bool is_sponge = false; + int input_size_in_scalars = size / sizeof(S); + if ((config.batch == 1) && (input_size_in_scalars != (m_use_domain_tag ? m_t - 1 : m_t))) { // Check if sponge + // function. + is_sponge = true; + if (config.batch != 1) { + ICICLE_LOG_ERROR << "The only supported value of config.batch for sponge functions is 1.\n"; + return eIcicleError::INVALID_ARGUMENT; + } + } // sponge function + else { // Non-sponge function. + if ((m_use_domain_tag ? input_size_in_scalars : input_size_in_scalars - 1) % (m_t - 1) != 0) { + ICICLE_LOG_ERROR << "Padding isn't supported for non-sponge function hash. The following should be true: " + "((m_use_domain_tag ? size : size-1) % (m_t-1) != 0).\n"; + return eIcicleError::INVALID_ARGUMENT; + } + } // Non-sponge function. - // Currently sponge and padding functionalities are not supported. - if (size != arity * sizeof(S)) { - ICICLE_LOG_ERROR - << "Sponge function still isn't supported. The following should be true: (size == T) but it is not.\n"; - return eIcicleError::INVALID_ARGUMENT; + const unsigned int T = m_t; + bool is_unsupported_T_for_this_field = poseidon2_constants[T].nof_upper_full_rounds == 0; + if (is_unsupported_T_for_this_field) { + ICICLE_LOG_ERROR << "Unsupported poseidon width (t = " << T << ") for this field! Planned for next version"; + return eIcicleError::API_NOT_IMPLEMENTED; + } + + int alpha = poseidon2_constants[T].alpha; + int nof_upper_full_rounds = poseidon2_constants[T].nof_upper_full_rounds; + int nof_partial_rounds = poseidon2_constants[T].nof_partial_rounds; + int nof_bottom_full_rounds = poseidon2_constants[T].nof_bottom_full_rounds; + S* rounds_constants = poseidon2_constants[T].rounds_constants; + S* mds_matrix = poseidon2_constants[T].mds_matrix; + S* partial_matrix_diagonal_m1 = poseidon2_constants[T].partial_matrix_diagonal_m1; + + // Allocate temporary memory for intermediate calcs and in order not to change the input. + // int sponge_nof_hashers = m_use_domain_tag ? (input_size_in_scalars / arity) : ((input_size_in_scalars - 1) / + // (arity - 1)); int tmp_fields_nof_scalars = is_sponge ? (T * sponge_nof_hashers) : (T * config.batch); S* + // tmp_fields = new S[tmp_fields_nof_scalars]; + S* tmp_fields; + S* tmp_fields_init_ptr; // This pointer to keep initial tmp_fields value to perform a easy rollback when needed. + int sponge_nof_hashers; + const S* in_fields = (S*)(input); + int padding_size = 0; + S* padding; + if (is_sponge) { + if (input_size_in_scalars < T) { // Single hasher in the chain. + sponge_nof_hashers = 1; + padding_size = T - (input_size_in_scalars + (m_use_domain_tag == true)); + } else if (input_size_in_scalars >= T) { // More than a single hasher in the chain. + sponge_nof_hashers = (input_size_in_scalars - !(m_use_domain_tag == true) + (T - 2)) / (T - 1); + bool is_padding_needed = (input_size_in_scalars - !(m_use_domain_tag == true)) % (T - 1); + if (is_padding_needed) { + padding_size = (T - 1) - ((input_size_in_scalars - !(m_use_domain_tag == true)) % (T - 1)); + } + } + if (padding_size > 0) { // Fill padding array with 1,0,0,... + padding = new S[padding_size]; + padding[0] = S::from(1); + for (int i = 1; i < padding_size; i++) { + padding[i] = S::from(0); + } + } + tmp_fields = new S[T * sponge_nof_hashers]; + tmp_fields_init_ptr = tmp_fields; + // Take care of hasher 0. It's done separately of the rest of the hashers because of the domain tag. + if (m_use_domain_tag) { + // Domain tag exists only for the first hasher. For the rest of the hashers this + // input is undefined at this stage and its value will be set later. + // tmp_fields = {{dt, in0}, {undef, in1}, {undef, in2}, etc.} + memcpy(tmp_fields, &m_domain_tag, sizeof(S)); + } else { + // tmp_fields = {{in0 (T inputs)}, {undef, in1 (T-1 inputs)}, {under, in2 (T-1 inputs)}, etc.} + memcpy(tmp_fields, &in_fields[0], sizeof(S)); + in_fields += 1; + } + tmp_fields += 1; + // Take care of rest of the hashers (T-1 scalar to each hasher). + for (int hasher_idx = 0; hasher_idx < sponge_nof_hashers; hasher_idx++) { + if (hasher_idx == sponge_nof_hashers - 1 && padding_size > 0) { + // Last hasher in the chain. Take care of padding if needed. + memcpy(tmp_fields, in_fields, (T - padding_size - 1) * sizeof(S)); + memcpy(tmp_fields + T - padding_size - 1, padding, padding_size * sizeof(S)); + } else { // Not a last hasher in the chain. There is no padding. + memcpy(tmp_fields, in_fields, (T - 1) * sizeof(S)); + } + in_fields += (T - 1); + tmp_fields += T; + } + tmp_fields = tmp_fields_init_ptr; // Rollback to initial value. + } // if (is_sponge) { + else { // Not a sponge function. The is no padding. + // Input of each hash should have domain tag at its input. + // tmp_fields = {{dt, in0 (T-1 inputs)}, {dt, in1 (T-1 inputs)}, {dt, in2 (T-1 inputs)}, etc.} + tmp_fields = new S[T * config.batch]; + tmp_fields_init_ptr = tmp_fields; // Keep tmp_fields pointer for delete. + if (m_use_domain_tag) { + for (int batch_idx = 0; batch_idx < config.batch; batch_idx++) { + memcpy(tmp_fields, &m_domain_tag, sizeof(S)); + memcpy(tmp_fields + 1, in_fields, (T - 1) * sizeof(S)); + in_fields += (T - 1); + tmp_fields += T; + } + tmp_fields = tmp_fields_init_ptr; // Rollback to initial value. + } else { + // tmp_fields = {{in0 (T inputs)}, {in1 (T inputs)}, {in2 (T inputs)}, etc.} + memcpy(tmp_fields, in_fields, T * config.batch * sizeof(S)); + } } - // Call hash_single config.batch times. - for (int batch_hash_idx = 0; batch_hash_idx < config.batch; batch_hash_idx++) { - eIcicleError err = hash_single(input, output); + + // Hashes processing. + if (is_sponge) { + // Call hash_single for hasher[0] + eIcicleError err = hash_single( + tmp_fields /* input */, tmp_fields /* output */, alpha, nof_upper_full_rounds, nof_partial_rounds, + nof_bottom_full_rounds, rounds_constants, mds_matrix, partial_matrix_diagonal_m1); + S* tmp_fields_tmp_ptr = tmp_fields; // Save current pointer in order to access prev output. if (err != eIcicleError::SUCCESS) return err; - input += arity * sizeof(S); - output += sizeof(S); + if (sponge_nof_hashers != 1) { + tmp_fields[T] = tmp_fields[0]; // Current first output is an input to the next hasher. + } + tmp_fields += T; + // Process rest of the hashers. + for (int hasher_idx = 1; hasher_idx < sponge_nof_hashers; hasher_idx++) { + // The first output of the prev hasher is the first input of the current hasher. + // The T-1 new inputs of the current hasher should be added to the T-1 outputs of the + // prev hasher (starting from index 1). + for (int i = 1; i < T; i++) { + tmp_fields[i] = tmp_fields_tmp_ptr[i] + tmp_fields[i]; + } + eIcicleError err = hash_single( + tmp_fields /* input */, tmp_fields /* output */, alpha, nof_upper_full_rounds, nof_partial_rounds, + nof_bottom_full_rounds, rounds_constants, mds_matrix, partial_matrix_diagonal_m1); + tmp_fields_tmp_ptr = tmp_fields; // Save current pointer in order to access prev output. + if (err != eIcicleError::SUCCESS) return err; + if (hasher_idx != sponge_nof_hashers - 1) // Not to do in the last loop to prevent mem leak. + tmp_fields[T] = tmp_fields[0]; // Fill first scalar of the input to the next hasher. + tmp_fields += T; // Now tmp_fields points to input of the next hasher before the addition. + } // for (int hasher_idx = 1; hasher_idx < sponge_nof_hashers; hasher_idx++) { + tmp_fields -= T; // Rollback to the last hasher output. + memcpy(output, (std::byte*)(&tmp_fields[1]), sizeof(S)); + tmp_fields = tmp_fields_init_ptr; // Rollback to initial value. + } else { // Not a sponge function. + for (int batch_hash_idx = 0; batch_hash_idx < config.batch; batch_hash_idx++) { + eIcicleError err = hash_single( + tmp_fields /* input */, tmp_fields /* output */, alpha, nof_upper_full_rounds, nof_partial_rounds, + nof_bottom_full_rounds, rounds_constants, mds_matrix, partial_matrix_diagonal_m1); + if (err != eIcicleError::SUCCESS) return err; + memcpy(output, (std::byte*)(&tmp_fields[1]), sizeof(S)); + tmp_fields += T; + output += sizeof(S); + } + tmp_fields = tmp_fields_init_ptr; // Rollback to initial value. + } + + delete[] tmp_fields; + tmp_fields = nullptr; + if (padding_size != 0) { + delete[] padding; + padding = nullptr; } return eIcicleError::SUCCESS; - } + } // eIcicleError hash(const std::byte* input, uint64_t size, const HashConfig& config, std::byte* output) const + // override private: // // DEBUG start. Do not remove!!! - // void print_state(std::string str, S* state_to_print) const { + // void print_state(std::string str, const S* state_to_print, int count) const { // std::cout << str << std::endl; - // unsigned int T = m_t; - // for (int state_idx = 0; state_idx < T; state_idx++) { // Columns of matrix. + // for (int state_idx = 0; state_idx < count; state_idx++) { // Columns of matrix. // std::cout << std::hex << state_to_print[state_idx] << std::endl; // } // } @@ -236,40 +382,21 @@ namespace icicle { // // DEBUG end // This function performs a single hash according to parameters in the poseidon2_constants[] struct. - eIcicleError hash_single(const std::byte* input, std::byte* output) const + // eIcicleError hash_single(const std::byte* input, std::byte* output) const + eIcicleError hash_single( + S* tmp_fields, + S* hasher_output, + int alpha, + int nof_upper_full_rounds, + int nof_partial_rounds, + int nof_bottom_full_rounds, + S* rounds_constants, + S* mds_matrix, + S* partial_matrix_diagonal_m1) const { const unsigned int T = m_t; - bool is_unsupported_T_for_this_field = poseidon2_constants[T].nof_upper_full_rounds == 0; - if (is_unsupported_T_for_this_field) { - ICICLE_LOG_ERROR << "Unsupported poseidon width (t=" << T << ") for this field! Planned for next version"; - return eIcicleError::API_NOT_IMPLEMENTED; - } - unsigned int alpha = poseidon2_constants[T].alpha; - unsigned int nof_upper_full_rounds = poseidon2_constants[T].nof_upper_full_rounds; - unsigned int nof_partial_rounds = poseidon2_constants[T].nof_partial_rounds; - unsigned int nof_bottom_full_rounds = poseidon2_constants[T].nof_bottom_full_rounds; - // S* rounds_constants = poseidon2_constants[T].rounds_constants; - S* rounds_constants = poseidon2_constants[T].rounds_constants; - S* mds_matrix = poseidon2_constants[T].mds_matrix; - // S* partial_matrix_diagonal = poseidon2_constants[T].partial_matrix_diagonal; - S* partial_matrix_diagonal_m1 = poseidon2_constants[T].partial_matrix_diagonal_m1; - // Allocate temporary memory for intermediate calcs. - S* tmp_fields = new S[T]; - // Casting from bytes to scalar. - const S* in_fields = (S*)(input); - // Copy input scalar to the output (as a temp storage) to be used in the rounds. - // *tmp_fields are used as a temp storage during the calculations in this function. - if (m_use_domain_tag) { - // in that case we hash [domain_tag, t-1 field elements] - memcpy(tmp_fields, &m_domain_tag, sizeof(S)); - memcpy(tmp_fields + 1, in_fields, (T - 1) * sizeof(S)); - } else { - // in that case we hash [t field elements] - memcpy(tmp_fields, in_fields, T * sizeof(S)); - } - - // Pre-rounds full maatrix multiplication. + // Pre-rounds full matrix multiplication. full_matrix_mul_by_vector(tmp_fields, mds_matrix, tmp_fields); // Upper full rounds. @@ -288,10 +415,8 @@ namespace icicle { // Bottom full rounds. full_rounds(nof_bottom_full_rounds, tmp_fields, rounds_constants); - memcpy(output, (std::byte*)(&tmp_fields[1]), sizeof(S)); - - delete[] tmp_fields; - tmp_fields = nullptr; + memcpy(hasher_output, (std::byte*)(tmp_fields), T * sizeof(S)); + // memcpy(output, (std::byte*)(&tmp_fields[1]), sizeof(S)); return eIcicleError::SUCCESS; } // eIcicleError hash_single(const std::byte* input, std::byte* output) const diff --git a/icicle/cmake/field.cmake b/icicle/cmake/field.cmake index b7864c869a..5786b700e9 100644 --- a/icicle/cmake/field.cmake +++ b/icicle/cmake/field.cmake @@ -53,6 +53,7 @@ function(setup_field_target FIELD FIELD_INDEX FEATURES_STRING) handle_poseidon(icicle_field "${FEATURES_LIST}") handle_poseidon2(icicle_field "${FEATURES_LIST}") handle_sumcheck(icicle_field "${FEATURES_LIST}") + handle_gateops(icicle_field "${FEATURES_LIST}") # Add additional feature handling calls here set_target_properties(icicle_field PROPERTIES OUTPUT_NAME "icicle_field_${FIELD}") diff --git a/icicle/cmake/fields_and_curves.cmake b/icicle/cmake/fields_and_curves.cmake index e67f4fd6a7..8af6eafb9e 100644 --- a/icicle/cmake/fields_and_curves.cmake +++ b/icicle/cmake/fields_and_curves.cmake @@ -2,18 +2,18 @@ # Define available fields with an index and their supported features # Format: index:field:features set(ICICLE_FIELDS - 1001:babybear:NTT,EXT_FIELD,POSEIDON,POSEIDON2,SUMCHECK - 1002:stark252:NTT,POSEIDON,POSEIDON2,SUMCHECK - 1003:m31:EXT_FIELD,POSEIDON,POSEIDON2,SUMCHECK - 1004:koalabear:NTT,EXT_FIELD,POSEIDON,POSEIDON2,SUMCHECK + 1001:babybear:NTT,EXT_FIELD,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS + 1002:stark252:NTT,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS + 1003:m31:EXT_FIELD,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS + 1004:koalabear:NTT,EXT_FIELD,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS ) # Define available curves with an index and their supported features # Format: index:curve:features set(ICICLE_CURVES - 1:bn254:NTT,MSM,G2,ECNTT,POSEIDON,POSEIDON2,SUMCHECK - 2:bls12_381:NTT,MSM,G2,ECNTT,POSEIDON,POSEIDON2,SUMCHECK - 3:bls12_377:NTT,MSM,G2,ECNTT,POSEIDON,POSEIDON2,SUMCHECK - 4:bw6_761:NTT,MSM,G2,ECNTT,POSEIDON,POSEIDON2,SUMCHECK - 5:grumpkin:MSM,POSEIDON,POSEIDON2,SUMCHECK + 1:bn254:NTT,MSM,G2,ECNTT,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS + 2:bls12_381:NTT,MSM,G2,ECNTT,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS + 3:bls12_377:NTT,MSM,G2,ECNTT,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS + 4:bw6_761:NTT,MSM,G2,ECNTT,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS + 5:grumpkin:MSM,POSEIDON,POSEIDON2,SUMCHECK,GATEOPS ) diff --git a/icicle/cmake/target_editor.cmake b/icicle/cmake/target_editor.cmake index 64d330aab9..59dee56eb2 100644 --- a/icicle/cmake/target_editor.cmake +++ b/icicle/cmake/target_editor.cmake @@ -99,3 +99,14 @@ function(handle_sumcheck TARGET FEATURE_LIST) set(SUMCHECK OFF CACHE BOOL "SUMCHECK not available for this field" FORCE) endif() endfunction() + + +function(handle_gateops TARGET FEATURE_LIST) + if(GATEOPS AND "GATEOPS" IN_LIST FEATURE_LIST) + target_compile_definitions(${TARGET} PUBLIC GATEOPS=${GATEOPS}) + target_sources(${TARGET} PRIVATE src/sumcheck/sumcheck.cpp src/gate_ops.cpp) + set(GATEOPS ON CACHE BOOL "Enable GATEOPS feature" FORCE) + else() + set(GATEOPS OFF CACHE BOOL "GATEOPS not available for this field" FORCE) + endif() +endfunction() diff --git a/icicle/include/icicle/backend/gate_ops_backend.h b/icicle/include/icicle/backend/gate_ops_backend.h new file mode 100644 index 0000000000..f834c32410 --- /dev/null +++ b/icicle/include/icicle/backend/gate_ops_backend.h @@ -0,0 +1,44 @@ +#pragma once + +#include "icicle/gate_ops.h" +#include "icicle/fields/field_config.h" +using namespace field_config; + +namespace icicle { + /*************************** Backend registration ***************************/ + + using gateEvaluationImpl = std::function& gate_data, + const CalculationData& calc_data, + const HornerData& horner_data, + const GateOpsConfig& config, + scalar_t* results)>; + + void register_gate_evaluation(const std::string& deviceType, gateEvaluationImpl impl); + +#define REGISTER_GATE_EVALUATION_BACKEND(DEVICE_TYPE, FUNC) \ + namespace { \ + static bool UNIQUE(_reg_vec_gate_evaluation) = []() -> bool { \ + register_gate_evaluation(DEVICE_TYPE, FUNC); \ + return true; \ + }(); \ + } + + using lookupsConstraintImpl = std::function& lookup_data, + const LookupConfig& config, + scalar_t* results)>; + + void register_lookups_constraint(const std::string& deviceType, lookupsConstraintImpl impl); + +#define REGISTER_LOOKUP_CONSTRAINT_BACKEND(DEVICE_TYPE, FUNC) \ + namespace { \ + static bool UNIQUE(_reg_vec_lookups_constraint) = []() -> bool { \ + register_lookups_constraint(DEVICE_TYPE, FUNC); \ + return true; \ + }(); \ + } + +} // namespace icicle diff --git a/icicle/include/icicle/backend/vec_ops_backend.h b/icicle/include/icicle/backend/vec_ops_backend.h index 765062842f..e800bb370d 100644 --- a/icicle/include/icicle/backend/vec_ops_backend.h +++ b/icicle/include/icicle/backend/vec_ops_backend.h @@ -10,6 +10,9 @@ namespace icicle { using vectorVectorOpImplInplaceA = std::function; + using VectorOpImplInplaceA = std::function; + using scalarConvertMontgomeryImpl = std::function bool { \ + register_vector_inplace_inv(DEVICE_TYPE, FUNC); \ + return true; \ + }(); \ + } + void register_vector_sub(const std::string& deviceType, scalarVectorOpImpl impl); #define REGISTER_VECTOR_SUB_BACKEND(DEVICE_TYPE, FUNC) \ namespace { \ @@ -130,6 +143,16 @@ namespace icicle { }(); \ } + void register_vector_mul_accumulate(const std::string& deviceType, vectorVectorOpImplInplaceA impl); + +#define REGISTER_VECTOR_MUL_ACCUMULATE_BACKEND(DEVICE_TYPE, FUNC) \ + namespace { \ + static bool UNIQUE(_reg_vec_mul_accumulate) = []() -> bool { \ + register_vector_mul_accumulate(DEVICE_TYPE, FUNC); \ + return true; \ + }(); \ + } + void register_vector_div(const std::string& deviceType, scalarVectorOpImpl impl); #define REGISTER_VECTOR_DIV_BACKEND(DEVICE_TYPE, FUNC) \ @@ -290,6 +313,9 @@ namespace icicle { using extFieldVectorOpImplInplaceA = std::function; + using extFieldOneVectorOpImplInplaceA = std::function; + using extFieldVectorReduceOpImpl = std::function; @@ -342,6 +368,16 @@ namespace icicle { }(); \ } + void register_extension_vector_mul_accumulate(const std::string& deviceType, extFieldVectorOpImpl impl); + + #define REGISTER_VECTOR_MUL_EXT_FIELD_BACKEND(DEVICE_TYPE, FUNC) \ + namespace { \ + static bool UNIQUE(_reg_vec_mul_ext_field) = []() -> bool { \ + register_extension_vector_mul_accumulate(DEVICE_TYPE, FUNC); \ + return true; \ + }(); \ + } + void register_extension_vector_mixed_mul(const std::string& deviceType, mixedVectorOpImpl impl); #define REGISTER_VECTOR_MIXED_MUL_BACKEND(DEVICE_TYPE, FUNC) \ diff --git a/icicle/include/icicle/device_api.h b/icicle/include/icicle/device_api.h index 0768f135c0..617b98cbc3 100644 --- a/icicle/include/icicle/device_api.h +++ b/icicle/include/icicle/device_api.h @@ -246,4 +246,15 @@ namespace icicle { }(); \ } +#define REGISTER_DEVICE_API_AND_SET_AS_DEFAULT(DEVICE_TYPE, API_CLASS) \ + namespace { \ + static bool UNIQUE(_reg_device_##API_CLASS) = []() -> bool { \ + std::shared_ptr apiInstance = std::make_shared(); \ + register_deviceAPI(DEVICE_TYPE, apiInstance); \ + ICICLE_CHECK(icicle_set_default_device(icicle::Device(DEVICE_TYPE))); \ + ICICLE_LOG_INFO << "Successfully loaded " << DEVICE_TYPE << " as default device"; \ + return true; \ + }(); \ + } + } // namespace icicle \ No newline at end of file diff --git a/icicle/include/icicle/fields/field.h b/icicle/include/icicle/fields/field.h index 57d23233fe..60f01fb2c2 100644 --- a/icicle/include/icicle/fields/field.h +++ b/icicle/include/icicle/fields/field.h @@ -116,7 +116,7 @@ class Field static HOST_DEVICE_INLINE Field inv_log_size(uint32_t logn) { if (logn == 0) { return Field{CONFIG::one}; } - base_math::inv_log_size_err(logn, CONFIG::omegas_count); + base_math::index_err(logn, CONFIG::omegas_count); // check if the requested size is within the valid range storage_array const inv = CONFIG::inv; return Field{inv.storages[logn - 1]}; } @@ -239,6 +239,20 @@ class Field } } + // access precomputed values for first step of the from storage function (see below) + static HOST_DEVICE_INLINE Field get_reduced_digit_for_storage_reduction(int i) + { + storage_array const reduced_digits = CONFIG::reduced_digits; + return Field{reduced_digits.storages[i]}; + } + + // access precomputed values for second step of the from storage function (see below) + static HOST_DEVICE_INLINE storage<2 * TLC + 2> get_mod_sub_for_storage_reduction(int i) + { + storage_array const mod_subs = CONFIG::mod_subs; + return mod_subs.storages[i]; + } + template static constexpr HOST_DEVICE_INLINE uint32_t add_limbs(const storage& xs, const storage& ys, storage& rs) @@ -275,6 +289,16 @@ class Field return rv; } + template + static HOST_INLINE storage rand_storage(unsigned non_zero_limbs = NLIMBS) + { + std::uniform_int_distribution distribution; + storage value{}; + for (unsigned i = 0; i < non_zero_limbs; i++) + value.limbs[i] = distribution(rand_generator); + return value; + } + // NOTE this function is used for test and examples - it assumed it is executed on a single-thread (no two threads // accessing rand_generator at the same time) static HOST_INLINE Field rand_host() @@ -369,6 +393,97 @@ class Field xs.limbs_storage, get_m(), get_modulus(), get_modulus<2>(), get_neg_modulus())}; } + /* This function receives a storage object (currently supports up to 576 bits) and reduces it to a field element + between 0 and p. This is done using 3 steps: + 1. Splitting the number into TLC sized digits - xs = x_i * p_i = x_i * 2^(TLC*32*i). + p_i are precomputed modulo p and so the first step is performed multiplying by p_i and accumultaing. + At the end of this step the number is reduced from NLIMBS to 2*TLC+1 (assuming less than 2^32 additions). + 2. The second step subtracts a single precomputed multiple of p in ordr to reduce the number into the range 0 + static constexpr HOST_DEVICE_INLINE Field from(const storage& xs) + { + static_assert(NLIMBS * 32 <= 576); // for now we support up to 576 bits + storage<2 * TLC + 2> rs = {}; // we use 2*TLC+2 and not 2*TLC+1 because for now we don't support an odd number of + // limbs in the storage struct + int constexpr size = NLIMBS / TLC; + // first reduction step: + for (int i = 0; i < size; i++) // future optimization - because we assume a maximum value for size anyway, this loop + // can be unrolled with potential performance benefits + { + const Field& xi = *reinterpret_cast(xs.limbs + i * TLC); // use casting instead of copying + Field pi = get_reduced_digit_for_storage_reduction(i); // use precomputed values - pi = 2^(TLC*32*i) % p + storage<2 * TLC + 2> temp = {}; + storage<2 * TLC>& temp_storage = *reinterpret_cast*>(temp.limbs); + base_math::template multiply_raw(xi.limbs_storage, pi.limbs_storage, temp_storage); // multiplication + base_math::template add_sub_limbs<2 * TLC + 2, false, false>(rs, temp, rs); // accumulation + } + int constexpr extra_limbs = NLIMBS - TLC * size; + if constexpr (extra_limbs > 0) { // handle the extra limbs (when TLC does not divide NLIMBS) + const storage& xi = *reinterpret_cast*>(xs.limbs + size * TLC); + Field pi = get_reduced_digit_for_storage_reduction(size); + storage<2 * TLC + 2> temp = {}; + storage& temp_storage = *reinterpret_cast*>(temp.limbs); + base_math::template multiply_raw(xi, pi.limbs_storage, temp_storage); // multiplication + base_math::template add_sub_limbs<2 * TLC + 2, false, false>(rs, temp, rs); // accumulation + } + // second reduction step: - an alternative for this step would be to use the barret reduction straight away but with + // a larger value of m. + unsigned constexpr msbits_count = 2 * TLC * 32 - (2 * NBITS - 1); + unsigned top_bits = (rs.limbs[2 * TLC] << msbits_count) + (rs.limbs[2 * TLC - 1] >> (32 - msbits_count)); + base_math::template add_sub_limbs<2 * TLC + 2, true, false>( + rs, get_mod_sub_for_storage_reduction(top_bits), + rs); // subtracting the precomputed multiple of p from the look-up table + // third and final step: + storage<2 * TLC>& res = *reinterpret_cast*>(rs.limbs); + return reduce(Wide{res}); // finally, use barret reduction + } + + /* This is the non-template version of the from(storage) function above. It receives an array of bytes and its size + and returns a field element after modular reduction. For now we support up to 576 bits. */ + static constexpr HOST_DEVICE_INLINE Field from(const std::byte* in, unsigned nof_bytes) + { + storage<2 * TLC + 2> rs = {}; // we use 2*TLC+2 and not 2*TLC+1 because for now we don't support an odd number of + // limbs in the storage struct + unsigned constexpr bytes_per_field = TLC * 4; + int size = nof_bytes / bytes_per_field; + // first reduction step: + for (int i = 0; i < size; i++) { + const Field& xi = *reinterpret_cast(in + i * bytes_per_field); // use casting instead of copying + Field pi = get_reduced_digit_for_storage_reduction(i); // use precomputed values - pi = 2^(TLC*32*i) % p + storage<2 * TLC + 2> temp = {}; + storage<2 * TLC>& temp_storage = *reinterpret_cast*>(temp.limbs); + base_math::template multiply_raw(xi.limbs_storage, pi.limbs_storage, temp_storage); // multiplication + base_math::template add_sub_limbs<2 * TLC + 2, false, false>(rs, temp, rs); // accumulation + } + int extra_bytes = nof_bytes - bytes_per_field * size; + if (extra_bytes > 0) { // handle the extra limbs (when TLC does not divide NLIMBS) + std::byte final_bytes[bytes_per_field] = {}; + for (int j = 0; j < extra_bytes; j++) // this copy cannot be avoided in the non-template version + { + final_bytes[j] = in[size * bytes_per_field + j]; + } + const storage& xi = *reinterpret_cast*>(final_bytes); + Field pi = get_reduced_digit_for_storage_reduction(size); + storage<2 * TLC + 2> temp = {}; + storage<2 * TLC>& temp_storage = *reinterpret_cast*>(temp.limbs); + base_math::template multiply_raw(xi, pi.limbs_storage, temp_storage); // multiplication + base_math::template add_sub_limbs<2 * TLC + 2, false, false>(rs, temp, rs); // accumulation + } + // second reduction step: - an alternative for this step would be to use the barret reduction straight away but with + // a larger value of m. + unsigned constexpr msbits_count = 2 * TLC * 32 - (2 * NBITS - 1); + unsigned top_bits = (rs.limbs[2 * TLC] << msbits_count) + (rs.limbs[2 * TLC - 1] >> (32 - msbits_count)); + base_math::template add_sub_limbs<2 * TLC + 2, true, false>( + rs, get_mod_sub_for_storage_reduction(top_bits), + rs); // subtracting the precomputed multiple of p from the look-up table + // third and final step: + storage<2 * TLC>& res = *reinterpret_cast*>(rs.limbs); + return reduce(Wide{res}); // finally, use barret reduction + } + HOST_DEVICE Field& operator=(Field const& other) { #pragma unroll diff --git a/icicle/include/icicle/fields/host_math.h b/icicle/include/icicle/fields/host_math.h index ab4965d270..1bf5260208 100644 --- a/icicle/include/icicle/fields/host_math.h +++ b/icicle/include/icicle/fields/host_math.h @@ -227,13 +227,13 @@ namespace host_math { static HOST_INLINE void multiply_raw_64(const uint64_t* a, const uint64_t* b, uint64_t* r) { #pragma unroll - for (unsigned j = 0; j < NLIMBS_A / 2; j++) { + for (unsigned i = 0; i < NLIMBS_B / 2; i++) { uint64_t carry = 0; #pragma unroll - for (unsigned i = 0; i < NLIMBS_B / 2; i++) { + for (unsigned j = 0; j < NLIMBS_A / 2; j++) { r[j + i] = host_math::madc_cc_64(a[j], b[i], r[j + i], carry); } - r[NLIMBS_A / 2 + j] = carry; + r[NLIMBS_A / 2 + i] = carry; } } @@ -256,8 +256,8 @@ namespace host_math { multiply_raw(const storage& as, const storage& bs, storage& rs) { static_assert( - (NLIMBS_A % 2 == 0 || NLIMBS_A == 1) && (NLIMBS_B % 2 == 0 || NLIMBS_B == 1), - "odd number of limbs is not supported\n"); + ((NLIMBS_A % 2 == 0 || NLIMBS_A == 1) && (NLIMBS_B % 2 == 0 || NLIMBS_B == 1)) || USE_32, + "odd number of limbs is not supported for 64 bit multiplication\n"); if constexpr (USE_32) { multiply_raw_32(as, bs, rs); return; @@ -363,12 +363,13 @@ namespace host_math { { return std::memcmp(xs.limbs, ys.limbs, NLIMBS * sizeof(xs.limbs[0])) == 0; } - static constexpr void inv_log_size_err(uint32_t logn, uint32_t omegas_count) + // this function checks if the given index is within the array range + static constexpr void index_err(uint32_t index, uint32_t max_index) { - if (logn > omegas_count) + if (index > max_index) THROW_ICICLE_ERR( - icicle::eIcicleError::INVALID_ARGUMENT, - "Field: Invalid inv index" + std::to_string(logn) + ">" + std::to_string(omegas_count)); + icicle::eIcicleError::INVALID_ARGUMENT, "Field: index out of range: given index -" + std::to_string(index) + + "> max index - " + std::to_string(max_index)); } template @@ -453,8 +454,9 @@ namespace host_math { template static constexpr void div2(const storage& xs, storage& rs) { - const uint32_t* x = xs.limbs; - uint32_t* r = rs.limbs; + // Note: volatile is used to prevent compiler optimizations that assume strict aliasing rules. + volatile const uint32_t* x = xs.limbs; + volatile uint32_t* r = rs.limbs; if constexpr (NLIMBS > 1) { for (unsigned i = 0; i < NLIMBS - 1; i++) { r[i] = (x[i] >> 1) | (x[i + 1] << 31); diff --git a/icicle/include/icicle/fields/params_gen.h b/icicle/include/icicle/fields/params_gen.h index 3626971b59..8b011877f4 100644 --- a/icicle/include/icicle/fields/params_gen.h +++ b/icicle/include/icicle/fields/params_gen.h @@ -93,6 +93,31 @@ namespace params_gen { } return invs; } + + // This function generates the precomputed values for the second step of the from storage function in the field class. + // However, it is not used due to constexpr computation overflow. Instead, the values are currently generated by a + // python script and appear explicitly in the field config struct. + template + constexpr storage_array get_modulus_subs(const storage& modulus) + { + storage_array mod_subs = {}; + unsigned constexpr bit_shift = 2 * mod_bit_count - 1; + mod_subs.storages[0] = {0}; + for (int i = 1; i < mod_subs_count; i++) { + storage<2 * NLIMBS + 2> temp = {}; + storage rs = {}; + storage mod_sub_factor = {}; + temp.limbs[0] = i; + storage<2 * NLIMBS + 2> candidate = host_math::template left_shift<2 * NLIMBS + 2, bit_shift>(temp); + host_math::template integer_division<2 * NLIMBS + 2, NLIMBS, NLIMBS + 2, true>( // find the closest multiple of p + // to subtract. + candidate, modulus, mod_sub_factor, rs); + storage<2 * NLIMBS + 2> temp2 = {}; + host_math::template multiply_raw(mod_sub_factor, modulus, temp2); + mod_subs.storages[i] = temp2; + } + return mod_subs; + } } // namespace params_gen #define PARAMS(modulus) \ @@ -119,6 +144,9 @@ namespace params_gen { static constexpr unsigned num_of_reductions = \ params_gen::template num_of_reductions(modulus, m); +#define MOD_SQR_SUBS() \ + static constexpr unsigned mod_subs_count = reduced_digits_count << (limbs_count * 32 + 1 - modulus_bit_count); + #define TWIDDLES(modulus, rou) \ static constexpr unsigned omegas_count = params_gen::template two_adicity(modulus); \ static constexpr storage_array inv = \ diff --git a/icicle/include/icicle/fields/snark_fields/bls12_377_base.h b/icicle/include/icicle/fields/snark_fields/bls12_377_base.h index ec540a7de4..4ec914b95a 100644 --- a/icicle/include/icicle/fields/snark_fields/bls12_377_base.h +++ b/icicle/include/icicle/fields/snark_fields/bls12_377_base.h @@ -7,7 +7,1551 @@ namespace bls12_377 { struct fq_config { static constexpr storage<12> modulus = {0x00000001, 0x8508c000, 0x30000000, 0x170b5d44, 0xba094800, 0x1ef3622f, 0x00f5138f, 0x1a22d9f3, 0x6ca1493b, 0xc63b05c0, 0x17c510ea, 0x01ae3a46}; + static constexpr unsigned reduced_digits_count = 2; + static constexpr storage_array reduced_digits = { + {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000}, + {0xffffff68, 0x02cdffff, 0x7fffffb1, 0x51409f83, 0x8a7d3ff2, 0x9f7db3a9, 0x6e7c6305, 0x7b4e97b7, 0x803c84e8, + 0x4cf495bf, 0xe2fdf49a, 0x008d6661}}}; PARAMS(modulus) + MOD_SQR_SUBS() + static constexpr storage_array mod_subs = { + {{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x2f26d7fe, 0x67be6ac6, 0xa1a75ff7, 0xadfd9187, 0x2e6af219, 0xa456fa3b, 0x18239652, 0xcf558eac, 0xb5f414b7, + 0x5c501c65, 0x938f8e78, 0xff550633, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff, 0x00000000, 0x00000000}, + {0x5e4daffc, 0xcf7cd58c, 0x434ebfee, 0x5bfb230f, 0x5cd5e433, 0x48adf476, 0x30472ca5, 0x9eab1d58, 0x6be8296f, + 0xb8a038cb, 0x271f1cf0, 0xfeaa0c67, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff, 0x00000000, 0x00000000}, + {0x8d7487fb, 0xbc440052, 0x14f61fe6, 0x210411db, 0x454a1e4d, 0x0bf850e1, 0x495fd687, 0x882385f7, 0x8e7d8762, + 0xdb2b5af1, 0xd273bc53, 0xffad4ce0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0005ffff, 0x00000000, 0x00000000}, + {0xbc9b5ff9, 0x24026b18, 0xb69d7fde, 0xcf01a362, 0x73b51066, 0xb04f4b1c, 0x61836cd9, 0x577914a3, 0x44719c1a, + 0x377b7757, 0x66034acc, 0xff025314, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0007ffff, 0x00000000, 0x00000000}, + {0xebc237f7, 0x8bc0d5de, 0x5844dfd5, 0x7cff34ea, 0xa2200280, 0x54a64557, 0x79a7032c, 0x26cea34f, 0xfa65b0d2, + 0x93cb93bc, 0xf992d944, 0xfe575947, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0009ffff, 0x00000000, 0x00000000}, + {0x1ae90ff6, 0x788800a5, 0x29ec3fcd, 0x420823b6, 0x8a943c9a, 0x17f0a1c2, 0x92bfad0e, 0x10470bee, 0x1cfb0ec5, + 0xb656b5e3, 0xa4e778a7, 0xff5a99c1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000bffff, 0x00000000, 0x00000000}, + {0x4a0fe7f4, 0xe0466b6b, 0xcb939fc4, 0xf005b53d, 0xb8ff2eb3, 0xbc479bfd, 0xaae34360, 0xdf9c9a9a, 0xd2ef237c, + 0x12a6d248, 0x38770720, 0xfeaf9ff5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000dffff, 0x00000000, 0x00000000}, + {0x7936bff3, 0xcd0d9631, 0x9d3affbc, 0xb50ea409, 0xa17368cd, 0x7f91f868, 0xc3fbed42, 0xc9150339, 0xf584816f, + 0x3531f46e, 0xe3cba683, 0xffb2e06e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000fffff, 0x00000000, 0x00000000}, + {0xa85d97f1, 0x34cc00f7, 0x3ee25fb4, 0x630c3591, 0xcfde5ae7, 0x23e8f2a3, 0xdc1f8395, 0x986a91e5, 0xab789627, + 0x918210d4, 0x775b34fb, 0xff07e6a2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0011ffff, 0x00000000, 0x00000000}, + {0xd7846fef, 0x9c8a6bbd, 0xe089bfab, 0x1109c718, 0xfe494d01, 0xc83fecde, 0xf44319e7, 0x67c02091, 0x616caadf, + 0xedd22d3a, 0x0aeac373, 0xfe5cecd6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0013ffff, 0x00000000, 0x00000000}, + {0x06ab47ee, 0x89519684, 0xb2311fa3, 0xd612b5e4, 0xe6bd871a, 0x8b8a4949, 0x0d5bc3c9, 0x51388931, 0x840208d2, + 0x105d4f60, 0xb63f62d7, 0xff602d4f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0015ffff, 0x00000000, 0x00000000}, + {0x35d21fec, 0xf110014a, 0x53d87f9a, 0x8410476c, 0x15287934, 0x2fe14385, 0x257f5a1c, 0x208e17dd, 0x39f61d8a, + 0x6cad6bc6, 0x49cef14f, 0xfeb53383, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0017ffff, 0x00000000, 0x00000000}, + {0x64f8f7eb, 0xddd72c10, 0x257fdf92, 0x49193638, 0xfd9cb34e, 0xf32b9fef, 0x3e9803fd, 0x0a06807c, 0x5c8b7b7d, + 0x8f388dec, 0xf52390b2, 0xffb873fc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0019ffff, 0x00000000, 0x00000000}, + {0x941fcfe9, 0x459596d6, 0xc7273f8a, 0xf716c7bf, 0x2c07a567, 0x97829a2b, 0x56bb9a50, 0xd95c0f28, 0x127f9034, + 0xeb88aa52, 0x88b31f2a, 0xff0d7a30, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x001bffff, 0x00000000, 0x00000000}, + {0xc346a7e7, 0xad54019c, 0x68ce9f81, 0xa5145947, 0x5a729781, 0x3bd99466, 0x6edf30a3, 0xa8b19dd4, 0xc873a4ec, + 0x47d8c6b7, 0x1c42ada3, 0xfe628064, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x001dffff, 0x00000000, 0x00000000}, + {0xf26d7fe6, 0x9a1b2c62, 0x3a75ff79, 0x6a1d4813, 0x42e6d19b, 0xff23f0d1, 0x87f7da84, 0x922a0673, 0xeb0902df, + 0x6a63e8dd, 0xc7974d06, 0xff65c0dd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x001fffff, 0x00000000, 0x00000000}, + {0x219457e4, 0x01d99729, 0xdc1d5f71, 0x181ad99a, 0x7151c3b5, 0xa37aeb0c, 0xa01b70d7, 0x617f951f, 0xa0fd1797, + 0xc6b40543, 0x5b26db7e, 0xfebac711, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0021ffff, 0x00000000, 0x00000000}, + {0x50bb2fe3, 0xeea0c1ef, 0xadc4bf68, 0xdd23c866, 0x59c5fdce, 0x66c54777, 0xb9341ab9, 0x4af7fdbe, 0xc392758a, + 0xe93f2769, 0x067b7ae1, 0xffbe078b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0023ffff, 0x00000000, 0x00000000}, + {0x7fe207e1, 0x565f2cb5, 0x4f6c1f60, 0x8b2159ee, 0x8830efe8, 0x0b1c41b2, 0xd157b10c, 0x1a4d8c6a, 0x79868a42, + 0x458f43cf, 0x9a0b095a, 0xff130dbe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0025ffff, 0x00000000, 0x00000000}, + {0xaf08dfdf, 0xbe1d977b, 0xf1137f57, 0x391eeb75, 0xb69be202, 0xaf733bed, 0xe97b475e, 0xe9a31b16, 0x2f7a9ef9, + 0xa1df6035, 0x2d9a97d2, 0xfe6813f2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0027ffff, 0x00000000, 0x00000000}, + {0xde2fb7de, 0xaae4c241, 0xc2badf4f, 0xfe27da41, 0x9f101c1b, 0x72bd9858, 0x0293f140, 0xd31b83b6, 0x520ffcec, + 0xc46a825b, 0xd8ef3735, 0xff6b546b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0029ffff, 0x00000000, 0x00000000}, + {0x0d568fdc, 0x12a32d08, 0x64623f47, 0xac256bc9, 0xcd7b0e35, 0x17149293, 0x1ab78793, 0xa2711262, 0x080411a4, + 0x20ba9ec1, 0x6c7ec5ae, 0xfec05a9f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x002bffff, 0x00000000, 0x00000000}, + {0x3c7d67db, 0xff6a57ce, 0x36099f3e, 0x712e5a95, 0xb5ef484f, 0xda5eeefe, 0x33d03174, 0x8be97b01, 0x2a996f97, + 0x4345c0e7, 0x17d36511, 0xffc39b19, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x002dffff, 0x00000000, 0x00000000}, + {0x6ba43fd9, 0x6728c294, 0xd7b0ff36, 0x1f2bec1c, 0xe45a3a69, 0x7eb5e939, 0x4bf3c7c7, 0x5b3f09ad, 0xe08d844f, + 0x9f95dd4c, 0xab62f389, 0xff18a14c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x002fffff, 0x00000000, 0x00000000}, + {0x9acb17d7, 0xcee72d5a, 0x79585f2d, 0xcd297da4, 0x12c52c82, 0x230ce375, 0x64175e1a, 0x2a949859, 0x96819907, + 0xfbe5f9b2, 0x3ef28201, 0xfe6da780, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0031ffff, 0x00000000, 0x00000000}, + {0xc9f1efd6, 0xbbae5820, 0x4affbf25, 0x92326c70, 0xfb39669c, 0xe6573fdf, 0x7d3007fb, 0x140d00f8, 0xb916f6fa, + 0x1e711bd8, 0xea472165, 0xff70e7f9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0033ffff, 0x00000000, 0x00000000}, + {0xf918c7d4, 0x236cc2e6, 0xeca71f1d, 0x402ffdf7, 0x29a458b6, 0x8aae3a1b, 0x95539e4e, 0xe3628fa4, 0x6f0b0bb1, + 0x7ac1383e, 0x7dd6afdd, 0xfec5ee2d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0035ffff, 0x00000000, 0x00000000}, + {0x283f9fd3, 0x1033edad, 0xbe4e7f15, 0x0538ecc3, 0x121892d0, 0x4df89686, 0xae6c4830, 0xccdaf843, 0x91a069a4, + 0x9d4c5a64, 0x292b4f40, 0xffc92ea7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0037ffff, 0x00000000, 0x00000000}, + {0x576677d1, 0x77f25873, 0x5ff5df0c, 0xb3367e4b, 0x408384e9, 0xf24f90c1, 0xc68fde82, 0x9c3086ef, 0x47947e5c, + 0xf99c76ca, 0xbcbaddb8, 0xff1e34da, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0039ffff, 0x00000000, 0x00000000}, + {0x868d4fcf, 0xdfb0c339, 0x019d3f03, 0x61340fd3, 0x6eee7703, 0x96a68afc, 0xdeb374d5, 0x6b86159b, 0xfd889314, + 0x55ec932f, 0x504a6c31, 0xfe733b0e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x003bffff, 0x00000000, 0x00000000}, + {0xb5b427ce, 0xcc77edff, 0xd3449efb, 0x263cfe9e, 0x5762b11d, 0x59f0e767, 0xf7cc1eb7, 0x54fe7e3a, 0x201df107, + 0x7877b556, 0xfb9f0b94, 0xff767b87, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x003dffff, 0x00000000, 0x00000000}, + {0xe4daffcc, 0x343658c5, 0x74ebfef3, 0xd43a9026, 0x85cda336, 0xfe47e1a2, 0x0fefb509, 0x24540ce7, 0xd61205bf, + 0xd4c7d1bb, 0x8f2e9a0c, 0xfecb81bb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x003fffff, 0x00000000, 0x00000000}, + {0x1401d7cb, 0x20fd838c, 0x46935eeb, 0x99437ef2, 0x6e41dd50, 0xc1923e0d, 0x29085eeb, 0x0dcc7586, 0xf8a763b2, + 0xf752f3e1, 0x3a83396f, 0xffcec235, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0041ffff, 0x00000000, 0x00000000}, + {0x4328afc9, 0x88bbee52, 0xe83abee2, 0x47411079, 0x9caccf6a, 0x65e93848, 0x412bf53e, 0xdd220432, 0xae9b7869, + 0x53a31047, 0xce12c7e8, 0xff23c868, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0043ffff, 0x00000000, 0x00000000}, + {0x724f87c7, 0xf07a5918, 0x89e21ed9, 0xf53ea201, 0xcb17c183, 0x0a403283, 0x594f8b91, 0xac7792de, 0x648f8d21, + 0xaff32cad, 0x61a25660, 0xfe78ce9c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0045ffff, 0x00000000, 0x00000000}, + {0xa1765fc6, 0xdd4183de, 0x5b897ed1, 0xba4790cd, 0xb38bfb9d, 0xcd8a8eee, 0x72683572, 0x95effb7d, 0x8724eb14, + 0xd27e4ed3, 0x0cf6f5c3, 0xff7c0f16, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0047ffff, 0x00000000, 0x00000000}, + {0xd09d37c4, 0x44ffeea4, 0xfd30dec9, 0x68452254, 0xe1f6edb7, 0x71e18929, 0x8a8bcbc5, 0x65458a29, 0x3d18ffcc, + 0x2ece6b39, 0xa086843c, 0xfed11549, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0049ffff, 0x00000000, 0x00000000}, + {0xffc40fc3, 0x31c7196a, 0xced83ec1, 0x2d4e1120, 0xca6b27d1, 0x352be594, 0xa3a475a7, 0x4ebdf2c8, 0x5fae5dbf, + 0x51598d5f, 0x4bdb239f, 0xffd455c3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x004bffff, 0x00000000, 0x00000000}, + {0x2eeae7c1, 0x99858431, 0x707f9eb8, 0xdb4ba2a8, 0xf8d619ea, 0xd982dfcf, 0xbbc80bf9, 0x1e138174, 0x15a27277, + 0xada9a9c5, 0xdf6ab217, 0xff295bf6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x004dffff, 0x00000000, 0x00000000}, + {0x5e11bfbf, 0x0143eef7, 0x1226feb0, 0x89493430, 0x27410c04, 0x7dd9da0b, 0xd3eba24c, 0xed691020, 0xcb96872e, + 0x09f9c62a, 0x72fa4090, 0xfe7e622a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x004fffff, 0x00000000, 0x00000000}, + {0x8d3897be, 0xee0b19bd, 0xe3ce5ea7, 0x4e5222fb, 0x0fb5461e, 0x41243676, 0xed044c2e, 0xd6e178bf, 0xee2be521, + 0x2c84e850, 0x1e4edff3, 0xff81a2a4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0051ffff, 0x00000000, 0x00000000}, + {0xbc5f6fbc, 0x55c98483, 0x8575be9f, 0xfc4fb483, 0x3e203837, 0xe57b30b1, 0x0527e280, 0xa637076c, 0xa41ff9d9, + 0x88d504b6, 0xb1de6e6b, 0xfed6a8d7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0053ffff, 0x00000000, 0x00000000}, + {0xeb8647bb, 0x4290af49, 0x571d1e97, 0xc158a34f, 0x26947251, 0xa8c58d1c, 0x1e408c62, 0x8faf700b, 0xc6b557cc, + 0xab6026dc, 0x5d330dce, 0xffd9e951, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0055ffff, 0x00000000, 0x00000000}, + {0x1aad1fb9, 0xaa4f1a10, 0xf8c47e8e, 0x6f5634d6, 0x54ff646b, 0x4d1c8757, 0x366422b5, 0x5f04feb7, 0x7ca96c84, + 0x07b04342, 0xf0c29c47, 0xff2eef84, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0057ffff, 0x00000000, 0x00000000}, + {0x49d3f7b7, 0x120d84d6, 0x9a6bde86, 0x1d53c65e, 0x836a5685, 0xf1738192, 0x4e87b907, 0x2e5a8d63, 0x329d813c, + 0x64005fa8, 0x84522abf, 0xfe83f5b8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0059ffff, 0x00000000, 0x00000000}, + {0x78facfb6, 0xfed4af9c, 0x6c133e7d, 0xe25cb52a, 0x6bde909e, 0xb4bdddfd, 0x67a062e9, 0x17d2f602, 0x5532df2f, + 0x868b81ce, 0x2fa6ca22, 0xff873632, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x005bffff, 0x00000000, 0x00000000}, + {0xa821a7b4, 0x66931a62, 0x0dba9e75, 0x905a46b2, 0x9a4982b8, 0x5914d838, 0x7fc3f93c, 0xe72884ae, 0x0b26f3e6, + 0xe2db9e34, 0xc336589a, 0xfedc3c65, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x005dffff, 0x00000000, 0x00000000}, + {0xd7487fb3, 0x535a4528, 0xdf61fe6d, 0x5563357d, 0x82bdbcd2, 0x1c5f34a3, 0x98dca31e, 0xd0a0ed4d, 0x2dbc51d9, + 0x0566c05a, 0x6e8af7fe, 0xffdf7cdf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x005fffff, 0x00000000, 0x00000000}, + {0x066f57b1, 0xbb18afef, 0x81095e64, 0x0360c705, 0xb128aeec, 0xc0b62ede, 0xb1003970, 0x9ff67bf9, 0xe3b06691, + 0x61b6dcbf, 0x021a8676, 0xff348313, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0061ffff, 0x00000000, 0x00000000}, + {0x35962faf, 0x22d71ab5, 0x22b0be5c, 0xb15e588d, 0xdf93a105, 0x650d2919, 0xc923cfc3, 0x6f4c0aa5, 0x99a47b49, + 0xbe06f925, 0x95aa14ee, 0xfe898946, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0063ffff, 0x00000000, 0x00000000}, + {0x64bd07ae, 0x0f9e457b, 0xf4581e54, 0x76674758, 0xc807db1f, 0x28578584, 0xe23c79a5, 0x58c47344, 0xbc39d93c, + 0xe0921b4b, 0x40feb451, 0xff8cc9c0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0065ffff, 0x00000000, 0x00000000}, + {0x93e3dfac, 0x775cb041, 0x95ff7e4b, 0x2464d8e0, 0xf672cd39, 0xccae7fbf, 0xfa600ff7, 0x281a01f0, 0x722dedf4, + 0x3ce237b1, 0xd48e42ca, 0xfee1cff3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0067ffff, 0x00000000, 0x00000000}, + {0xc30ab7ab, 0x6423db07, 0x67a6de43, 0xe96dc7ac, 0xdee70752, 0x8ff8dc2a, 0x1378b9d9, 0x11926a90, 0x94c34be7, + 0x5f6d59d7, 0x7fe2e22d, 0xffe5106d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0069ffff, 0x00000000, 0x00000000}, + {0xf2318fa9, 0xcbe245cd, 0x094e3e3a, 0x976b5934, 0x0d51f96c, 0x344fd666, 0x2b9c502c, 0xe0e7f93c, 0x4ab7609e, + 0xbbbd763d, 0x137270a5, 0xff3a16a1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x006bffff, 0x00000000, 0x00000000}, + {0x215867a7, 0x33a0b094, 0xaaf59e32, 0x4568eabb, 0x3bbceb86, 0xd8a6d0a1, 0x43bfe67e, 0xb03d87e8, 0x00ab7556, + 0x180d92a3, 0xa701ff1e, 0xfe8f1cd4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x006dffff, 0x00000000, 0x00000000}, + {0x507f3fa6, 0x2067db5a, 0x7c9cfe2a, 0x0a71d987, 0x243125a0, 0x9bf12d0c, 0x5cd89060, 0x99b5f087, 0x2340d349, + 0x3a98b4c9, 0x52569e81, 0xff925d4e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x006fffff, 0x00000000, 0x00000000}, + {0x7fa617a4, 0x88264620, 0x1e445e21, 0xb86f6b0f, 0x529c17b9, 0x40482747, 0x74fc26b3, 0x690b7f33, 0xd934e801, + 0x96e8d12e, 0xe5e62cf9, 0xfee76381, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0071ffff, 0x00000000, 0x00000000}, + {0xaeccefa3, 0x74ed70e6, 0xefebbe19, 0x7d7859da, 0x3b1051d3, 0x039283b2, 0x8e14d095, 0x5283e7d2, 0xfbca45f4, + 0xb973f354, 0x913acc5c, 0xffeaa3fb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0073ffff, 0x00000000, 0x00000000}, + {0xddf3c7a1, 0xdcabdbac, 0x91931e10, 0x2b75eb62, 0x697b43ed, 0xa7e97ded, 0xa63866e7, 0x21d9767e, 0xb1be5aac, + 0x15c40fba, 0x24ca5ad5, 0xff3faa2f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0075ffff, 0x00000000, 0x00000000}, + {0x0d1a9f9f, 0x446a4673, 0x333a7e08, 0xd9737cea, 0x97e63606, 0x4c407828, 0xbe5bfd3a, 0xf12f052a, 0x67b26f63, + 0x72142c20, 0xb859e94d, 0xfe94b062, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0077ffff, 0x00000000, 0x00000000}, + {0x3c41779e, 0x31317139, 0x04e1de00, 0x9e7c6bb6, 0x805a7020, 0x0f8ad493, 0xd774a71c, 0xdaa76dc9, 0x8a47cd56, + 0x949f4e46, 0x63ae88b0, 0xff97f0dc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0079ffff, 0x00000000, 0x00000000}, + {0x6b684f9c, 0x98efdbff, 0xa6893df7, 0x4c79fd3d, 0xaec5623a, 0xb3e1cece, 0xef983d6e, 0xa9fcfc75, 0x403be20e, + 0xf0ef6aac, 0xf73e1728, 0xfeecf70f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x007bffff, 0x00000000, 0x00000000}, + {0x9a8f279b, 0x85b706c5, 0x78309def, 0x1182ec09, 0x97399c54, 0x772c2b39, 0x08b0e750, 0x93756515, 0x62d14001, + 0x137a8cd2, 0xa292b68c, 0xfff03789, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x007dffff, 0x00000000, 0x00000000}, + {0xc9b5ff99, 0xed75718b, 0x19d7fde6, 0xbf807d91, 0xc5a48e6d, 0x1b832574, 0x20d47da3, 0x62caf3c1, 0x18c554b9, + 0x6fcaa938, 0x36224504, 0xff453dbd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x007fffff, 0x00000000, 0x00000000}, + {0xf8dcd797, 0x5533dc51, 0xbb7f5dde, 0x6d7e0f18, 0xf40f8087, 0xbfda1faf, 0x38f813f5, 0x3220826d, 0xceb96971, + 0xcc1ac59d, 0xc9b1d37c, 0xfe9a43f0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0081ffff, 0x00000000, 0x00000000}, + {0x2803af96, 0x41fb0718, 0x8d26bdd6, 0x3286fde4, 0xdc83baa1, 0x83247c1a, 0x5210bdd7, 0x1b98eb0c, 0xf14ec764, + 0xeea5e7c3, 0x750672df, 0xff9d846a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0083ffff, 0x00000000, 0x00000000}, + {0x572a8794, 0xa9b971de, 0x2ece1dcd, 0xe0848f6c, 0x0aeeacba, 0x277b7656, 0x6a34542a, 0xeaee79b8, 0xa742dc1b, + 0x4af60429, 0x08960158, 0xfef28a9e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0085ffff, 0x00000000, 0x00000000}, + {0x86515f93, 0x96809ca4, 0x00757dc5, 0xa58d7e38, 0xf362e6d4, 0xeac5d2c0, 0x834cfe0b, 0xd466e257, 0xc9d83a0e, + 0x6d81264f, 0xb3eaa0bb, 0xfff5cb17, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0087ffff, 0x00000000, 0x00000000}, + {0xb5783791, 0xfe3f076a, 0xa21cddbc, 0x538b0fbf, 0x21cdd8ee, 0x8f1cccfc, 0x9b70945e, 0xa3bc7103, 0x7fcc4ec6, + 0xc9d142b5, 0x477a2f33, 0xff4ad14b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0089ffff, 0x00000000, 0x00000000}, + {0xe49f0f8f, 0x65fd7230, 0x43c43db4, 0x0188a147, 0x5038cb08, 0x3373c737, 0xb3942ab1, 0x7311ffaf, 0x35c0637e, + 0x26215f1b, 0xdb09bdac, 0xfe9fd77e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x008bffff, 0x00000000, 0x00000000}, + {0x13c5e78e, 0x52c49cf7, 0x156b9dac, 0xc6919013, 0x38ad0521, 0xf6be23a2, 0xccacd492, 0x5c8a684e, 0x5855c171, + 0x48ac8141, 0x865e5d0f, 0xffa317f8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x008dffff, 0x00000000, 0x00000000}, + {0x42ecbf8c, 0xba8307bd, 0xb712fda3, 0x748f219a, 0x6717f73b, 0x9b151ddd, 0xe4d06ae5, 0x2bdff6fa, 0x0e49d629, + 0xa4fc9da7, 0x19edeb87, 0xfef81e2c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x008fffff, 0x00000000, 0x00000000}, + {0x7213978b, 0xa74a3283, 0x88ba5d9b, 0x39981066, 0x4f8c3155, 0x5e5f7a48, 0xfde914c7, 0x15585f99, 0x30df341c, + 0xc787bfcd, 0xc5428aea, 0xfffb5ea5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0091ffff, 0x00000000, 0x00000000}, + {0xa13a6f89, 0x0f089d49, 0x2a61bd93, 0xe795a1ee, 0x7df7236e, 0x02b67483, 0x160cab1a, 0xe4adee46, 0xe6d348d3, + 0x23d7dc32, 0x58d21963, 0xff5064d9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0093ffff, 0x00000000, 0x00000000}, + {0xd0614787, 0x76c7080f, 0xcc091d8a, 0x95933375, 0xac621588, 0xa70d6ebe, 0x2e30416c, 0xb4037cf2, 0x9cc75d8b, + 0x8027f898, 0xec61a7db, 0xfea56b0c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0095ffff, 0x00000000, 0x00000000}, + {0xff881f86, 0x638e32d5, 0x9db07d82, 0x5a9c2241, 0x94d64fa2, 0x6a57cb29, 0x4748eb4e, 0x9d7be591, 0xbf5cbb7e, + 0xa2b31abe, 0x97b6473e, 0xffa8ab86, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0097ffff, 0x00000000, 0x00000000}, + {0x2eaef784, 0xcb4c9d9c, 0x3f57dd79, 0x0899b3c9, 0xc34141bc, 0x0eaec564, 0x5f6c81a1, 0x6cd1743d, 0x7550d036, + 0xff033724, 0x2b45d5b6, 0xfefdb1ba, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0099ffff, 0x00000000, 0x00000000}, + {0x5dd5cf82, 0x330b0862, 0xe0ff3d71, 0xb6974550, 0xf1ac33d5, 0xb305bf9f, 0x779017f3, 0x3c2702e9, 0x2b44e4ee, + 0x5b53538a, 0xbed5642f, 0xfe52b7ed, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x009bffff, 0x00000000, 0x00000000}, + {0x8cfca781, 0x1fd23328, 0xb2a69d69, 0x7ba0341c, 0xda206def, 0x76501c0a, 0x90a8c1d5, 0x259f6b88, 0x4dda42e1, + 0x7dde75b0, 0x6a2a0392, 0xff55f867, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x009dffff, 0x00000000, 0x00000000}, + {0xbc237f7f, 0x87909dee, 0x544dfd60, 0x299dc5a4, 0x088b6009, 0x1aa71646, 0xa8cc5828, 0xf4f4fa34, 0x03ce5798, + 0xda2e9216, 0xfdb9920a, 0xfeaafe9a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x009fffff, 0x00000000, 0x00000000}, + {0xeb4a577e, 0x7457c8b4, 0x25f55d58, 0xeea6b470, 0xf0ff9a22, 0xddf172b0, 0xc1e50209, 0xde6d62d3, 0x2663b58b, + 0xfcb9b43c, 0xa90e316d, 0xffae3f14, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00a1ffff, 0x00000000, 0x00000000}, + {0x1a712f7c, 0xdc16337b, 0xc79cbd4f, 0x9ca445f7, 0x1f6a8c3c, 0x82486cec, 0xda08985c, 0xadc2f17f, 0xdc57ca43, + 0x5909d0a1, 0x3c9dbfe6, 0xff034548, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00a3ffff, 0x00000000, 0x00000000}, + {0x4998077a, 0x43d49e41, 0x69441d47, 0x4aa1d77f, 0x4dd57e56, 0x269f6727, 0xf22c2eaf, 0x7d18802b, 0x924bdefb, + 0xb559ed07, 0xd02d4e5e, 0xfe584b7b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00a5ffff, 0x00000000, 0x00000000}, + {0x78bedf79, 0x309bc907, 0x3aeb7d3f, 0x0faac64b, 0x3649b870, 0xe9e9c392, 0x0b44d890, 0x6690e8cb, 0xb4e13cee, + 0xd7e50f2d, 0x7b81edc1, 0xff5b8bf5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00a7ffff, 0x00000000, 0x00000000}, + {0xa7e5b777, 0x985a33cd, 0xdc92dd36, 0xbda857d2, 0x64b4aa89, 0x8e40bdcd, 0x23686ee3, 0x35e67777, 0x6ad551a6, + 0x34352b93, 0x0f117c3a, 0xfeb09229, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00a9ffff, 0x00000000, 0x00000000}, + {0xd70c8f76, 0x85215e93, 0xae3a3d2e, 0x82b1469e, 0x4d28e4a3, 0x518b1a38, 0x3c8118c5, 0x1f5ee016, 0x8d6aaf99, + 0x56c04db9, 0xba661b9d, 0xffb3d2a2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00abffff, 0x00000000, 0x00000000}, + {0x06336774, 0xecdfc95a, 0x4fe19d25, 0x30aed826, 0x7b93d6bd, 0xf5e21473, 0x54a4af17, 0xeeb46ec2, 0x435ec450, + 0xb3106a1f, 0x4df5aa15, 0xff08d8d6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00adffff, 0x00000000, 0x00000000}, + {0x355a3f72, 0x549e3420, 0xf188fd1d, 0xdeac69ad, 0xa9fec8d6, 0x9a390eae, 0x6cc8456a, 0xbe09fd6e, 0xf952d908, + 0x0f608684, 0xe185388e, 0xfe5ddf09, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00afffff, 0x00000000, 0x00000000}, + {0x64811771, 0x41655ee6, 0xc3305d15, 0xa3b55879, 0x927302f0, 0x5d836b19, 0x85e0ef4c, 0xa782660d, 0x1be836fb, + 0x31eba8ab, 0x8cd9d7f1, 0xff611f83, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00b1ffff, 0x00000000, 0x00000000}, + {0x93a7ef6f, 0xa923c9ac, 0x64d7bd0c, 0x51b2ea01, 0xc0ddf50a, 0x01da6554, 0x9e04859f, 0x76d7f4b9, 0xd1dc4bb3, + 0x8e3bc510, 0x20696669, 0xfeb625b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00b3ffff, 0x00000000, 0x00000000}, + {0xc2cec76e, 0x95eaf472, 0x367f1d04, 0x16bbd8cd, 0xa9522f24, 0xc524c1bf, 0xb71d2f80, 0x60505d58, 0xf471a9a6, + 0xb0c6e736, 0xcbbe05cc, 0xffb96630, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00b5ffff, 0x00000000, 0x00000000}, + {0xf1f59f6c, 0xfda95f38, 0xd8267cfb, 0xc4b96a54, 0xd7bd213d, 0x697bbbfa, 0xcf40c5d3, 0x2fa5ec04, 0xaa65be5e, + 0x0d17039c, 0x5f4d9445, 0xff0e6c64, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00b7ffff, 0x00000000, 0x00000000}, + {0x211c776a, 0x6567c9ff, 0x79cddcf3, 0x72b6fbdc, 0x06281357, 0x0dd2b636, 0xe7645c26, 0xfefb7ab0, 0x6059d315, + 0x69672002, 0xf2dd22bd, 0xfe637297, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00b9ffff, 0x00000000, 0x00000000}, + {0x50434f69, 0x522ef4c5, 0x4b753ceb, 0x37bfeaa8, 0xee9c4d71, 0xd11d12a0, 0x007d0607, 0xe873e350, 0x82ef3108, + 0x8bf24228, 0x9e31c220, 0xff66b311, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00bbffff, 0x00000000, 0x00000000}, + {0x7f6a2767, 0xb9ed5f8b, 0xed1c9ce2, 0xe5bd7c2f, 0x1d073f8a, 0x75740cdc, 0x18a09c5a, 0xb7c971fc, 0x38e345c0, + 0xe8425e8e, 0x31c15098, 0xfebbb945, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00bdffff, 0x00000000, 0x00000000}, + {0xae90ff66, 0xa6b48a51, 0xbec3fcda, 0xaac66afb, 0x057b79a4, 0x38be6947, 0x31b9463c, 0xa141da9b, 0x5b78a3b3, + 0x0acd80b4, 0xdd15effc, 0xffbef9be, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00bfffff, 0x00000000, 0x00000000}, + {0xddb7d764, 0x0e72f517, 0x606b5cd2, 0x58c3fc83, 0x33e66bbe, 0xdd156382, 0x49dcdc8e, 0x70976947, 0x116cb86b, + 0x671d9d1a, 0x70a57e74, 0xff13fff2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00c1ffff, 0x00000000, 0x00000000}, + {0x0cdeaf62, 0x76315fde, 0x0212bcc9, 0x06c18e0b, 0x62515dd8, 0x816c5dbd, 0x620072e1, 0x3fecf7f3, 0xc760cd23, + 0xc36db97f, 0x04350cec, 0xfe690626, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00c3ffff, 0x00000000, 0x00000000}, + {0x3c058761, 0x62f88aa4, 0xd3ba1cc1, 0xcbca7cd6, 0x4ac597f1, 0x44b6ba28, 0x7b191cc3, 0x29656092, 0xe9f62b16, + 0xe5f8dba5, 0xaf89ac4f, 0xff6c469f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00c5ffff, 0x00000000, 0x00000000}, + {0x6b2c5f5f, 0xcab6f56a, 0x75617cb8, 0x79c80e5e, 0x79308a0b, 0xe90db463, 0x933cb315, 0xf8baef3e, 0x9fea3fcd, + 0x4248f80b, 0x43193ac8, 0xfec14cd3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00c7ffff, 0x00000000, 0x00000000}, + {0x9a53375e, 0xb77e2030, 0x4708dcb0, 0x3ed0fd2a, 0x61a4c425, 0xac5810ce, 0xac555cf7, 0xe23357dd, 0xc27f9dc0, + 0x64d41a31, 0xee6dda2b, 0xffc48d4c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00c9ffff, 0x00000000, 0x00000000}, + {0xc97a0f5c, 0x1f3c8af6, 0xe8b03ca8, 0xecce8eb1, 0x900fb63e, 0x50af0b09, 0xc478f34a, 0xb188e689, 0x7873b278, + 0xc1243697, 0x81fd68a3, 0xff199380, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00cbffff, 0x00000000, 0x00000000}, + {0xf8a0e75a, 0x86faf5bc, 0x8a579c9f, 0x9acc2039, 0xbe7aa858, 0xf5060544, 0xdc9c899c, 0x80de7535, 0x2e67c730, + 0x1d7452fd, 0x158cf71c, 0xfe6e99b4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00cdffff, 0x00000000, 0x00000000}, + {0x27c7bf59, 0x73c22083, 0x5bfefc97, 0x5fd50f05, 0xa6eee272, 0xb85061af, 0xf5b5337e, 0x6a56ddd4, 0x50fd2523, + 0x3fff7523, 0xc0e1967f, 0xff71da2d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00cfffff, 0x00000000, 0x00000000}, + {0x56ee9757, 0xdb808b49, 0xfda65c8e, 0x0dd2a08c, 0xd559d48c, 0x5ca75bea, 0x0dd8c9d1, 0x39ac6c81, 0x06f139db, + 0x9c4f9189, 0x547124f7, 0xfec6e061, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00d1ffff, 0x00000000, 0x00000000}, + {0x86156f56, 0xc847b60f, 0xcf4dbc86, 0xd2db8f58, 0xbdce0ea5, 0x1ff1b855, 0x26f173b3, 0x2324d520, 0x298697ce, + 0xbedab3af, 0xffc5c45a, 0xffca20da, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00d3ffff, 0x00000000, 0x00000000}, + {0xb53c4754, 0x300620d5, 0x70f51c7e, 0x80d920e0, 0xec3900bf, 0xc448b290, 0x3f150a05, 0xf27a63cc, 0xdf7aac85, + 0x1b2ad014, 0x935552d3, 0xff1f270e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00d5ffff, 0x00000000, 0x00000000}, + {0xe4631f52, 0x97c48b9b, 0x129c7c75, 0x2ed6b268, 0x1aa3f2d9, 0x689faccc, 0x5738a058, 0xc1cff278, 0x956ec13d, + 0x777aec7a, 0x26e4e14b, 0xfe742d42, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00d7ffff, 0x00000000, 0x00000000}, + {0x1389f751, 0x848bb662, 0xe443dc6d, 0xf3dfa133, 0x03182cf2, 0x2bea0937, 0x70514a3a, 0xab485b17, 0xb8041f30, + 0x9a060ea0, 0xd23980ae, 0xff776dbb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00d9ffff, 0x00000000, 0x00000000}, + {0x42b0cf4f, 0xec4a2128, 0x85eb3c64, 0xa1dd32bb, 0x31831f0c, 0xd0410372, 0x8874e08c, 0x7a9de9c3, 0x6df833e8, + 0xf6562b06, 0x65c90f26, 0xfecc73ef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00dbffff, 0x00000000, 0x00000000}, + {0x71d7a74e, 0xd9114bee, 0x57929c5c, 0x66e62187, 0x19f75926, 0x938b5fdd, 0xa18d8a6e, 0x64165262, 0x908d91db, + 0x18e14d2c, 0x111dae8a, 0xffcfb469, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00ddffff, 0x00000000, 0x00000000}, + {0xa0fe7f4c, 0x40cfb6b4, 0xf939fc54, 0x14e3b30e, 0x48624b40, 0x37e25a18, 0xb9b120c1, 0x336be10e, 0x4681a693, + 0x75316992, 0xa4ad3d02, 0xff24ba9c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00dfffff, 0x00000000, 0x00000000}, + {0xd025574a, 0xa88e217a, 0x9ae15c4b, 0xc2e14496, 0x76cd3d59, 0xdc395453, 0xd1d4b713, 0x02c16fba, 0xfc75bb4b, + 0xd18185f7, 0x383ccb7a, 0xfe79c0d0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00e1ffff, 0x00000000, 0x00000000}, + {0xff4c2f49, 0x95554c40, 0x6c88bc43, 0x87ea3362, 0x5f417773, 0x9f83b0be, 0xeaed60f5, 0xec39d859, 0x1f0b193d, + 0xf40ca81e, 0xe3916add, 0xff7d0149, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00e3ffff, 0x00000000, 0x00000000}, + {0x2e730747, 0xfd13b707, 0x0e301c3a, 0x35e7c4ea, 0x8dac698d, 0x43daaaf9, 0x0310f748, 0xbb8f6706, 0xd4ff2df5, + 0x505cc483, 0x7720f956, 0xfed2077d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00e5ffff, 0x00000000, 0x00000000}, + {0x5d99df46, 0xe9dae1cd, 0xdfd77c32, 0xfaf0b3b5, 0x7620a3a6, 0x07250764, 0x1c29a12a, 0xa507cfa5, 0xf7948be8, + 0x72e7e6a9, 0x227598b9, 0xffd547f7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00e7ffff, 0x00000000, 0x00000000}, + {0x8cc0b744, 0x51994c93, 0x817edc2a, 0xa8ee453d, 0xa48b95c0, 0xab7c019f, 0x344d377c, 0x745d5e51, 0xad88a0a0, + 0xcf38030f, 0xb6052731, 0xff2a4e2a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00e9ffff, 0x00000000, 0x00000000}, + {0xbbe78f42, 0xb957b759, 0x23263c21, 0x56ebd6c5, 0xd2f687da, 0x4fd2fbda, 0x4c70cdcf, 0x43b2ecfd, 0x637cb558, + 0x2b881f75, 0x4994b5aa, 0xfe7f545e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00ebffff, 0x00000000, 0x00000000}, + {0xeb0e6741, 0xa61ee21f, 0xf4cd9c19, 0x1bf4c590, 0xbb6ac1f4, 0x131d5845, 0x658977b1, 0x2d2b559c, 0x8612134b, + 0x4e13419b, 0xf4e9550d, 0xff8294d7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00edffff, 0x00000000, 0x00000000}, + {0x1a353f3f, 0x0ddd4ce6, 0x9674fc11, 0xc9f25718, 0xe9d5b40d, 0xb7745280, 0x7dad0e03, 0xfc80e448, 0x3c062802, + 0xaa635e01, 0x8878e385, 0xfed79b0b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00efffff, 0x00000000, 0x00000000}, + {0x495c173e, 0xfaa477ac, 0x681c5c08, 0x8efb45e4, 0xd249ee27, 0x7abeaeeb, 0x96c5b7e5, 0xe5f94ce7, 0x5e9b85f5, + 0xccee8027, 0x33cd82e8, 0xffdadb85, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00f1ffff, 0x00000000, 0x00000000}, + {0x7882ef3c, 0x6262e272, 0x09c3bc00, 0x3cf8d76c, 0x00b4e041, 0x1f15a927, 0xaee94e38, 0xb54edb93, 0x148f9aad, + 0x293e9c8d, 0xc75d1161, 0xff2fe1b8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00f3ffff, 0x00000000, 0x00000000}, + {0xa7a9c73a, 0xca214d38, 0xab6b1bf7, 0xeaf668f3, 0x2f1fd25a, 0xc36ca362, 0xc70ce48a, 0x84a46a3f, 0xca83af65, + 0x858eb8f2, 0x5aec9fd9, 0xfe84e7ec, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00f5ffff, 0x00000000, 0x00000000}, + {0xd6d09f39, 0xb6e877fe, 0x7d127bef, 0xafff57bf, 0x17940c74, 0x86b6ffcd, 0xe0258e6c, 0x6e1cd2de, 0xed190d58, + 0xa819db18, 0x06413f3c, 0xff882866, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00f7ffff, 0x00000000, 0x00000000}, + {0x05f77737, 0x1ea6e2c5, 0x1eb9dbe7, 0x5dfce947, 0x45fefe8e, 0x2b0dfa08, 0xf84924bf, 0x3d72618a, 0xa30d2210, + 0x0469f77e, 0x99d0cdb5, 0xfedd2e99, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00f9ffff, 0x00000000, 0x00000000}, + {0x351e4f36, 0x0b6e0d8b, 0xf0613bdf, 0x2305d812, 0x2e7338a8, 0xee585673, 0x1161cea0, 0x26eaca2a, 0xc5a28003, + 0x26f519a4, 0x45256d18, 0xffe06f13, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00fbffff, 0x00000000, 0x00000000}, + {0x64452734, 0x732c7851, 0x92089bd6, 0xd103699a, 0x5cde2ac1, 0x92af50ae, 0x298564f3, 0xf64058d6, 0x7b9694ba, + 0x8345360a, 0xd8b4fb90, 0xff357546, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00fdffff, 0x00000000, 0x00000000}, + {0x936bff32, 0xdaeae317, 0x33affbcd, 0x7f00fb22, 0x8b491cdb, 0x37064ae9, 0x41a8fb46, 0xc595e782, 0x318aa972, + 0xdf955270, 0x6c448a08, 0xfe8a7b7a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00ffffff, 0x00000000, 0x00000000}, + {0xc292d731, 0xc7b20ddd, 0x05575bc5, 0x4409e9ee, 0x73bd56f5, 0xfa50a754, 0x5ac1a527, 0xaf0e5021, 0x54200765, + 0x02207496, 0x1799296c, 0xff8dbbf4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0101ffff, 0x00000000, 0x00000000}, + {0xf1b9af2f, 0x2f7078a3, 0xa6febbbd, 0xf2077b75, 0xa228490e, 0x9ea7a18f, 0x72e53b7a, 0x7e63decd, 0x0a141c1d, + 0x5e7090fc, 0xab28b7e4, 0xfee2c227, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0103ffff, 0x00000000, 0x00000000}, + {0x20e0872e, 0x1c37a36a, 0x78a61bb5, 0xb7106a41, 0x8a9c8328, 0x61f1fdfa, 0x8bfde55c, 0x67dc476c, 0x2ca97a10, + 0x80fbb322, 0x567d5747, 0xffe602a1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0105ffff, 0x00000000, 0x00000000}, + {0x50075f2c, 0x83f60e30, 0x1a4d7bac, 0x650dfbc9, 0xb9077542, 0x0648f835, 0xa4217baf, 0x3731d618, 0xe29d8ec8, + 0xdd4bcf87, 0xea0ce5bf, 0xff3b08d4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0107ffff, 0x00000000, 0x00000000}, + {0x7f2e372a, 0xebb478f6, 0xbbf4dba3, 0x130b8d50, 0xe772675c, 0xaa9ff270, 0xbc451201, 0x068764c4, 0x9891a380, + 0x399bebed, 0x7d9c7438, 0xfe900f08, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0109ffff, 0x00000000, 0x00000000}, + {0xae550f29, 0xd87ba3bc, 0x8d9c3b9b, 0xd8147c1c, 0xcfe6a175, 0x6dea4edb, 0xd55dbbe3, 0xefffcd63, 0xbb270172, + 0x5c270e13, 0x28f1139b, 0xff934f82, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x010bffff, 0x00000000, 0x00000000}, + {0xdd7be727, 0x403a0e82, 0x2f439b93, 0x86120da4, 0xfe51938f, 0x12414916, 0xed815236, 0xbf555c0f, 0x711b162a, + 0xb8772a79, 0xbc80a213, 0xfee855b5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x010dffff, 0x00000000, 0x00000000}, + {0x0ca2bf26, 0x2d013949, 0x00eafb8b, 0x4b1afc70, 0xe6c5cda9, 0xd58ba581, 0x0699fc17, 0xa8cdc4af, 0x93b0741d, + 0xdb024c9f, 0x67d54176, 0xffeb962f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x010fffff, 0x00000000, 0x00000000}, + {0x3bc99724, 0x94bfa40f, 0xa2925b82, 0xf9188df7, 0x1530bfc2, 0x79e29fbd, 0x1ebd926a, 0x7823535b, 0x49a488d5, + 0x37526905, 0xfb64cfef, 0xff409c62, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0111ffff, 0x00000000, 0x00000000}, + {0x6af06f22, 0xfc7e0ed5, 0x4439bb79, 0xa7161f7f, 0x439bb1dc, 0x1e3999f8, 0x36e128bd, 0x4778e207, 0xff989d8d, + 0x93a2856a, 0x8ef45e67, 0xfe95a296, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0113ffff, 0x00000000, 0x00000000}, + {0x9a174721, 0xe945399b, 0x15e11b71, 0x6c1f0e4b, 0x2c0febf6, 0xe183f663, 0x4ff9d29e, 0x30f14aa6, 0x222dfb80, + 0xb62da791, 0x3a48fdca, 0xff98e310, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0115ffff, 0x00000000, 0x00000000}, + {0xc93e1f1f, 0x5103a461, 0xb7887b69, 0x1a1c9fd2, 0x5a7ade10, 0x85daf09e, 0x681d68f1, 0x0046d952, 0xd8221038, + 0x127dc3f6, 0xcdd88c43, 0xfeede943, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0117ffff, 0x00000000, 0x00000000}, + {0xf864f71e, 0x3dcacf27, 0x892fdb61, 0xdf258e9e, 0x42ef1829, 0x49254d09, 0x813612d3, 0xe9bf41f1, 0xfab76e2a, + 0x3508e61c, 0x792d2ba6, 0xfff129bd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0119ffff, 0x00000000, 0x00000000}, + {0x278bcf1c, 0xa58939ee, 0x2ad73b58, 0x8d232026, 0x715a0a43, 0xed7c4744, 0x9959a925, 0xb914d09d, 0xb0ab82e2, + 0x91590282, 0x0cbcba1e, 0xff462ff1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x011bffff, 0x00000000, 0x00000000}, + {0x56b2a71a, 0x0d47a4b4, 0xcc7e9b50, 0x3b20b1ad, 0x9fc4fc5d, 0x91d3417f, 0xb17d3f78, 0x886a5f49, 0x669f979a, + 0xeda91ee8, 0xa04c4896, 0xfe9b3624, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x011dffff, 0x00000000, 0x00000000}, + {0x85d97f19, 0xfa0ecf7a, 0x9e25fb47, 0x0029a079, 0x88393677, 0x551d9dea, 0xca95e95a, 0x71e2c7e8, 0x8934f58d, + 0x1034410e, 0x4ba0e7fa, 0xff9e769e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x011fffff, 0x00000000, 0x00000000}, + {0xb5005717, 0x61cd3a40, 0x3fcd5b3f, 0xae273201, 0xb6a42890, 0xf9749825, 0xe2b97fac, 0x41385694, 0x3f290a45, + 0x6c845d74, 0xdf307672, 0xfef37cd1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0121ffff, 0x00000000, 0x00000000}, + {0xe4272f16, 0x4e946506, 0x1174bb37, 0x733020cd, 0x9f1862aa, 0xbcbef490, 0xfbd2298e, 0x2ab0bf33, 0x61be6838, + 0x8f0f7f9a, 0x8a8515d5, 0xfff6bd4b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0123ffff, 0x00000000, 0x00000000}, + {0x134e0714, 0xb652cfcd, 0xb31c1b2e, 0x212db254, 0xcd8354c4, 0x6115eecb, 0x13f5bfe1, 0xfa064de0, 0x17b27cef, + 0xeb5f9c00, 0x1e14a44d, 0xff4bc37f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0125ffff, 0x00000000, 0x00000000}, + {0x4274df12, 0x1e113a93, 0x54c37b26, 0xcf2b43dc, 0xfbee46dd, 0x056ce906, 0x2c195634, 0xc95bdc8c, 0xcda691a7, + 0x47afb865, 0xb1a432c6, 0xfea0c9b2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0127ffff, 0x00000000, 0x00000000}, + {0x719bb711, 0x0ad86559, 0x266adb1e, 0x943432a8, 0xe46280f7, 0xc8b74571, 0x45320015, 0xb2d4452b, 0xf03bef9a, + 0x6a3ada8b, 0x5cf8d229, 0xffa40a2c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0129ffff, 0x00000000, 0x00000000}, + {0xa0c28f0f, 0x7296d01f, 0xc8123b15, 0x4231c42f, 0x12cd7311, 0x6d0e3fad, 0x5d559668, 0x8229d3d7, 0xa6300452, + 0xc68af6f1, 0xf08860a1, 0xfef9105f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x012bffff, 0x00000000, 0x00000000}, + {0xcfe9670e, 0x5f5dfae5, 0x99b99b0d, 0x073ab2fb, 0xfb41ad2b, 0x30589c17, 0x766e404a, 0x6ba23c76, 0xc8c56245, + 0xe9161917, 0x9bdd0004, 0xfffc50d9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x012dffff, 0x00000000, 0x00000000}, + {0xff103f0c, 0xc71c65ab, 0x3b60fb04, 0xb5384483, 0x29ac9f44, 0xd4af9653, 0x8e91d69c, 0x3af7cb22, 0x7eb976fd, + 0x4566357d, 0x2f6c8e7d, 0xff51570d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x012fffff, 0x00000000, 0x00000000}, + {0x2e37170a, 0x2edad072, 0xdd085afc, 0x6335d60a, 0x5817915e, 0x7906908e, 0xa6b56cef, 0x0a4d59ce, 0x34ad8bb5, + 0xa1b651e3, 0xc2fc1cf5, 0xfea65d40, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0131ffff, 0x00000000, 0x00000000}, + {0x5d5def09, 0x1ba1fb38, 0xaeafbaf4, 0x283ec4d6, 0x408bcb78, 0x3c50ecf9, 0xbfce16d1, 0xf3c5c26d, 0x5742e9a7, + 0xc4417409, 0x6e50bc58, 0xffa99dba, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0133ffff, 0x00000000, 0x00000000}, + {0x8c84c707, 0x836065fe, 0x50571aeb, 0xd63c565e, 0x6ef6bd91, 0xe0a7e734, 0xd7f1ad23, 0xc31b5119, 0x0d36fe5f, + 0x2091906f, 0x01e04ad1, 0xfefea3ee, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0135ffff, 0x00000000, 0x00000000}, + {0xbbab9f05, 0xeb1ed0c4, 0xf1fe7ae2, 0x8439e7e5, 0x9d61afab, 0x84fee16f, 0xf0154376, 0x9270dfc5, 0xc32b1317, + 0x7ce1acd4, 0x956fd949, 0xfe53aa21, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0137ffff, 0x00000000, 0x00000000}, + {0xead27704, 0xd7e5fb8a, 0xc3a5dada, 0x4942d6b1, 0x85d5e9c5, 0x48493dda, 0x092ded58, 0x7be94865, 0xe5c0710a, + 0x9f6ccefa, 0x40c478ac, 0xff56ea9b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0139ffff, 0x00000000, 0x00000000}, + {0x19f94f02, 0x3fa46651, 0x654d3ad2, 0xf7406839, 0xb440dbde, 0xeca03815, 0x215183aa, 0x4b3ed711, 0x9bb485c2, + 0xfbbceb60, 0xd4540724, 0xfeabf0ce, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x013bffff, 0x00000000, 0x00000000}, + {0x49202701, 0x2c6b9117, 0x36f49aca, 0xbc495705, 0x9cb515f8, 0xafea9480, 0x3a6a2d8c, 0x34b73fb0, 0xbe49e3b5, + 0x1e480d86, 0x7fa8a688, 0xffaf3148, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x013dffff, 0x00000000, 0x00000000}, + {0x7846feff, 0x9429fbdd, 0xd89bfac1, 0x6a46e88c, 0xcb200812, 0x54418ebb, 0x528dc3df, 0x040cce5c, 0x743df86d, + 0x7a9829ec, 0x13383500, 0xff04377c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x013fffff, 0x00000000, 0x00000000}, + {0xa76dd6fd, 0xfbe866a3, 0x7a435ab8, 0x18447a14, 0xf98afa2c, 0xf89888f6, 0x6ab15a31, 0xd3625d08, 0x2a320d24, + 0xd6e84652, 0xa6c7c378, 0xfe593daf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0141ffff, 0x00000000, 0x00000000}, + {0xd694aefc, 0xe8af9169, 0x4beabab0, 0xdd4d68e0, 0xe1ff3445, 0xbbe2e561, 0x83ca0413, 0xbcdac5a7, 0x4cc76b17, + 0xf9736878, 0x521c62db, 0xff5c7e29, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0143ffff, 0x00000000, 0x00000000}, + {0x05bb86fa, 0x506dfc30, 0xed921aa8, 0x8b4afa67, 0x106a265f, 0x6039df9d, 0x9bed9a66, 0x8c305453, 0x02bb7fcf, + 0x55c384de, 0xe5abf154, 0xfeb1845c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0145ffff, 0x00000000, 0x00000000}, + {0x34e25ef9, 0x3d3526f6, 0xbf397aa0, 0x5053e933, 0xf8de6079, 0x23843c07, 0xb5064448, 0x75a8bcf2, 0x2550ddc2, + 0x784ea704, 0x910090b7, 0xffb4c4d6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0147ffff, 0x00000000, 0x00000000}, + {0x640936f7, 0xa4f391bc, 0x60e0da97, 0xfe517abb, 0x27495292, 0xc7db3643, 0xcd29da9a, 0x44fe4b9e, 0xdb44f27a, + 0xd49ec369, 0x24901f2f, 0xff09cb0a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0149ffff, 0x00000000, 0x00000000}, + {0x93300ef5, 0x0cb1fc82, 0x02883a8f, 0xac4f0c43, 0x55b444ac, 0x6c32307e, 0xe54d70ed, 0x1453da4a, 0x91390732, + 0x30eedfcf, 0xb81fada8, 0xfe5ed13d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x014bffff, 0x00000000, 0x00000000}, + {0xc256e6f4, 0xf9792748, 0xd42f9a86, 0x7157fb0e, 0x3e287ec6, 0x2f7c8ce9, 0xfe661acf, 0xfdcc42e9, 0xb3ce6524, + 0x537a01f5, 0x63744d0b, 0xff6211b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x014dffff, 0x00000000, 0x00000000}, + {0xf17dbef2, 0x6137920e, 0x75d6fa7e, 0x1f558c96, 0x6c9370e0, 0xd3d38724, 0x1689b121, 0xcd21d196, 0x69c279dc, + 0xafca1e5b, 0xf703db83, 0xfeb717ea, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x014fffff, 0x00000000, 0x00000000}, + {0x20a496f1, 0x4dfebcd5, 0x477e5a76, 0xe45e7b62, 0x5507aaf9, 0x971de38f, 0x2fa25b03, 0xb69a3a35, 0x8c57d7cf, + 0xd2554081, 0xa2587ae6, 0xffba5864, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0151ffff, 0x00000000, 0x00000000}, + {0x4fcb6eef, 0xb5bd279b, 0xe925ba6d, 0x925c0ce9, 0x83729d13, 0x3b74ddca, 0x47c5f156, 0x85efc8e1, 0x424bec87, + 0x2ea55ce7, 0x35e8095f, 0xff0f5e98, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0153ffff, 0x00000000, 0x00000000}, + {0x7ef246ed, 0x1d7b9261, 0x8acd1a65, 0x40599e71, 0xb1dd8f2d, 0xdfcbd805, 0x5fe987a8, 0x5545578d, 0xf840013f, + 0x8af5794c, 0xc97797d7, 0xfe6464cb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0155ffff, 0x00000000, 0x00000000}, + {0xae191eec, 0x0a42bd27, 0x5c747a5d, 0x05628d3d, 0x9a51c947, 0xa3163470, 0x7902318a, 0x3ebdc02c, 0x1ad55f32, + 0xad809b73, 0x74cc373a, 0xff67a545, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0157ffff, 0x00000000, 0x00000000}, + {0xdd3ff6ea, 0x720127ed, 0xfe1bda54, 0xb3601ec4, 0xc8bcbb60, 0x476d2eab, 0x9125c7dd, 0x0e134ed8, 0xd0c973ea, + 0x09d0b7d8, 0x085bc5b3, 0xfebcab79, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0159ffff, 0x00000000, 0x00000000}, + {0x0c66cee9, 0x5ec852b4, 0xcfc33a4c, 0x78690d90, 0xb130f57a, 0x0ab78b16, 0xaa3e71bf, 0xf78bb777, 0xf35ed1dc, + 0x2c5bd9fe, 0xb3b06516, 0xffbfebf2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x015bffff, 0x00000000, 0x00000000}, + {0x3b8da6e7, 0xc686bd7a, 0x716a9a43, 0x26669f18, 0xdf9be794, 0xaf0e8551, 0xc2620811, 0xc6e14623, 0xa952e694, + 0x88abf664, 0x473ff38e, 0xff14f226, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x015dffff, 0x00000000, 0x00000000}, + {0x6ab47ee5, 0x2e452840, 0x1311fa3b, 0xd46430a0, 0x0e06d9ad, 0x53657f8d, 0xda859e64, 0x9636d4cf, 0x5f46fb4c, + 0xe4fc12ca, 0xdacf8206, 0xfe69f859, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x015fffff, 0x00000000, 0x00000000}, + {0x99db56e4, 0x1b0c5306, 0xe4b95a33, 0x996d1f6b, 0xf67b13c7, 0x16afdbf7, 0xf39e4846, 0x7faf3d6e, 0x81dc593f, + 0x078734f0, 0x8624216a, 0xff6d38d3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0161ffff, 0x00000000, 0x00000000}, + {0xc9022ee2, 0x82cabdcc, 0x8660ba2a, 0x476ab0f3, 0x24e605e1, 0xbb06d633, 0x0bc1de98, 0x4f04cc1b, 0x37d06df7, + 0x63d75156, 0x19b3afe2, 0xfec23f07, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0163ffff, 0x00000000, 0x00000000}, + {0xf82906e1, 0x6f91e892, 0x58081a22, 0x0c739fbf, 0x0d5a3ffb, 0x7e51329e, 0x24da887a, 0x387d34ba, 0x5a65cbea, + 0x8662737c, 0xc5084f45, 0xffc57f80, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0165ffff, 0x00000000, 0x00000000}, + {0x274fdedf, 0xd7505359, 0xf9af7a19, 0xba713146, 0x3bc53214, 0x22a82cd9, 0x3cfe1ecd, 0x07d2c366, 0x1059e0a2, + 0xe2b28fe2, 0x5897ddbd, 0xff1a85b4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0167ffff, 0x00000000, 0x00000000}, + {0x5676b6dd, 0x3f0ebe1f, 0x9b56da11, 0x686ec2ce, 0x6a30242e, 0xc6ff2714, 0x5521b51f, 0xd7285212, 0xc64df559, + 0x3f02ac47, 0xec276c36, 0xfe6f8be7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0169ffff, 0x00000000, 0x00000000}, + {0x859d8edc, 0x2bd5e8e5, 0x6cfe3a09, 0x2d77b19a, 0x52a45e48, 0x8a49837f, 0x6e3a5f01, 0xc0a0bab1, 0xe8e3534c, + 0x618dce6d, 0x977c0b99, 0xff72cc61, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x016bffff, 0x00000000, 0x00000000}, + {0xb4c466da, 0x939453ab, 0x0ea59a00, 0xdb754322, 0x810f5061, 0x2ea07dba, 0x865df554, 0x8ff6495d, 0x9ed76804, + 0xbdddead3, 0x2b0b9a11, 0xfec7d295, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x016dffff, 0x00000000, 0x00000000}, + {0xe3eb3ed9, 0x805b7e71, 0xe04cf9f8, 0xa07e31ed, 0x69838a7b, 0xf1eada25, 0x9f769f35, 0x796eb1fc, 0xc16cc5f7, + 0xe0690cf9, 0xd6603974, 0xffcb130e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x016fffff, 0x00000000, 0x00000000}, + {0x131216d7, 0xe819e938, 0x81f459ef, 0x4e7bc375, 0x97ee7c95, 0x9641d460, 0xb79a3588, 0x48c440a8, 0x7760daaf, + 0x3cb9295f, 0x69efc7ed, 0xff201942, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0171ffff, 0x00000000, 0x00000000}, + {0x4238eed5, 0x4fd853fe, 0x239bb9e7, 0xfc7954fd, 0xc6596eae, 0x3a98ce9b, 0xcfbdcbdb, 0x1819cf54, 0x2d54ef67, + 0x990945c5, 0xfd7f5665, 0xfe751f75, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0173ffff, 0x00000000, 0x00000000}, + {0x715fc6d4, 0x3c9f7ec4, 0xf54319df, 0xc18243c8, 0xaecda8c8, 0xfde32b06, 0xe8d675bc, 0x019237f3, 0x4fea4d5a, + 0xbb9467eb, 0xa8d3f5c8, 0xff785fef, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0175ffff, 0x00000000, 0x00000000}, + {0xa0869ed2, 0xa45de98a, 0x96ea79d6, 0x6f7fd550, 0xdd389ae2, 0xa23a2541, 0x00fa0c0f, 0xd0e7c6a0, 0x05de6211, + 0x17e48451, 0x3c638441, 0xfecd6623, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0177ffff, 0x00000000, 0x00000000}, + {0xcfad76d1, 0x91251450, 0x6891d9ce, 0x3488c41c, 0xc5acd4fc, 0x658481ac, 0x1a12b5f1, 0xba602f3f, 0x2873c004, + 0x3a6fa677, 0xe7b823a4, 0xffd0a69c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0179ffff, 0x00000000, 0x00000000}, + {0xfed44ecf, 0xf8e37f16, 0x0a3939c5, 0xe28655a4, 0xf417c715, 0x09db7be7, 0x32364c44, 0x89b5bdeb, 0xde67d4bc, + 0x96bfc2dc, 0x7b47b21c, 0xff25acd0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x017bffff, 0x00000000, 0x00000000}, + {0x2dfb26cd, 0x60a1e9dd, 0xabe099bd, 0x9083e72b, 0x2282b92f, 0xae327623, 0x4a59e296, 0x590b4c97, 0x945be974, + 0xf30fdf42, 0x0ed74094, 0xfe7ab304, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x017dffff, 0x00000000, 0x00000000}, + {0x5d21fecc, 0x4d6914a3, 0x7d87f9b5, 0x558cd5f7, 0x0af6f349, 0x717cd28e, 0x63728c78, 0x4283b536, 0xb6f14767, + 0x159b0168, 0xba2bdff8, 0xff7df37d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x017fffff, 0x00000000, 0x00000000}, + {0x8c48d6ca, 0xb5277f69, 0x1f2f59ac, 0x038a677f, 0x3961e563, 0x15d3ccc9, 0x7b9622cb, 0x11d943e2, 0x6ce55c1f, + 0x71eb1dce, 0x4dbb6e70, 0xfed2f9b1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0181ffff, 0x00000000, 0x00000000}, + {0xbb6faec9, 0xa1eeaa2f, 0xf0d6b9a4, 0xc893564a, 0x21d61f7c, 0xd91e2934, 0x94aeccac, 0xfb51ac81, 0x8f7aba11, + 0x94763ff4, 0xf9100dd3, 0xffd63a2a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0183ffff, 0x00000000, 0x00000000}, + {0xea9686c7, 0x09ad14f5, 0x927e199c, 0x7690e7d2, 0x50411196, 0x7d75236f, 0xacd262ff, 0xcaa73b2d, 0x456ecec9, + 0xf0c65c5a, 0x8c9f9c4b, 0xff2b405e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0185ffff, 0x00000000, 0x00000000}, + {0x19bd5ec5, 0x716b7fbc, 0x34257993, 0x248e795a, 0x7eac03b0, 0x21cc1daa, 0xc4f5f952, 0x99fcc9d9, 0xfb62e381, + 0x4d1678bf, 0x202f2ac4, 0xfe804692, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0187ffff, 0x00000000, 0x00000000}, + {0x48e436c4, 0x5e32aa82, 0x05ccd98b, 0xe9976826, 0x67203dc9, 0xe5167a15, 0xde0ea333, 0x83753278, 0x1df84174, + 0x6fa19ae6, 0xcb83ca27, 0xff83870b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0189ffff, 0x00000000, 0x00000000}, + {0x780b0ec2, 0xc5f11548, 0xa7743982, 0x9794f9ad, 0x958b2fe3, 0x896d7450, 0xf6323986, 0x52cac124, 0xd3ec562c, + 0xcbf1b74b, 0x5f13589f, 0xfed88d3f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x018bffff, 0x00000000, 0x00000000}, + {0xa731e6c1, 0xb2b8400e, 0x791b997a, 0x5c9de879, 0x7dff69fd, 0x4cb7d0bb, 0x0f4ae368, 0x3c4329c4, 0xf681b41f, + 0xee7cd971, 0x0a67f802, 0xffdbcdb9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x018dffff, 0x00000000, 0x00000000}, + {0xd658bebf, 0x1a76aad4, 0x1ac2f972, 0x0a9b7a01, 0xac6a5c17, 0xf10ecaf6, 0x276e79ba, 0x0b98b870, 0xac75c8d7, + 0x4accf5d7, 0x9df7867b, 0xff30d3ec, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x018fffff, 0x00000000, 0x00000000}, + {0x057f96bd, 0x8235159b, 0xbc6a5969, 0xb8990b88, 0xdad54e30, 0x9565c531, 0x3f92100d, 0xdaee471c, 0x6269dd8e, + 0xa71d123d, 0x318714f3, 0xfe85da20, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0191ffff, 0x00000000, 0x00000000}, + {0x34a66ebc, 0x6efc4061, 0x8e11b961, 0x7da1fa54, 0xc349884a, 0x58b0219c, 0x58aab9ef, 0xc466afbb, 0x84ff3b81, + 0xc9a83463, 0xdcdbb456, 0xff891a99, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0193ffff, 0x00000000, 0x00000000}, + {0x63cd46ba, 0xd6baab27, 0x2fb91958, 0x2b9f8bdc, 0xf1b47a64, 0xfd071bd7, 0x70ce5041, 0x93bc3e67, 0x3af35039, + 0x25f850c9, 0x706b42cf, 0xfede20cd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0195ffff, 0x00000000, 0x00000000}, + {0x92f41eb9, 0xc381d5ed, 0x01607950, 0xf0a87aa8, 0xda28b47d, 0xc0517842, 0x89e6fa23, 0x7d34a706, 0x5d88ae2c, + 0x488372ef, 0x1bbfe232, 0xffe16147, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0197ffff, 0x00000000, 0x00000000}, + {0xc21af6b7, 0x2b4040b3, 0xa307d948, 0x9ea60c2f, 0x0893a697, 0x64a8727e, 0xa20a9076, 0x4c8a35b2, 0x137cc2e4, + 0xa4d38f55, 0xaf4f70aa, 0xff36677a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0199ffff, 0x00000000, 0x00000000}, + {0xf141ceb5, 0x92feab79, 0x44af393f, 0x4ca39db7, 0x36fe98b1, 0x08ff6cb9, 0xba2e26c9, 0x1bdfc45e, 0xc970d79c, + 0x0123abba, 0x42deff23, 0xfe8b6dae, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x019bffff, 0x00000000, 0x00000000}, + {0x2068a6b4, 0x7fc5d640, 0x16569937, 0x11ac8c83, 0x1f72d2cb, 0xcc49c924, 0xd346d0aa, 0x05582cfd, 0xec06358f, + 0x23aecde0, 0xee339e86, 0xff8eae27, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x019dffff, 0x00000000, 0x00000000}, + {0x4f8f7eb2, 0xe7844106, 0xb7fdf92e, 0xbfaa1e0a, 0x4dddc4e4, 0x70a0c35f, 0xeb6a66fd, 0xd4adbba9, 0xa1fa4a46, + 0x7ffeea46, 0x81c32cfe, 0xfee3b45b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x019fffff, 0x00000000, 0x00000000}, + {0x7eb656b1, 0xd44b6bcc, 0x89a55926, 0x84b30cd6, 0x3651fefe, 0x33eb1fca, 0x048310df, 0xbe262449, 0xc48fa839, + 0xa28a0c6c, 0x2d17cc61, 0xffe6f4d5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01a1ffff, 0x00000000, 0x00000000}, + {0xaddd2eaf, 0x3c09d692, 0x2b4cb91e, 0x32b09e5e, 0x64bcf118, 0xd8421a05, 0x1ca6a731, 0x8d7bb2f5, 0x7a83bcf1, + 0xfeda28d2, 0xc0a75ad9, 0xff3bfb08, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01a3ffff, 0x00000000, 0x00000000}, + {0xdd0406ad, 0xa3c84158, 0xccf41915, 0xe0ae2fe5, 0x9327e331, 0x7c991440, 0x34ca3d84, 0x5cd141a1, 0x3077d1a9, + 0x5b2a4538, 0x5436e952, 0xfe91013c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01a5ffff, 0x00000000, 0x00000000}, + {0x0c2adeac, 0x908f6c1f, 0x9e9b790d, 0xa5b71eb1, 0x7b9c1d4b, 0x3fe370ab, 0x4de2e766, 0x4649aa40, 0x530d2f9c, + 0x7db5675e, 0xff8b88b5, 0xff9441b5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01a7ffff, 0x00000000, 0x00000000}, + {0x3b51b6aa, 0xf84dd6e5, 0x4042d904, 0x53b4b039, 0xaa070f65, 0xe43a6ae6, 0x66067db8, 0x159f38ec, 0x09014454, + 0xda0583c4, 0x931b172d, 0xfee947e9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01a9ffff, 0x00000000, 0x00000000}, + {0x6a788ea9, 0xe51501ab, 0x11ea38fc, 0x18bd9f05, 0x927b497f, 0xa784c751, 0x7f1f279a, 0xff17a18b, 0x2b96a246, + 0xfc90a5ea, 0x3e6fb690, 0xffec8863, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01abffff, 0x00000000, 0x00000000}, + {0x999f66a7, 0x4cd36c71, 0xb39198f4, 0xc6bb308c, 0xc0e63b98, 0x4bdbc18c, 0x9742bded, 0xce6d3037, 0xe18ab6fe, + 0x58e0c24f, 0xd1ff4509, 0xff418e96, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01adffff, 0x00000000, 0x00000000}, + {0xc8c63ea5, 0xb491d737, 0x5538f8eb, 0x74b8c214, 0xef512db2, 0xf032bbc7, 0xaf66543f, 0x9dc2bee3, 0x977ecbb6, + 0xb530deb5, 0x658ed381, 0xfe9694ca, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01afffff, 0x00000000, 0x00000000}, + {0xf7ed16a4, 0xa15901fd, 0x26e058e3, 0x39c1b0e0, 0xd7c567cc, 0xb37d1832, 0xc87efe21, 0x873b2782, 0xba1429a9, + 0xd7bc00db, 0x10e372e4, 0xff99d544, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01b1ffff, 0x00000000, 0x00000000}, + {0x2713eea2, 0x09176cc4, 0xc887b8db, 0xe7bf4267, 0x063059e5, 0x57d4126e, 0xe0a29474, 0x5690b62e, 0x70083e61, + 0x340c1d41, 0xa473015d, 0xfeeedb77, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01b3ffff, 0x00000000, 0x00000000}, + {0x563ac6a1, 0xf5de978a, 0x9a2f18d2, 0xacc83133, 0xeea493ff, 0x1b1e6ed8, 0xf9bb3e56, 0x40091ecd, 0x929d9c54, + 0x56973f67, 0x4fc7a0c0, 0xfff21bf1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01b5ffff, 0x00000000, 0x00000000}, + {0x85619e9f, 0x5d9d0250, 0x3bd678ca, 0x5ac5c2bb, 0x1d0f8619, 0xbf756914, 0x11ded4a8, 0x0f5ead7a, 0x4891b10c, + 0xb2e75bcd, 0xe3572f38, 0xff472224, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01b7ffff, 0x00000000, 0x00000000}, + {0xb488769d, 0xc55b6d16, 0xdd7dd8c1, 0x08c35442, 0x4b7a7833, 0x63cc634f, 0x2a026afb, 0xdeb43c26, 0xfe85c5c3, + 0x0f377832, 0x76e6bdb1, 0xfe9c2858, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01b9ffff, 0x00000000, 0x00000000}, + {0xe3af4e9c, 0xb22297dc, 0xaf2538b9, 0xcdcc430e, 0x33eeb24c, 0x2716bfba, 0x431b14dd, 0xc82ca4c5, 0x211b23b6, + 0x31c29a59, 0x223b5d14, 0xff9f68d2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01bbffff, 0x00000000, 0x00000000}, + {0x12d6269a, 0x19e102a3, 0x50cc98b1, 0x7bc9d496, 0x6259a466, 0xcb6db9f5, 0x5b3eab2f, 0x97823371, 0xd70f386e, + 0x8e12b6be, 0xb5caeb8c, 0xfef46f05, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01bdffff, 0x00000000, 0x00000000}, + {0x41fcfe99, 0x06a82d69, 0x2273f8a9, 0x40d2c362, 0x4acdde80, 0x8eb81660, 0x74575511, 0x80fa9c10, 0xf9a49661, + 0xb09dd8e4, 0x611f8aef, 0xfff7af7f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01bfffff, 0x00000000, 0x00000000}, + {0x7123d697, 0x6e66982f, 0xc41b58a0, 0xeed054e9, 0x7938d099, 0x330f109b, 0x8c7aeb64, 0x50502abc, 0xaf98ab19, + 0x0cedf54a, 0xf4af1968, 0xff4cb5b2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01c1ffff, 0x00000000, 0x00000000}, + {0xa04aae95, 0xd62502f5, 0x65c2b897, 0x9ccde671, 0xa7a3c2b3, 0xd7660ad6, 0xa49e81b6, 0x1fa5b968, 0x658cbfd1, + 0x693e11b0, 0x883ea7e0, 0xfea1bbe6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01c3ffff, 0x00000000, 0x00000000}, + {0xcf718694, 0xc2ec2dbb, 0x376a188f, 0x61d6d53d, 0x9017fccd, 0x9ab06741, 0xbdb72b98, 0x091e2207, 0x88221dc4, + 0x8bc933d6, 0x33934743, 0xffa4fc60, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01c5ffff, 0x00000000, 0x00000000}, + {0xfe985e92, 0x2aaa9881, 0xd9117887, 0x0fd466c4, 0xbe82eee7, 0x3f07617c, 0xd5dac1eb, 0xd873b0b3, 0x3e16327b, + 0xe819503c, 0xc722d5bb, 0xfefa0293, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01c7ffff, 0x00000000, 0x00000000}, + {0x2dbf3691, 0x1771c348, 0xaab8d87f, 0xd4dd5590, 0xa6f72900, 0x0251bde7, 0xeef36bcd, 0xc1ec1952, 0x60ab906e, + 0x0aa47262, 0x7277751f, 0xfffd430d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01c9ffff, 0x00000000, 0x00000000}, + {0x5ce60e8f, 0x7f302e0e, 0x4c603876, 0x82dae718, 0xd5621b1a, 0xa6a8b822, 0x0717021f, 0x9141a7ff, 0x169fa526, + 0x66f48ec8, 0x06070397, 0xff524941, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01cbffff, 0x00000000, 0x00000000}, + {0x8c0ce68d, 0xe6ee98d4, 0xee07986d, 0x30d8789f, 0x03cd0d34, 0x4affb25e, 0x1f3a9872, 0x609736ab, 0xcc93b9de, + 0xc344ab2d, 0x9996920f, 0xfea74f74, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01cdffff, 0x00000000, 0x00000000}, + {0xbb33be8c, 0xd3b5c39a, 0xbfaef865, 0xf5e1676b, 0xec41474d, 0x0e4a0ec8, 0x38534254, 0x4a0f9f4a, 0xef2917d1, + 0xe5cfcd53, 0x44eb3172, 0xffaa8fee, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01cfffff, 0x00000000, 0x00000000}, + {0xea5a968a, 0x3b742e60, 0x6156585d, 0xa3def8f3, 0x1aac3967, 0xb2a10904, 0x5076d8a6, 0x19652df6, 0xa51d2c89, + 0x421fe9b9, 0xd87abfeb, 0xfeff9621, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01d1ffff, 0x00000000, 0x00000000}, + {0x19816e88, 0xa3329927, 0x02fdb854, 0x51dc8a7b, 0x49172b81, 0x56f8033f, 0x689a6ef9, 0xe8babca2, 0x5b114140, + 0x9e70061f, 0x6c0a4e63, 0xfe549c55, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01d3ffff, 0x00000000, 0x00000000}, + {0x48a84687, 0x8ff9c3ed, 0xd4a5184c, 0x16e57946, 0x318b659b, 0x1a425faa, 0x81b318db, 0xd2332541, 0x7da69f33, + 0xc0fb2845, 0x175eedc6, 0xff57dccf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01d5ffff, 0x00000000, 0x00000000}, + {0x77cf1e85, 0xf7b82eb3, 0x764c7843, 0xc4e30ace, 0x5ff657b4, 0xbe9959e5, 0x99d6af2d, 0xa188b3ed, 0x339ab3eb, + 0x1d4b44ab, 0xaaee7c3f, 0xfeace302, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01d7ffff, 0x00000000, 0x00000000}, + {0xa6f5f684, 0xe47f5979, 0x47f3d83b, 0x89ebf99a, 0x486a91ce, 0x81e3b650, 0xb2ef590f, 0x8b011c8c, 0x563011de, + 0x3fd666d1, 0x56431ba2, 0xffb0237c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01d9ffff, 0x00000000, 0x00000000}, + {0xd61cce82, 0x4c3dc43f, 0xe99b3833, 0x37e98b21, 0x76d583e8, 0x263ab08b, 0xcb12ef62, 0x5a56ab38, 0x0c242696, + 0x9c268337, 0xe9d2aa1a, 0xff0529af, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01dbffff, 0x00000000, 0x00000000}, + {0x0543a680, 0xb3fc2f06, 0x8b42982a, 0xe5e71ca9, 0xa5407601, 0xca91aac6, 0xe33685b4, 0x29ac39e4, 0xc2183b4e, + 0xf8769f9c, 0x7d623892, 0xfe5a2fe3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ddffff, 0x00000000, 0x00000000}, + {0x346a7e7f, 0xa0c359cc, 0x5ce9f822, 0xaaf00b75, 0x8db4b01b, 0x8ddc0731, 0xfc4f2f96, 0x1324a283, 0xe4ad9941, + 0x1b01c1c2, 0x28b6d7f6, 0xff5d705d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01dfffff, 0x00000000, 0x00000000}, + {0x6391567d, 0x0881c492, 0xfe91581a, 0x58ed9cfc, 0xbc1fa235, 0x3233016c, 0x1472c5e9, 0xe27a3130, 0x9aa1adf8, + 0x7751de28, 0xbc46666e, 0xfeb27690, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01e1ffff, 0x00000000, 0x00000000}, + {0x92b82e7c, 0xf548ef58, 0xd038b811, 0x1df68bc8, 0xa493dc4f, 0xf57d5dd7, 0x2d8b6fca, 0xcbf299cf, 0xbd370beb, + 0x99dd004e, 0x679b05d1, 0xffb5b70a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01e3ffff, 0x00000000, 0x00000000}, + {0xc1df067a, 0x5d075a1e, 0x71e01809, 0xcbf41d50, 0xd2fece68, 0x99d45812, 0x45af061d, 0x9b48287b, 0x732b20a3, + 0xf62d1cb4, 0xfb2a9449, 0xff0abd3d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01e5ffff, 0x00000000, 0x00000000}, + {0xf105de78, 0xc4c5c4e4, 0x13877800, 0x79f1aed8, 0x0169c082, 0x3e2b524e, 0x5dd29c70, 0x6a9db727, 0x291f355b, + 0x527d391a, 0x8eba22c2, 0xfe5fc371, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01e7ffff, 0x00000000, 0x00000000}, + {0x202cb677, 0xb18cefab, 0xe52ed7f8, 0x3efa9da3, 0xe9ddfa9c, 0x0175aeb8, 0x76eb4652, 0x54161fc6, 0x4bb4934e, + 0x75085b40, 0x3a0ec225, 0xff6303eb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01e9ffff, 0x00000000, 0x00000000}, + {0x4f538e75, 0x194b5a71, 0x86d637f0, 0xecf82f2b, 0x1848ecb5, 0xa5cca8f4, 0x8f0edca4, 0x236bae72, 0x01a8a806, + 0xd15877a6, 0xcd9e509d, 0xfeb80a1e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ebffff, 0x00000000, 0x00000000}, + {0x7e7a6674, 0x06128537, 0x587d97e8, 0xb2011df7, 0x00bd26cf, 0x6917055f, 0xa8278686, 0x0ce41711, 0x243e05f9, + 0xf3e399cc, 0x78f2f000, 0xffbb4a98, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01edffff, 0x00000000, 0x00000000}, + {0xada13e72, 0x6dd0effd, 0xfa24f7df, 0x5ffeaf7e, 0x2f2818e9, 0x0d6dff9a, 0xc04b1cd9, 0xdc39a5bd, 0xda321ab0, + 0x5033b631, 0x0c827e79, 0xff1050cc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01efffff, 0x00000000, 0x00000000}, + {0xdcc81670, 0xd58f5ac3, 0x9bcc57d6, 0x0dfc4106, 0x5d930b03, 0xb1c4f9d5, 0xd86eb32b, 0xab8f3469, 0x90262f68, + 0xac83d297, 0xa0120cf1, 0xfe6556ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01f1ffff, 0x00000000, 0x00000000}, + {0x0beeee6f, 0xc256858a, 0x6d73b7ce, 0xd3052fd2, 0x4607451c, 0x750f5640, 0xf1875d0d, 0x95079d08, 0xb2bb8d5b, + 0xcf0ef4bd, 0x4b66ac54, 0xff689779, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01f3ffff, 0x00000000, 0x00000000}, + {0x3b15c66d, 0x2a14f050, 0x0f1b17c6, 0x8102c15a, 0x74723736, 0x1966507b, 0x09aaf360, 0x645d2bb5, 0x68afa213, + 0x2b5f1123, 0xdef63acd, 0xfebd9dac, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01f5ffff, 0x00000000, 0x00000000}, + {0x6a3c9e6c, 0x16dc1b16, 0xe0c277be, 0x460bb025, 0x5ce67150, 0xdcb0ace6, 0x22c39d41, 0x4dd59454, 0x8b450006, + 0x4dea3349, 0x8a4ada30, 0xffc0de26, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01f7ffff, 0x00000000, 0x00000000}, + {0x9963766a, 0x7e9a85dc, 0x8269d7b5, 0xf40941ad, 0x8b516369, 0x8107a721, 0x3ae73394, 0x1d2b2300, 0x413914be, + 0xaa3a4faf, 0x1dda68a8, 0xff15e45a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01f9ffff, 0x00000000, 0x00000000}, + {0xc88a4e68, 0xe658f0a2, 0x241137ac, 0xa206d335, 0xb9bc5583, 0x255ea15c, 0x530ac9e7, 0xec80b1ac, 0xf72d2975, + 0x068a6c14, 0xb169f721, 0xfe6aea8d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01fbffff, 0x00000000, 0x00000000}, + {0xf7b12667, 0xd3201b68, 0xf5b897a4, 0x670fc200, 0xa2308f9d, 0xe8a8fdc7, 0x6c2373c8, 0xd5f91a4b, 0x19c28768, + 0x29158e3b, 0x5cbe9684, 0xff6e2b07, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01fdffff, 0x00000000, 0x00000000}, + {0x26d7fe65, 0x3ade862f, 0x975ff79c, 0x150d5388, 0xd09b81b7, 0x8cfff802, 0x84470a1b, 0xa54ea8f7, 0xcfb69c20, + 0x8565aaa0, 0xf04e24fc, 0xfec3313a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff, 0x00000000, 0x00000000}, + {0x55fed664, 0x27a5b0f5, 0x69075794, 0xda164254, 0xb90fbbd0, 0x504a546d, 0x9d5fb3fd, 0x8ec71196, 0xf24bfa13, + 0xa7f0ccc6, 0x9ba2c45f, 0xffc671b4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0201ffff, 0x00000000, 0x00000000}, + {0x8525ae62, 0x8f641bbb, 0x0aaeb78b, 0x8813d3dc, 0xe77aadea, 0xf4a14ea8, 0xb5834a4f, 0x5e1ca042, 0xa8400ecb, + 0x0440e92c, 0x2f3252d8, 0xff1b77e8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0203ffff, 0x00000000, 0x00000000}, + {0xb44c8660, 0xf7228681, 0xac561782, 0x36116563, 0x15e5a004, 0x98f848e4, 0xcda6e0a2, 0x2d722eee, 0x5e342383, + 0x60910592, 0xc2c1e150, 0xfe707e1b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0205ffff, 0x00000000, 0x00000000}, + {0xe3735e5f, 0xe3e9b147, 0x7dfd777a, 0xfb1a542f, 0xfe59da1d, 0x5c42a54e, 0xe6bf8a84, 0x16ea978d, 0x80c98176, + 0x831c27b8, 0x6e1680b3, 0xff73be95, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0207ffff, 0x00000000, 0x00000000}, + {0x129a365d, 0x4ba81c0e, 0x1fa4d772, 0xa917e5b7, 0x2cc4cc37, 0x00999f8a, 0xfee320d7, 0xe6402639, 0x36bd962d, + 0xdf6c441e, 0x01a60f2b, 0xfec8c4c9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0209ffff, 0x00000000, 0x00000000}, + {0x41c10e5c, 0x386f46d4, 0xf14c376a, 0x6e20d482, 0x15390651, 0xc3e3fbf5, 0x17fbcab8, 0xcfb88ed9, 0x5952f420, + 0x01f76644, 0xacfaae8f, 0xffcc0542, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x020bffff, 0x00000000, 0x00000000}, + {0x70e7e65a, 0xa02db19a, 0x92f39761, 0x1c1e660a, 0x43a3f86b, 0x683af630, 0x301f610b, 0x9f0e1d85, 0x0f4708d8, + 0x5e4782aa, 0x408a3d07, 0xff210b76, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x020dffff, 0x00000000, 0x00000000}, + {0xa00ebe58, 0x07ec1c60, 0x349af759, 0xca1bf792, 0x720eea84, 0x0c91f06b, 0x4842f75e, 0x6e63ac31, 0xc53b1d90, + 0xba979f0f, 0xd419cb7f, 0xfe7611a9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x020fffff, 0x00000000, 0x00000000}, + {0xcf359657, 0xf4b34726, 0x06425750, 0x8f24e65e, 0x5a83249e, 0xcfdc4cd6, 0x615ba13f, 0x57dc14d0, 0xe7d07b83, + 0xdd22c135, 0x7f6e6ae2, 0xff795223, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0211ffff, 0x00000000, 0x00000000}, + {0xfe5c6e55, 0x5c71b1ec, 0xa7e9b748, 0x3d2277e5, 0x88ee16b8, 0x74334711, 0x797f3792, 0x2731a37c, 0x9dc4903b, + 0x3972dd9b, 0x12fdf95b, 0xfece5857, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0213ffff, 0x00000000, 0x00000000}, + {0x2d834654, 0x4938dcb3, 0x79911740, 0x022b66b1, 0x716250d2, 0x377da37c, 0x9297e174, 0x10aa0c1b, 0xc059ee2e, + 0x5bfdffc1, 0xbe5298be, 0xffd198d0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0215ffff, 0x00000000, 0x00000000}, + {0x5caa1e52, 0xb0f74779, 0x1b387737, 0xb028f839, 0x9fcd42eb, 0xdbd49db7, 0xaabb77c6, 0xdfff9ac7, 0x764e02e5, + 0xb84e1c27, 0x51e22736, 0xff269f04, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0217ffff, 0x00000000, 0x00000000}, + {0x8bd0f650, 0x18b5b23f, 0xbcdfd72f, 0x5e2689c0, 0xce383505, 0x802b97f2, 0xc2df0e19, 0xaf552973, 0x2c42179d, + 0x149e388d, 0xe571b5af, 0xfe7ba537, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0219ffff, 0x00000000, 0x00000000}, + {0xbaf7ce4f, 0x057cdd05, 0x8e873727, 0x232f788c, 0xb6ac6f1f, 0x4375f45d, 0xdbf7b7fb, 0x98cd9212, 0x4ed77590, + 0x37295ab3, 0x90c65512, 0xff7ee5b1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x021bffff, 0x00000000, 0x00000000}, + {0xea1ea64d, 0x6d3b47cb, 0x302e971e, 0xd12d0a14, 0xe5176138, 0xe7ccee98, 0xf41b4e4d, 0x682320be, 0x04cb8a48, + 0x93797719, 0x2455e38a, 0xfed3ebe5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x021dffff, 0x00000000, 0x00000000}, + {0x19457e4c, 0x5a027292, 0x01d5f716, 0x9635f8e0, 0xcd8b9b52, 0xab174b03, 0x0d33f82f, 0x519b895e, 0x2760e83b, + 0xb604993f, 0xcfaa82ed, 0xffd72c5e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x021fffff, 0x00000000, 0x00000000}, + {0x486c564a, 0xc1c0dd58, 0xa37d570d, 0x44338a67, 0xfbf68d6c, 0x4f6e453e, 0x25578e82, 0x20f1180a, 0xdd54fcf3, + 0x1254b5a4, 0x633a1166, 0xff2c3292, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0221ffff, 0x00000000, 0x00000000}, + {0x77932e48, 0x297f481e, 0x4524b705, 0xf2311bef, 0x2a617f85, 0xf3c53f7a, 0x3d7b24d4, 0xf046a6b6, 0x934911aa, + 0x6ea4d20a, 0xf6c99fde, 0xfe8138c5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0223ffff, 0x00000000, 0x00000000}, + {0xa6ba0647, 0x164672e4, 0x16cc16fd, 0xb73a0abb, 0x12d5b99f, 0xb70f9be5, 0x5693ceb6, 0xd9bf0f55, 0xb5de6f9d, + 0x912ff430, 0xa21e3f41, 0xff84793f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0225ffff, 0x00000000, 0x00000000}, + {0xd5e0de45, 0x7e04ddaa, 0xb87376f4, 0x65379c42, 0x4140abb9, 0x5b669620, 0x6eb76509, 0xa9149e01, 0x6bd28455, + 0xed801096, 0x35adcdb9, 0xfed97f73, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0227ffff, 0x00000000, 0x00000000}, + {0x0507b644, 0x6acc0871, 0x8a1ad6ec, 0x2a408b0e, 0x29b4e5d3, 0x1eb0f28b, 0x87d00eeb, 0x928d06a0, 0x8e67e248, + 0x100b32bc, 0xe1026d1d, 0xffdcbfec, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0229ffff, 0x00000000, 0x00000000}, + {0x342e8e42, 0xd28a7337, 0x2bc236e3, 0xd83e1c96, 0x581fd7ec, 0xc307ecc6, 0x9ff3a53d, 0x61e2954c, 0x445bf700, + 0x6c5b4f22, 0x7491fb95, 0xff31c620, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x022bffff, 0x00000000, 0x00000000}, + {0x63556640, 0x3a48ddfd, 0xcd6996db, 0x863bae1d, 0x868aca06, 0x675ee701, 0xb8173b90, 0x313823f8, 0xfa500bb8, + 0xc8ab6b87, 0x08218a0d, 0xfe86cc54, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x022dffff, 0x00000000, 0x00000000}, + {0x927c3e3f, 0x271008c3, 0x9f10f6d3, 0x4b449ce9, 0x6eff0420, 0x2aa9436c, 0xd12fe572, 0x1ab08c97, 0x1ce569ab, + 0xeb368dae, 0xb3762970, 0xff8a0ccd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x022fffff, 0x00000000, 0x00000000}, + {0xc1a3163d, 0x8ece7389, 0x40b856ca, 0xf9422e71, 0x9d69f639, 0xcf003da7, 0xe9537bc4, 0xea061b43, 0xd2d97e62, + 0x4786aa13, 0x4705b7e9, 0xfedf1301, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0231ffff, 0x00000000, 0x00000000}, + {0xf0c9ee3c, 0x7b959e4f, 0x125fb6c2, 0xbe4b1d3d, 0x85de3053, 0x924a9a12, 0x026c25a6, 0xd37e83e3, 0xf56edc55, + 0x6a11cc39, 0xf25a574c, 0xffe2537a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0233ffff, 0x00000000, 0x00000000}, + {0x1ff0c63a, 0xe3540916, 0xb40716b9, 0x6c48aec4, 0xb449226d, 0x36a1944d, 0x1a8fbbf9, 0xa2d4128f, 0xab62f10d, + 0xc661e89f, 0x85e9e5c4, 0xff3759ae, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0235ffff, 0x00000000, 0x00000000}, + {0x4f179e38, 0x4b1273dc, 0x55ae76b1, 0x1a46404c, 0xe2b41487, 0xdaf88e88, 0x32b3524b, 0x7229a13b, 0x615705c5, + 0x22b20505, 0x1979743d, 0xfe8c5fe2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0237ffff, 0x00000000, 0x00000000}, + {0x7e3e7637, 0x37d99ea2, 0x2755d6a9, 0xdf4f2f18, 0xcb284ea0, 0x9e42eaf3, 0x4bcbfc2d, 0x5ba209da, 0x83ec63b8, + 0x453d272b, 0xc4ce13a0, 0xff8fa05b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0239ffff, 0x00000000, 0x00000000}, + {0xad654e35, 0x9f980968, 0xc8fd36a0, 0x8d4cc09f, 0xf99340ba, 0x4299e52e, 0x63ef9280, 0x2af79886, 0x39e07870, + 0xa18d4391, 0x585da218, 0xfee4a68f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x023bffff, 0x00000000, 0x00000000}, + {0xdc8c2634, 0x8c5f342e, 0x9aa49698, 0x5255af6b, 0xe2077ad4, 0x05e44199, 0x7d083c62, 0x14700125, 0x5c75d663, + 0xc41865b7, 0x03b2417b, 0xffe7e709, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x023dffff, 0x00000000, 0x00000000}, + {0x0bb2fe32, 0xf41d9ef5, 0x3c4bf68f, 0x005340f3, 0x10726cee, 0xaa3b3bd5, 0x952bd2b4, 0xe3c58fd1, 0x1269eb1a, + 0x2068821d, 0x9741cff4, 0xff3ced3c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x023fffff, 0x00000000, 0x00000000}, + {0x3ad9d630, 0x5bdc09bb, 0xddf35687, 0xae50d27a, 0x3edd5f07, 0x4e923610, 0xad4f6907, 0xb31b1e7d, 0xc85dffd2, + 0x7cb89e82, 0x2ad15e6c, 0xfe91f370, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0241ffff, 0x00000000, 0x00000000}, + {0x6a00ae2f, 0x48a33481, 0xaf9ab67f, 0x7359c146, 0x27519921, 0x11dc927b, 0xc66812e9, 0x9c93871c, 0xeaf35dc5, + 0x9f43c0a8, 0xd625fdcf, 0xff9533e9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0243ffff, 0x00000000, 0x00000000}, + {0x9927862d, 0xb0619f47, 0x51421676, 0x215752ce, 0x55bc8b3b, 0xb6338cb6, 0xde8ba93b, 0x6be915c8, 0xa0e7727d, + 0xfb93dd0e, 0x69b58c47, 0xfeea3a1d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0245ffff, 0x00000000, 0x00000000}, + {0xc84e5e2c, 0x9d28ca0d, 0x22e9766e, 0xe660419a, 0x3e30c554, 0x797de921, 0xf7a4531d, 0x55617e67, 0xc37cd070, + 0x1e1eff34, 0x150a2bab, 0xffed7a97, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0247ffff, 0x00000000, 0x00000000}, + {0xf775362a, 0x04e734d3, 0xc490d666, 0x945dd321, 0x6c9bb76e, 0x1dd4e35c, 0x0fc7e970, 0x24b70d14, 0x7970e528, + 0x7a6f1b9a, 0xa899ba23, 0xff4280ca, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0249ffff, 0x00000000, 0x00000000}, + {0x269c0e28, 0x6ca59f9a, 0x6638365d, 0x425b64a9, 0x9b06a988, 0xc22bdd97, 0x27eb7fc2, 0xf40c9bc0, 0x2f64f9df, + 0xd6bf3800, 0x3c29489b, 0xfe9786fe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x024bffff, 0x00000000, 0x00000000}, + {0x55c2e627, 0x596cca60, 0x37df9655, 0x07645375, 0x837ae3a2, 0x85763a02, 0x410429a4, 0xdd85045f, 0x51fa57d2, + 0xf94a5a26, 0xe77de7fe, 0xff9ac777, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x024dffff, 0x00000000, 0x00000000}, + {0x84e9be25, 0xc12b3526, 0xd986f64c, 0xb561e4fc, 0xb1e5d5bb, 0x29cd343d, 0x5927bff7, 0xacda930b, 0x07ee6c8a, + 0x559a768c, 0x7b0d7677, 0xfeefcdab, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x024fffff, 0x00000000, 0x00000000}, + {0xb4109624, 0xadf25fec, 0xab2e5644, 0x7a6ad3c8, 0x9a5a0fd5, 0xed1790a8, 0x724069d8, 0x9652fbaa, 0x2a83ca7d, + 0x782598b2, 0x266215da, 0xfff30e25, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0251ffff, 0x00000000, 0x00000000}, + {0xe3376e22, 0x15b0cab2, 0x4cd5b63c, 0x28686550, 0xc8c501ef, 0x916e8ae3, 0x8a64002b, 0x65a88a56, 0xe077df35, + 0xd475b517, 0xb9f1a452, 0xff481458, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0253ffff, 0x00000000, 0x00000000}, + {0x125e4620, 0x7d6f3579, 0xee7d1633, 0xd665f6d7, 0xf72ff408, 0x35c5851e, 0xa287967e, 0x34fe1902, 0x966bf3ed, + 0x30c5d17d, 0x4d8132cb, 0xfe9d1a8c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0255ffff, 0x00000000, 0x00000000}, + {0x41851e1f, 0x6a36603f, 0xc024762b, 0x9b6ee5a3, 0xdfa42e22, 0xf90fe189, 0xbba0405f, 0x1e7681a1, 0xb90151e0, + 0x5350f3a3, 0xf8d5d22e, 0xffa05b05, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0257ffff, 0x00000000, 0x00000000}, + {0x70abf61d, 0xd1f4cb05, 0x61cbd622, 0x496c772b, 0x0e0f203c, 0x9d66dbc5, 0xd3c3d6b2, 0xedcc104d, 0x6ef56697, + 0xafa11009, 0x8c6560a6, 0xfef56139, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0259ffff, 0x00000000, 0x00000000}, + {0x9fd2ce1c, 0xbebbf5cb, 0x3373361a, 0x0e7565f7, 0xf6835a56, 0x60b1382f, 0xecdc8094, 0xd74478ec, 0x918ac48a, + 0xd22c322f, 0x37ba0009, 0xfff8a1b3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x025bffff, 0x00000000, 0x00000000}, + {0xcef9a61a, 0x267a6091, 0xd51a9612, 0xbc72f77e, 0x24ee4c6f, 0x0508326b, 0x050016e7, 0xa69a0799, 0x477ed942, + 0x2e7c4e95, 0xcb498e82, 0xff4da7e6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x025dffff, 0x00000000, 0x00000000}, + {0xfe207e18, 0x8e38cb57, 0x76c1f609, 0x6a708906, 0x53593e89, 0xa95f2ca6, 0x1d23ad39, 0x75ef9645, 0xfd72edfa, + 0x8acc6afa, 0x5ed91cfa, 0xfea2ae1a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x025fffff, 0x00000000, 0x00000000}, + {0x2d475617, 0x7afff61e, 0x48695601, 0x2f7977d2, 0x3bcd78a3, 0x6ca98911, 0x363c571b, 0x5f67fee4, 0x20084bed, + 0xad578d21, 0x0a2dbc5d, 0xffa5ee94, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0261ffff, 0x00000000, 0x00000000}, + {0x5c6e2e15, 0xe2be60e4, 0xea10b5f8, 0xdd770959, 0x6a386abc, 0x1100834c, 0x4e5fed6e, 0x2ebd8d90, 0xd5fc60a5, + 0x09a7a986, 0x9dbd4ad6, 0xfefaf4c7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0263ffff, 0x00000000, 0x00000000}, + {0x8b950614, 0xcf858baa, 0xbbb815f0, 0xa27ff825, 0x52aca4d6, 0xd44adfb7, 0x6778974f, 0x1835f62f, 0xf891be98, + 0x2c32cbac, 0x4911ea39, 0xfffe3541, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0265ffff, 0x00000000, 0x00000000}, + {0xbabbde12, 0x3743f670, 0x5d5f75e8, 0x507d89ad, 0x811796f0, 0x78a1d9f2, 0x7f9c2da2, 0xe78b84db, 0xae85d34f, + 0x8882e812, 0xdca178b1, 0xff533b74, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0267ffff, 0x00000000, 0x00000000}, + {0xe9e2b610, 0x9f026136, 0xff06d5df, 0xfe7b1b34, 0xaf828909, 0x1cf8d42d, 0x97bfc3f5, 0xb6e11387, 0x6479e807, + 0xe4d30478, 0x70310729, 0xfea841a8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0269ffff, 0x00000000, 0x00000000}, + {0x19098e0f, 0x8bc98bfd, 0xd0ae35d7, 0xc3840a00, 0x97f6c323, 0xe0433098, 0xb0d86dd6, 0xa0597c26, 0x870f45fa, + 0x075e269e, 0x1b85a68d, 0xffab8222, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x026bffff, 0x00000000, 0x00000000}, + {0x4830660d, 0xf387f6c3, 0x725595ce, 0x71819b88, 0xc661b53d, 0x849a2ad3, 0xc8fc0429, 0x6faf0ad2, 0x3d035ab2, + 0x63ae4304, 0xaf153505, 0xff008855, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x026dffff, 0x00000000, 0x00000000}, + {0x77573e0b, 0x5b466189, 0x13fcf5c6, 0x1f7f2d10, 0xf4cca757, 0x28f1250e, 0xe11f9a7c, 0x3f04997e, 0xf2f76f6a, + 0xbffe5f69, 0x42a4c37d, 0xfe558e89, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x026fffff, 0x00000000, 0x00000000}, + {0xa67e160a, 0x480d8c4f, 0xe5a455be, 0xe4881bdb, 0xdd40e170, 0xec3b8179, 0xfa38445d, 0x287d021d, 0x158ccd5d, + 0xe2898190, 0xedf962e0, 0xff58cf02, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0271ffff, 0x00000000, 0x00000000}, + {0xd5a4ee08, 0xafcbf715, 0x874bb5b5, 0x9285ad63, 0x0babd38a, 0x90927bb5, 0x125bdab0, 0xf7d290ca, 0xcb80e214, + 0x3ed99df5, 0x8188f159, 0xfeadd536, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0273ffff, 0x00000000, 0x00000000}, + {0x04cbc607, 0x9c9321dc, 0x58f315ad, 0x578e9c2f, 0xf4200da4, 0x53dcd81f, 0x2b748492, 0xe14af969, 0xee164007, + 0x6164c01b, 0x2cdd90bc, 0xffb115b0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0275ffff, 0x00000000, 0x00000000}, + {0x33f29e05, 0x04518ca2, 0xfa9a75a5, 0x058c2db6, 0x228affbe, 0xf833d25b, 0x43981ae4, 0xb0a08815, 0xa40a54bf, + 0xbdb4dc81, 0xc06d1f34, 0xff061be3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0277ffff, 0x00000000, 0x00000000}, + {0x63197603, 0x6c0ff768, 0x9c41d59c, 0xb389bf3e, 0x50f5f1d7, 0x9c8acc96, 0x5bbbb137, 0x7ff616c1, 0x59fe6977, + 0x1a04f8e7, 0x53fcadad, 0xfe5b2217, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0279ffff, 0x00000000, 0x00000000}, + {0x92404e02, 0x58d7222e, 0x6de93594, 0x7892ae0a, 0x396a2bf1, 0x5fd52901, 0x74d45b19, 0x696e7f60, 0x7c93c76a, + 0x3c901b0d, 0xff514d10, 0xff5e6290, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x027bffff, 0x00000000, 0x00000000}, + {0xc1672600, 0xc0958cf4, 0x0f90958b, 0x26903f92, 0x67d51e0b, 0x042c233c, 0x8cf7f16c, 0x38c40e0c, 0x3287dc22, + 0x98e03773, 0x92e0db88, 0xfeb368c4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x027dffff, 0x00000000, 0x00000000}, + {0xf08dfdff, 0xad5cb7ba, 0xe137f583, 0xeb992e5d, 0x50495824, 0xc7767fa7, 0xa6109b4d, 0x223c76ab, 0x551d3a15, + 0xbb6b5999, 0x3e357aeb, 0xffb6a93e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x027fffff, 0x00000000, 0x00000000}, + {0x1fb4d5fd, 0x151b2281, 0x82df557b, 0x9996bfe5, 0x7eb44a3e, 0x6bcd79e2, 0xbe3431a0, 0xf1920557, 0x0b114ecc, + 0x17bb75ff, 0xd1c50964, 0xff0baf71, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0281ffff, 0x00000000, 0x00000000}, + {0x4edbadfb, 0x7cd98d47, 0x2486b572, 0x4794516d, 0xad1f3c58, 0x1024741d, 0xd657c7f3, 0xc0e79403, 0xc1056384, + 0x740b9264, 0x655497dc, 0xfe60b5a5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0283ffff, 0x00000000, 0x00000000}, + {0x7e0285fa, 0x69a0b80d, 0xf62e156a, 0x0c9d4038, 0x95937672, 0xd36ed088, 0xef7071d4, 0xaa5ffca2, 0xe39ac177, + 0x9696b48a, 0x10a9373f, 0xff63f61f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0285ffff, 0x00000000, 0x00000000}, + {0xad295df8, 0xd15f22d3, 0x97d57561, 0xba9ad1c0, 0xc3fe688b, 0x77c5cac3, 0x07940827, 0x79b58b4f, 0x998ed62f, + 0xf2e6d0f0, 0xa438c5b7, 0xfeb8fc52, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0287ffff, 0x00000000, 0x00000000}, + {0xdc5035f7, 0xbe264d99, 0x697cd559, 0x7fa3c08c, 0xac72a2a5, 0x3b10272e, 0x20acb209, 0x632df3ee, 0xbc243422, + 0x1571f316, 0x4f8d651b, 0xffbc3ccc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0289ffff, 0x00000000, 0x00000000}, + {0x0b770df5, 0x25e4b860, 0x0b243551, 0x2da15214, 0xdadd94bf, 0xdf672169, 0x38d0485b, 0x3283829a, 0x721848da, + 0x71c20f7c, 0xe31cf393, 0xff1142ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x028bffff, 0x00000000, 0x00000000}, + {0x3a9de5f3, 0x8da32326, 0xaccb9548, 0xdb9ee39b, 0x094886d8, 0x83be1ba5, 0x50f3deae, 0x01d91146, 0x280c5d92, + 0xce122be2, 0x76ac820b, 0xfe664933, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x028dffff, 0x00000000, 0x00000000}, + {0x69c4bdf2, 0x7a6a4dec, 0x7e72f540, 0xa0a7d267, 0xf1bcc0f2, 0x4708780f, 0x6a0c8890, 0xeb5179e5, 0x4aa1bb84, + 0xf09d4e08, 0x2201216e, 0xff6989ad, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x028fffff, 0x00000000, 0x00000000}, + {0x98eb95f0, 0xe228b8b2, 0x201a5537, 0x4ea563ef, 0x2027b30c, 0xeb5f724b, 0x82301ee2, 0xbaa70891, 0x0095d03c, + 0x4ced6a6e, 0xb590afe7, 0xfebe8fe0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0291ffff, 0x00000000, 0x00000000}, + {0xc8126def, 0xceefe378, 0xf1c1b52f, 0x13ae52ba, 0x089bed26, 0xaea9ceb6, 0x9b48c8c4, 0xa41f7130, 0x232b2e2f, + 0x6f788c94, 0x60e54f4a, 0xffc1d05a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0293ffff, 0x00000000, 0x00000000}, + {0xf73945ed, 0x36ae4e3e, 0x93691527, 0xc1abe442, 0x3706df3f, 0x5300c8f1, 0xb36c5f17, 0x7374ffdc, 0xd91f42e7, + 0xcbc8a8f9, 0xf474ddc2, 0xff16d68d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0295ffff, 0x00000000, 0x00000000}, + {0x26601deb, 0x9e6cb905, 0x3510751e, 0x6fa975ca, 0x6571d159, 0xf757c32c, 0xcb8ff569, 0x42ca8e88, 0x8f13579f, + 0x2818c55f, 0x88046c3b, 0xfe6bdcc1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0297ffff, 0x00000000, 0x00000000}, + {0x5586f5ea, 0x8b33e3cb, 0x06b7d516, 0x34b26496, 0x4de60b73, 0xbaa21f97, 0xe4a89f4b, 0x2c42f727, 0xb1a8b592, + 0x4aa3e785, 0x33590b9e, 0xff6f1d3b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0299ffff, 0x00000000, 0x00000000}, + {0x84adcde8, 0xf2f24e91, 0xa85f350d, 0xe2aff61d, 0x7c50fd8c, 0x5ef919d2, 0xfccc359e, 0xfb9885d3, 0x679cca49, + 0xa6f403eb, 0xc6e89a16, 0xfec4236e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x029bffff, 0x00000000, 0x00000000}, + {0xb3d4a5e7, 0xdfb97957, 0x7a069505, 0xa7b8e4e9, 0x64c537a6, 0x2243763d, 0x15e4df80, 0xe510ee73, 0x8a32283c, + 0xc97f2611, 0x723d3979, 0xffc763e8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x029dffff, 0x00000000, 0x00000000}, + {0xe2fb7de5, 0x4777e41d, 0x1badf4fd, 0x55b67671, 0x933029c0, 0xc69a7078, 0x2e0875d2, 0xb4667d1f, 0x40263cf4, + 0x25cf4277, 0x05ccc7f2, 0xff1c6a1c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x029fffff, 0x00000000, 0x00000000}, + {0x122255e3, 0xaf364ee4, 0xbd5554f4, 0x03b407f8, 0xc19b1bda, 0x6af16ab3, 0x462c0c25, 0x83bc0bcb, 0xf61a51ac, + 0x821f5edc, 0x995c566a, 0xfe71704f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02a1ffff, 0x00000000, 0x00000000}, + {0x41492de2, 0x9bfd79aa, 0x8efcb4ec, 0xc8bcf6c4, 0xaa0f55f3, 0x2e3bc71e, 0x5f44b607, 0x6d34746a, 0x18afaf9f, + 0xa4aa8103, 0x44b0f5cd, 0xff74b0c9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02a3ffff, 0x00000000, 0x00000000}, + {0x707005e0, 0x03bbe470, 0x30a414e4, 0x76ba884c, 0xd87a480d, 0xd292c159, 0x77684c59, 0x3c8a0316, 0xcea3c457, + 0x00fa9d68, 0xd8408446, 0xfec9b6fc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02a5ffff, 0x00000000, 0x00000000}, + {0x9f96dddf, 0xf0830f36, 0x024b74db, 0x3bc37718, 0xc0ee8227, 0x95dd1dc4, 0x9080f63b, 0x26026bb5, 0xf139224a, + 0x2385bf8e, 0x839523a9, 0xffccf776, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02a7ffff, 0x00000000, 0x00000000}, + {0xcebdb5dd, 0x584179fc, 0xa3f2d4d3, 0xe9c1089f, 0xef597440, 0x3a3417ff, 0xa8a48c8e, 0xf557fa61, 0xa72d3701, + 0x7fd5dbf4, 0x1724b221, 0xff21fdaa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02a9ffff, 0x00000000, 0x00000000}, + {0xfde48ddb, 0xbfffe4c2, 0x459a34ca, 0x97be9a27, 0x1dc4665a, 0xde8b123b, 0xc0c822e0, 0xc4ad890d, 0x5d214bb9, + 0xdc25f85a, 0xaab44099, 0xfe7703dd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02abffff, 0x00000000, 0x00000000}, + {0x2d0b65da, 0xacc70f89, 0x174194c2, 0x5cc788f3, 0x0638a074, 0xa1d56ea6, 0xd9e0ccc2, 0xae25f1ac, 0x7fb6a9ac, + 0xfeb11a80, 0x5608dffc, 0xff7a4457, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02adffff, 0x00000000, 0x00000000}, + {0x5c323dd8, 0x14857a4f, 0xb8e8f4ba, 0x0ac51a7a, 0x34a3928e, 0x462c68e1, 0xf2046315, 0x7d7b8058, 0x35aabe64, + 0x5b0136e6, 0xe9986e75, 0xfecf4a8a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02afffff, 0x00000000, 0x00000000}, + {0x8b5915d7, 0x014ca515, 0x8a9054b2, 0xcfce0946, 0x1d17cca7, 0x0976c54c, 0x0b1d0cf7, 0x66f3e8f8, 0x58401c57, + 0x7d8c590c, 0x94ed0dd8, 0xffd28b04, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02b1ffff, 0x00000000, 0x00000000}, + {0xba7fedd5, 0x690b0fdb, 0x2c37b4a9, 0x7dcb9ace, 0x4b82bec1, 0xadcdbf87, 0x2340a349, 0x364977a4, 0x0e34310f, + 0xd9dc7572, 0x287c9c50, 0xff279138, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02b3ffff, 0x00000000, 0x00000000}, + {0xe9a6c5d3, 0xd0c97aa1, 0xcddf14a0, 0x2bc92c55, 0x79edb0db, 0x5224b9c2, 0x3b64399c, 0x059f0650, 0xc42845c7, + 0x362c91d7, 0xbc0c2ac9, 0xfe7c976b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02b5ffff, 0x00000000, 0x00000000}, + {0x18cd9dd2, 0xbd90a568, 0x9f867498, 0xf0d21b21, 0x6261eaf4, 0x156f162d, 0x547ce37e, 0xef176eef, 0xe6bda3b9, + 0x58b7b3fd, 0x6760ca2c, 0xff7fd7e5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02b7ffff, 0x00000000, 0x00000000}, + {0x47f475d0, 0x254f102e, 0x412dd490, 0x9ecfaca9, 0x90ccdd0e, 0xb9c61068, 0x6ca079d0, 0xbe6cfd9b, 0x9cb1b871, + 0xb507d063, 0xfaf058a4, 0xfed4de18, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02b9ffff, 0x00000000, 0x00000000}, + {0x771b4dcf, 0x12163af4, 0x12d53488, 0x63d89b75, 0x79411728, 0x7d106cd3, 0x85b923b2, 0xa7e5663a, 0xbf471664, + 0xd792f289, 0xa644f807, 0xffd81e92, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02bbffff, 0x00000000, 0x00000000}, + {0xa64225cd, 0x79d4a5ba, 0xb47c947f, 0x11d62cfc, 0xa7ac0942, 0x2167670e, 0x9ddcba05, 0x773af4e6, 0x753b2b1c, + 0x33e30eef, 0x39d48680, 0xff2d24c6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02bdffff, 0x00000000, 0x00000000}, + {0xd568fdcb, 0xe1931080, 0x5623f476, 0xbfd3be84, 0xd616fb5b, 0xc5be6149, 0xb6005057, 0x46908392, 0x2b2f3fd4, + 0x90332b55, 0xcd6414f8, 0xfe822af9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02bfffff, 0x00000000, 0x00000000}, + {0x048fd5ca, 0xce5a3b47, 0x27cb546e, 0x84dcad50, 0xbe8b3575, 0x8908bdb4, 0xcf18fa39, 0x3008ec31, 0x4dc49dc7, + 0xb2be4d7b, 0x78b8b45b, 0xff856b73, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02c1ffff, 0x00000000, 0x00000000}, + {0x33b6adc8, 0x3618a60d, 0xc972b466, 0x32da3ed7, 0xecf6278f, 0x2d5fb7ef, 0xe73c908c, 0xff5e7add, 0x03b8b27e, + 0x0f0e69e1, 0x0c4842d4, 0xfeda71a7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02c3ffff, 0x00000000, 0x00000000}, + {0x62dd85c7, 0x22dfd0d3, 0x9b1a145e, 0xf7e32da3, 0xd56a61a8, 0xf0aa145a, 0x00553a6d, 0xe8d6e37d, 0x264e1071, + 0x31998c07, 0xb79ce237, 0xffddb220, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02c5ffff, 0x00000000, 0x00000000}, + {0x92045dc5, 0x8a9e3b99, 0x3cc17455, 0xa5e0bf2b, 0x03d553c2, 0x95010e96, 0x1878d0c0, 0xb82c7229, 0xdc422529, + 0x8de9a86c, 0x4b2c70af, 0xff32b854, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02c7ffff, 0x00000000, 0x00000000}, + {0xc12b35c3, 0xf25ca65f, 0xde68d44c, 0x53de50b2, 0x324045dc, 0x395808d1, 0x309c6713, 0x878200d5, 0x923639e1, + 0xea39c4d2, 0xdebbff27, 0xfe87be87, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02c9ffff, 0x00000000, 0x00000000}, + {0xf0520dc2, 0xdf23d125, 0xb0103444, 0x18e73f7e, 0x1ab47ff6, 0xfca2653c, 0x49b510f4, 0x70fa6974, 0xb4cb97d4, + 0x0cc4e6f8, 0x8a109e8b, 0xff8aff01, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02cbffff, 0x00000000, 0x00000000}, + {0x1f78e5c0, 0x46e23bec, 0x51b7943c, 0xc6e4d106, 0x491f720f, 0xa0f95f77, 0x61d8a747, 0x404ff820, 0x6abfac8c, + 0x6915035e, 0x1da02d03, 0xfee00535, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02cdffff, 0x00000000, 0x00000000}, + {0x4e9fbdbf, 0x33a966b2, 0x235ef434, 0x8bedbfd2, 0x3193ac29, 0x6443bbe2, 0x7af15129, 0x29c860bf, 0x8d550a7f, + 0x8ba02584, 0xc8f4cc66, 0xffe345ae, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02cfffff, 0x00000000, 0x00000000}, + {0x7dc695bd, 0x9b67d178, 0xc506542b, 0x39eb5159, 0x5ffe9e43, 0x089ab61d, 0x9314e77c, 0xf91def6b, 0x43491f36, + 0xe7f041ea, 0x5c845ade, 0xff384be2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02d1ffff, 0x00000000, 0x00000000}, + {0xaced6dbb, 0x03263c3e, 0x66adb423, 0xe7e8e2e1, 0x8e69905c, 0xacf1b058, 0xab387dce, 0xc8737e17, 0xf93d33ee, + 0x44405e4f, 0xf013e957, 0xfe8d5215, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02d3ffff, 0x00000000, 0x00000000}, + {0xdc1445ba, 0xefed6704, 0x3855141a, 0xacf1d1ad, 0x76ddca76, 0x703c0cc3, 0xc45127b0, 0xb1ebe6b6, 0x1bd291e1, + 0x66cb8076, 0x9b6888ba, 0xff90928f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02d5ffff, 0x00000000, 0x00000000}, + {0x0b3b1db8, 0x57abd1cb, 0xd9fc7412, 0x5aef6334, 0xa548bc90, 0x149306fe, 0xdc74be03, 0x81417562, 0xd1c6a699, + 0xc31b9cdb, 0x2ef81732, 0xfee598c3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02d7ffff, 0x00000000, 0x00000000}, + {0x3a61f5b7, 0x4472fc91, 0xaba3d40a, 0x1ff85200, 0x8dbcf6aa, 0xd7dd6369, 0xf58d67e4, 0x6ab9de01, 0xf45c048c, + 0xe5a6bf01, 0xda4cb695, 0xffe8d93c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02d9ffff, 0x00000000, 0x00000000}, + {0x6988cdb5, 0xac316757, 0x4d4b3401, 0xcdf5e388, 0xbc27e8c3, 0x7c345da4, 0x0db0fe37, 0x3a0f6cae, 0xaa501944, + 0x41f6db67, 0x6ddc450e, 0xff3ddf70, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02dbffff, 0x00000000, 0x00000000}, + {0x98afa5b3, 0x13efd21d, 0xeef293f9, 0x7bf3750f, 0xea92dadd, 0x208b57df, 0x25d4948a, 0x0964fb5a, 0x60442dfc, + 0x9e46f7cd, 0x016bd386, 0xfe92e5a4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02ddffff, 0x00000000, 0x00000000}, + {0xc7d67db2, 0x00b6fce3, 0xc099f3f1, 0x40fc63db, 0xd30714f7, 0xe3d5b44a, 0x3eed3e6b, 0xf2dd63f9, 0x82d98bee, + 0xc0d219f3, 0xacc072e9, 0xff96261d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02dfffff, 0x00000000, 0x00000000}, + {0xf6fd55b0, 0x687567a9, 0x624153e8, 0xeef9f563, 0x01720710, 0x882cae86, 0x5710d4be, 0xc232f2a5, 0x38cda0a6, + 0x1d223659, 0x40500162, 0xfeeb2c51, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02e1ffff, 0x00000000, 0x00000000}, + {0x26242daf, 0x553c9270, 0x33e8b3e0, 0xb402e42f, 0xe9e6412a, 0x4b770af0, 0x70297ea0, 0xabab5b44, 0x5b62fe99, + 0x3fad587f, 0xeba4a0c5, 0xffee6cca, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02e3ffff, 0x00000000, 0x00000000}, + {0x554b05ad, 0xbcfafd36, 0xd59013d7, 0x620075b6, 0x18513344, 0xefce052c, 0x884d14f2, 0x7b00e9f0, 0x11571351, + 0x9bfd74e5, 0x7f342f3d, 0xff4372fe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02e5ffff, 0x00000000, 0x00000000}, + {0x8471ddab, 0x24b967fc, 0x773773cf, 0x0ffe073e, 0x46bc255e, 0x9424ff67, 0xa070ab45, 0x4a56789c, 0xc74b2809, + 0xf84d914a, 0x12c3bdb5, 0xfe987932, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02e7ffff, 0x00000000, 0x00000000}, + {0xb398b5aa, 0x118092c2, 0x48ded3c7, 0xd506f60a, 0x2f305f77, 0x576f5bd2, 0xb9895527, 0x33cee13b, 0xe9e085fc, + 0x1ad8b370, 0xbe185d19, 0xff9bb9ab, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02e9ffff, 0x00000000, 0x00000000}, + {0xe2bf8da8, 0x793efd88, 0xea8633be, 0x83048791, 0x5d9b5191, 0xfbc6560d, 0xd1aceb79, 0x03246fe7, 0x9fd49ab4, + 0x7728cfd6, 0x51a7eb91, 0xfef0bfdf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02ebffff, 0x00000000, 0x00000000}, + {0x11e665a7, 0x6606284f, 0xbc2d93b6, 0x480d765d, 0x460f8bab, 0xbf10b278, 0xeac5955b, 0xec9cd886, 0xc269f8a6, + 0x99b3f1fc, 0xfcfc8af4, 0xfff40058, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02edffff, 0x00000000, 0x00000000}, + {0x410d3da5, 0xcdc49315, 0x5dd4f3ad, 0xf60b07e5, 0x747a7dc4, 0x6367acb3, 0x02e92bae, 0xbbf26733, 0x785e0d5e, + 0xf6040e62, 0x908c196c, 0xff49068c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02efffff, 0x00000000, 0x00000000}, + {0x703415a3, 0x3582fddb, 0xff7c53a5, 0xa408996c, 0xa2e56fde, 0x07bea6ee, 0x1b0cc201, 0x8b47f5df, 0x2e522216, + 0x52542ac8, 0x241ba7e5, 0xfe9e0cc0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02f1ffff, 0x00000000, 0x00000000}, + {0x9f5aeda2, 0x224a28a1, 0xd123b39d, 0x69118838, 0x8b59a9f8, 0xcb090359, 0x34256be2, 0x74c05e7e, 0x50e78009, + 0x74df4cee, 0xcf704748, 0xffa14d39, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02f3ffff, 0x00000000, 0x00000000}, + {0xce81c5a0, 0x8a089367, 0x72cb1394, 0x170f19c0, 0xb9c49c12, 0x6f5ffd94, 0x4c490235, 0x4415ed2a, 0x06db94c1, + 0xd12f6954, 0x62ffd5c0, 0xfef6536d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02f5ffff, 0x00000000, 0x00000000}, + {0xfda89d9f, 0x76cfbe2d, 0x4472738c, 0xdc18088c, 0xa238d62b, 0x32aa59ff, 0x6561ac17, 0x2d8e55c9, 0x2970f2b4, + 0xf3ba8b7a, 0x0e547523, 0xfff993e7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02f7ffff, 0x00000000, 0x00000000}, + {0x2ccf759d, 0xde8e28f4, 0xe619d383, 0x8a159a13, 0xd0a3c845, 0xd701543a, 0x7d854269, 0xfce3e475, 0xdf65076b, + 0x500aa7df, 0xa1e4039c, 0xff4e9a1a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02f9ffff, 0x00000000, 0x00000000}, + {0x5bf64d9b, 0x464c93ba, 0x87c1337b, 0x38132b9b, 0xff0eba5f, 0x7b584e75, 0x95a8d8bc, 0xcc397321, 0x95591c23, + 0xac5ac445, 0x35739214, 0xfea3a04e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02fbffff, 0x00000000, 0x00000000}, + {0x8b1d259a, 0x3313be80, 0x59689373, 0xfd1c1a67, 0xe782f478, 0x3ea2aae0, 0xaec1829e, 0xb5b1dbc0, 0xb7ee7a16, + 0xcee5e66b, 0xe0c83177, 0xffa6e0c7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02fdffff, 0x00000000, 0x00000000}, + {0xba43fd98, 0x9ad22946, 0xfb0ff36a, 0xab19abee, 0x15ede692, 0xe2f9a51c, 0xc6e518f0, 0x85076a6c, 0x6de28ece, + 0x2b3602d1, 0x7457bff0, 0xfefbe6fb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02ffffff, 0x00000000, 0x00000000}, + {0xe96ad597, 0x8799540c, 0xccb75362, 0x70229aba, 0xfe6220ac, 0xa6440186, 0xdffdc2d2, 0x6e7fd30b, 0x9077ecc1, + 0x4dc124f7, 0x1fac5f53, 0xffff2775, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0301ffff, 0x00000000, 0x00000000}, + {0x1891ad95, 0xef57bed3, 0x6e5eb359, 0x1e202c42, 0x2ccd12c6, 0x4a9afbc2, 0xf8215925, 0x3dd561b7, 0x466c0179, + 0xaa11415d, 0xb33bedcb, 0xff542da8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0303ffff, 0x00000000, 0x00000000}, + {0x47b88593, 0x57162999, 0x10061351, 0xcc1dbdca, 0x5b3804df, 0xeef1f5fd, 0x1044ef77, 0x0d2af064, 0xfc601631, + 0x06615dc2, 0x46cb7c44, 0xfea933dc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0305ffff, 0x00000000, 0x00000000}, + {0x76df5d92, 0x43dd545f, 0xe1ad7349, 0x9126ac95, 0x43ac3ef9, 0xb23c5268, 0x295d9959, 0xf6a35903, 0x1ef57423, + 0x28ec7fe9, 0xf2201ba7, 0xffac7455, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0307ffff, 0x00000000, 0x00000000}, + {0xa6063590, 0xab9bbf25, 0x8354d340, 0x3f243e1d, 0x72173113, 0x56934ca3, 0x41812fac, 0xc5f8e7af, 0xd4e988db, + 0x853c9c4e, 0x85afaa1f, 0xff017a89, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0309ffff, 0x00000000, 0x00000000}, + {0xd52d0d8e, 0x135a29eb, 0x24fc3338, 0xed21cfa5, 0xa082232c, 0xfaea46de, 0x59a4c5fe, 0x954e765b, 0x8add9d93, + 0xe18cb8b4, 0x193f3897, 0xfe5680bd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x030bffff, 0x00000000, 0x00000000}, + {0x0453e58d, 0x002154b2, 0xf6a39330, 0xb22abe70, 0x88f65d46, 0xbe34a349, 0x72bd6fe0, 0x7ec6defa, 0xad72fb86, + 0x0417dada, 0xc493d7fb, 0xff59c136, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x030dffff, 0x00000000, 0x00000000}, + {0x337abd8b, 0x67dfbf78, 0x984af327, 0x60284ff8, 0xb7614f60, 0x628b9d84, 0x8ae10633, 0x4e1c6da6, 0x6367103e, + 0x6067f740, 0x58236673, 0xfeaec76a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x030fffff, 0x00000000, 0x00000000}, + {0x62a1958a, 0x54a6ea3e, 0x69f2531f, 0x25313ec4, 0x9fd5897a, 0x25d5f9ef, 0xa3f9b015, 0x3794d645, 0x85fc6e31, + 0x82f31966, 0x037805d6, 0xffb207e4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0311ffff, 0x00000000, 0x00000000}, + {0x91c86d88, 0xbc655504, 0x0b99b316, 0xd32ed04c, 0xce407b93, 0xca2cf42a, 0xbc1d4667, 0x06ea64f1, 0x3bf082e9, + 0xdf4335cc, 0x9707944e, 0xff070e17, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0313ffff, 0x00000000, 0x00000000}, + {0xc0ef4586, 0x2423bfca, 0xad41130e, 0x812c61d3, 0xfcab6dad, 0x6e83ee65, 0xd440dcba, 0xd63ff39d, 0xf1e497a0, + 0x3b935231, 0x2a9722c7, 0xfe5c144b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0315ffff, 0x00000000, 0x00000000}, + {0xf0161d85, 0x10eaea90, 0x7ee87306, 0x4635509f, 0xe51fa7c7, 0x31ce4ad0, 0xed59869c, 0xbfb85c3c, 0x1479f593, + 0x5e1e7458, 0xd5ebc22a, 0xff5f54c4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0317ffff, 0x00000000, 0x00000000}, + {0x1f3cf583, 0x78a95557, 0x208fd2fd, 0xf432e227, 0x138a99e0, 0xd625450c, 0x057d1cee, 0x8f0deae9, 0xca6e0a4b, + 0xba6e90bd, 0x697b50a2, 0xfeb45af8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0319ffff, 0x00000000, 0x00000000}, + {0x4e63cd82, 0x6570801d, 0xf23732f5, 0xb93bd0f2, 0xfbfed3fa, 0x996fa176, 0x1e95c6d0, 0x78865388, 0xed03683e, + 0xdcf9b2e3, 0x14cff005, 0xffb79b72, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x031bffff, 0x00000000, 0x00000000}, + {0x7d8aa580, 0xcd2eeae3, 0x93de92ec, 0x6739627a, 0x2a69c614, 0x3dc69bb2, 0x36b95d23, 0x47dbe234, 0xa2f77cf6, + 0x3949cf49, 0xa85f7e7e, 0xff0ca1a5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x031dffff, 0x00000000, 0x00000000}, + {0xacb17d7e, 0x34ed55a9, 0x3585f2e4, 0x1536f402, 0x58d4b82e, 0xe21d95ed, 0x4edcf375, 0x173170e0, 0x58eb91ae, + 0x9599ebaf, 0x3bef0cf6, 0xfe61a7d9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x031fffff, 0x00000000, 0x00000000}, + {0xdbd8557d, 0x21b4806f, 0x072d52dc, 0xda3fe2ce, 0x4148f247, 0xa567f258, 0x67f59d57, 0x00a9d97f, 0x7b80efa1, + 0xb8250dd5, 0xe743ac59, 0xff64e852, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0321ffff, 0x00000000, 0x00000000}, + {0x0aff2d7b, 0x8972eb36, 0xa8d4b2d3, 0x883d7455, 0x6fb3e461, 0x49beec93, 0x801933aa, 0xcfff682b, 0x31750458, + 0x14752a3b, 0x7ad33ad2, 0xfeb9ee86, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0323ffff, 0x00000000, 0x00000000}, + {0x3a26057a, 0x763a15fc, 0x7a7c12cb, 0x4d466321, 0x58281e7b, 0x0d0948fe, 0x9931dd8c, 0xb977d0ca, 0x540a624b, + 0x37004c61, 0x2627da35, 0xffbd2f00, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0325ffff, 0x00000000, 0x00000000}, + {0x694cdd78, 0xddf880c2, 0x1c2372c2, 0xfb43f4a9, 0x86931094, 0xb1604339, 0xb15573de, 0x88cd5f76, 0x09fe7703, + 0x935068c7, 0xb9b768ad, 0xff123533, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0327ffff, 0x00000000, 0x00000000}, + {0x9873b576, 0x45b6eb88, 0xbdcad2ba, 0xa9418630, 0xb4fe02ae, 0x55b73d74, 0xc9790a31, 0x5822ee22, 0xbff28bbb, + 0xefa0852c, 0x4d46f725, 0xfe673b67, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0329ffff, 0x00000000, 0x00000000}, + {0xc79a8d75, 0x327e164e, 0x8f7232b2, 0x6e4a74fc, 0x9d723cc8, 0x190199df, 0xe291b413, 0x419b56c1, 0xe287e9ae, + 0x122ba752, 0xf89b9689, 0xff6a7be0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x032bffff, 0x00000000, 0x00000000}, + {0xf6c16573, 0x9a3c8114, 0x311992a9, 0x1c480684, 0xcbdd2ee2, 0xbd58941a, 0xfab54a65, 0x10f0e56d, 0x987bfe66, + 0x6e7bc3b8, 0x8c2b2501, 0xfebf8214, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x032dffff, 0x00000000, 0x00000000}, + {0x25e83d72, 0x8703abdb, 0x02c0f2a1, 0xe150f550, 0xb45168fb, 0x80a2f085, 0x13cdf447, 0xfa694e0d, 0xbb115c58, + 0x9106e5de, 0x377fc464, 0xffc2c28e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x032fffff, 0x00000000, 0x00000000}, + {0x550f1570, 0xeec216a1, 0xa4685298, 0x8f4e86d7, 0xe2bc5b15, 0x24f9eac0, 0x2bf18a9a, 0xc9bedcb9, 0x71057110, + 0xed570244, 0xcb0f52dc, 0xff17c8c1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0331ffff, 0x00000000, 0x00000000}, + {0x8435ed6e, 0x56808167, 0x460fb290, 0x3d4c185f, 0x11274d2f, 0xc950e4fc, 0x441520ec, 0x99146b65, 0x26f985c8, + 0x49a71eaa, 0x5e9ee155, 0xfe6ccef5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0333ffff, 0x00000000, 0x00000000}, + {0xb35cc56d, 0x4347ac2d, 0x17b71288, 0x0255072b, 0xf99b8749, 0x8c9b4166, 0x5d2dcace, 0x828cd404, 0x498ee3bb, + 0x6c3240d0, 0x09f380b8, 0xff700f6f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0335ffff, 0x00000000, 0x00000000}, + {0xe2839d6b, 0xab0616f3, 0xb95e727f, 0xb05298b2, 0x28067962, 0x30f23ba2, 0x75516121, 0x51e262b0, 0xff82f873, + 0xc8825d35, 0x9d830f30, 0xfec515a2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0337ffff, 0x00000000, 0x00000000}, + {0x11aa756a, 0x97cd41ba, 0x8b05d277, 0x755b877e, 0x107ab37c, 0xf43c980d, 0x8e6a0b02, 0x3b5acb4f, 0x22185666, + 0xeb0d7f5c, 0x48d7ae93, 0xffc8561c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0339ffff, 0x00000000, 0x00000000}, + {0x40d14d68, 0xff8bac80, 0x2cad326e, 0x23591906, 0x3ee5a596, 0x98939248, 0xa68da155, 0x0ab059fb, 0xd80c6b1e, + 0x475d9bc1, 0xdc673d0c, 0xff1d5c4f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x033bffff, 0x00000000, 0x00000000}, + {0x6ff82566, 0x674a1746, 0xce549266, 0xd156aa8d, 0x6d5097af, 0x3cea8c83, 0xbeb137a8, 0xda05e8a7, 0x8e007fd5, + 0xa3adb827, 0x6ff6cb84, 0xfe726283, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x033dffff, 0x00000000, 0x00000000}, + {0x9f1efd65, 0x5411420c, 0x9ffbf25e, 0x965f9959, 0x55c4d1c9, 0x0034e8ee, 0xd7c9e18a, 0xc37e5146, 0xb095ddc8, + 0xc638da4d, 0x1b4b6ae7, 0xff75a2fd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x033fffff, 0x00000000, 0x00000000}, + {0xce45d563, 0xbbcfacd2, 0x41a35255, 0x445d2ae1, 0x842fc3e3, 0xa48be329, 0xefed77dc, 0x92d3dff2, 0x6689f280, + 0x2288f6b3, 0xaedaf960, 0xfecaa930, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0341ffff, 0x00000000, 0x00000000}, + {0xfd6cad62, 0xa896d798, 0x134ab24d, 0x096619ad, 0x6ca3fdfd, 0x67d63f94, 0x090621be, 0x7c4c4892, 0x891f5073, + 0x451418d9, 0x5a2f98c3, 0xffcde9aa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0343ffff, 0x00000000, 0x00000000}, + {0x2c938560, 0x1055425f, 0xb4f21245, 0xb763ab34, 0x9b0ef016, 0x0c2d39cf, 0x2129b811, 0x4ba1d73e, 0x3f13652b, + 0xa164353f, 0xedbf273b, 0xff22efdd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0345ffff, 0x00000000, 0x00000000}, + {0x5bba5d5e, 0x7813ad25, 0x5699723c, 0x65613cbc, 0xc979e230, 0xb084340a, 0x394d4e63, 0x1af765ea, 0xf50779e3, + 0xfdb451a4, 0x814eb5b3, 0xfe77f611, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0347ffff, 0x00000000, 0x00000000}, + {0x8ae1355d, 0x64dad7eb, 0x2840d234, 0x2a6a2b88, 0xb1ee1c4a, 0x73ce9075, 0x5265f845, 0x046fce89, 0x179cd7d6, + 0x203f73cb, 0x2ca35517, 0xff7b368b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0349ffff, 0x00000000, 0x00000000}, + {0xba080d5b, 0xcc9942b1, 0xc9e8322b, 0xd867bd0f, 0xe0590e63, 0x18258ab0, 0x6a898e98, 0xd3c55d35, 0xcd90ec8d, + 0x7c8f9030, 0xc032e38f, 0xfed03cbe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x034bffff, 0x00000000, 0x00000000}, + {0xe92ee55a, 0xb9606d77, 0x9b8f9223, 0x9d70abdb, 0xc8cd487d, 0xdb6fe71b, 0x83a23879, 0xbd3dc5d4, 0xf0264a80, + 0x9f1ab256, 0x6b8782f2, 0xffd37d38, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x034dffff, 0x00000000, 0x00000000}, + {0x1855bd58, 0x211ed83e, 0x3d36f21b, 0x4b6e3d63, 0xf7383a97, 0x7fc6e156, 0x9bc5cecc, 0x8c935480, 0xa61a5f38, + 0xfb6acebc, 0xff17116a, 0xff28836b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x034fffff, 0x00000000, 0x00000000}, + {0x477c9556, 0x88dd4304, 0xdede5212, 0xf96bceea, 0x25a32cb0, 0x241ddb92, 0xb3e9651f, 0x5be8e32c, 0x5c0e73f0, + 0x57baeb22, 0x92a69fe3, 0xfe7d899f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0351ffff, 0x00000000, 0x00000000}, + {0x76a36d55, 0x75a46dca, 0xb085b20a, 0xbe74bdb6, 0x0e1766ca, 0xe76837fd, 0xcd020f00, 0x45614bcb, 0x7ea3d1e3, + 0x7a460d48, 0x3dfb3f46, 0xff80ca19, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0353ffff, 0x00000000, 0x00000000}, + {0xa5ca4553, 0xdd62d890, 0x522d1201, 0x6c724f3e, 0x3c8258e4, 0x8bbf3238, 0xe525a553, 0x14b6da77, 0x3497e69b, + 0xd69629ae, 0xd18acdbe, 0xfed5d04c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0355ffff, 0x00000000, 0x00000000}, + {0xd4f11d52, 0xca2a0356, 0x23d471f9, 0x317b3e0a, 0x24f692fe, 0x4f098ea3, 0xfe3e4f35, 0xfe2f4316, 0x572d448d, + 0xf9214bd4, 0x7cdf6d21, 0xffd910c6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0357ffff, 0x00000000, 0x00000000}, + {0x0417f550, 0x31e86e1d, 0xc57bd1f1, 0xdf78cf91, 0x53618517, 0xf36088de, 0x1661e587, 0xcd84d1c3, 0x0d215945, + 0x5571683a, 0x106efb9a, 0xff2e16fa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0359ffff, 0x00000000, 0x00000000}, + {0x333ecd4e, 0x99a6d8e3, 0x672331e8, 0x8d766119, 0x81cc7731, 0x97b78319, 0x2e857bda, 0x9cda606f, 0xc3156dfd, + 0xb1c1849f, 0xa3fe8a12, 0xfe831d2d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x035bffff, 0x00000000, 0x00000000}, + {0x6265a54d, 0x866e03a9, 0x38ca91e0, 0x527f4fe5, 0x6a40b14b, 0x5b01df84, 0x479e25bc, 0x8652c90e, 0xe5aacbf0, + 0xd44ca6c5, 0x4f532975, 0xff865da7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x035dffff, 0x00000000, 0x00000000}, + {0x918c7d4b, 0xee2c6e6f, 0xda71f1d7, 0x007ce16c, 0x98aba365, 0xff58d9bf, 0x5fc1bc0e, 0x55a857ba, 0x9b9ee0a8, + 0x309cc32b, 0xe2e2b7ee, 0xfedb63da, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x035fffff, 0x00000000, 0x00000000}, + {0xc0b3554a, 0xdaf39935, 0xac1951cf, 0xc585d038, 0x811fdd7e, 0xc2a3362a, 0x78da65f0, 0x3f20c059, 0xbe343e9b, + 0x5327e551, 0x8e375751, 0xffdea454, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0361ffff, 0x00000000, 0x00000000}, + {0xefda2d48, 0x42b203fb, 0x4dc0b1c7, 0x738361c0, 0xaf8acf98, 0x66fa3065, 0x90fdfc43, 0x0e764f05, 0x74285353, + 0xaf7801b7, 0x21c6e5c9, 0xff33aa88, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0363ffff, 0x00000000, 0x00000000}, + {0x1f010546, 0xaa706ec2, 0xef6811be, 0x2180f347, 0xddf5c1b2, 0x0b512aa0, 0xa9219296, 0xddcbddb1, 0x2a1c680a, + 0x0bc81e1d, 0xb5567442, 0xfe88b0bb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0365ffff, 0x00000000, 0x00000000}, + {0x4e27dd45, 0x97379988, 0xc10f71b6, 0xe689e213, 0xc669fbcb, 0xce9b870b, 0xc23a3c77, 0xc7444650, 0x4cb1c5fd, + 0x2e534043, 0x60ab13a5, 0xff8bf135, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0367ffff, 0x00000000, 0x00000000}, + {0x7d4eb543, 0xfef6044e, 0x62b6d1ad, 0x9487739b, 0xf4d4ede5, 0x72f28146, 0xda5dd2ca, 0x9699d4fc, 0x02a5dab5, + 0x8aa35ca9, 0xf43aa21d, 0xfee0f768, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0369ffff, 0x00000000, 0x00000000}, + {0xac758d42, 0xebbd2f14, 0x345e31a5, 0x59906267, 0xdd4927ff, 0x363cddb1, 0xf3767cac, 0x80123d9b, 0x253b38a8, + 0xad2e7ecf, 0x9f8f4180, 0xffe437e2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x036bffff, 0x00000000, 0x00000000}, + {0xdb9c6540, 0x537b99da, 0xd605919d, 0x078df3ee, 0x0bb41a19, 0xda93d7ed, 0x0b9a12fe, 0x4f67cc48, 0xdb2f4d60, + 0x097e9b34, 0x331ecff9, 0xff393e16, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x036dffff, 0x00000000, 0x00000000}, + {0x0ac33d3e, 0xbb3a04a1, 0x77acf194, 0xb58b8576, 0x3a1f0c32, 0x7eead228, 0x23bda951, 0x1ebd5af4, 0x91236218, + 0x65ceb79a, 0xc6ae5e71, 0xfe8e4449, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x036fffff, 0x00000000, 0x00000000}, + {0x39ea153d, 0xa8012f67, 0x4954518c, 0x7a947442, 0x2293464c, 0x42352e93, 0x3cd65333, 0x0835c393, 0xb3b8c00b, + 0x8859d9c0, 0x7202fdd4, 0xff9184c3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0371ffff, 0x00000000, 0x00000000}, + {0x6910ed3b, 0x0fbf9a2d, 0xeafbb184, 0x289205c9, 0x50fe3866, 0xe68c28ce, 0x54f9e985, 0xd78b523f, 0x69acd4c2, + 0xe4a9f626, 0x05928c4c, 0xfee68af7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0373ffff, 0x00000000, 0x00000000}, + {0x9837c53a, 0xfc86c4f3, 0xbca3117b, 0xed9af495, 0x3972727f, 0xa9d68539, 0x6e129367, 0xc103bade, 0x8c4232b5, + 0x0735184c, 0xb0e72bb0, 0xffe9cb70, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0375ffff, 0x00000000, 0x00000000}, + {0xc75e9d38, 0x64452fb9, 0x5e4a7173, 0x9b98861d, 0x67dd6499, 0x4e2d7f74, 0x863629ba, 0x9059498a, 0x4236476d, + 0x638534b2, 0x4476ba28, 0xff3ed1a4, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0377ffff, 0x00000000, 0x00000000}, + {0xf6857536, 0xcc039a7f, 0xfff1d16a, 0x499617a4, 0x964856b3, 0xf28479af, 0x9e59c00c, 0x5faed836, 0xf82a5c25, + 0xbfd55117, 0xd80648a0, 0xfe93d7d7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0379ffff, 0x00000000, 0x00000000}, + {0x25ac4d35, 0xb8cac546, 0xd1993162, 0x0e9f0670, 0x7ebc90cd, 0xb5ced61a, 0xb77269ee, 0x492740d5, 0x1abfba18, + 0xe260733e, 0x835ae803, 0xff971851, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x037bffff, 0x00000000, 0x00000000}, + {0x54d32533, 0x2089300c, 0x7340915a, 0xbc9c97f8, 0xad2782e6, 0x5a25d055, 0xcf960041, 0x187ccf81, 0xd0b3ced0, + 0x3eb08fa3, 0x16ea767c, 0xfeec1e85, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x037dffff, 0x00000000, 0x00000000}, + {0x83f9fd32, 0x0d505ad2, 0x44e7f152, 0x81a586c4, 0x959bbd00, 0x1d702cc0, 0xe8aeaa23, 0x01f53820, 0xf3492cc3, + 0x613bb1c9, 0xc23f15df, 0xffef5efe, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x037fffff, 0x00000000, 0x00000000}, + {0xb320d530, 0x750ec598, 0xe68f5149, 0x2fa3184b, 0xc406af1a, 0xc1c726fb, 0x00d24075, 0xd14ac6cd, 0xa93d417a, + 0xbd8bce2f, 0x55cea457, 0xff446532, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0381ffff, 0x00000000, 0x00000000}, + {0xe247ad2e, 0xdccd305e, 0x8836b140, 0xdda0a9d3, 0xf271a133, 0x661e2136, 0x18f5d6c8, 0xa0a05579, 0x5f315632, + 0x19dbea95, 0xe95e32d0, 0xfe996b65, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0383ffff, 0x00000000, 0x00000000}, + {0x116e852d, 0xc9945b25, 0x59de1138, 0xa2a9989f, 0xdae5db4d, 0x29687da1, 0x320e80aa, 0x8a18be18, 0x81c6b425, + 0x3c670cbb, 0x94b2d233, 0xff9cabdf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0385ffff, 0x00000000, 0x00000000}, + {0x40955d2b, 0x3152c5eb, 0xfb857130, 0x50a72a26, 0x0950cd67, 0xcdbf77dd, 0x4a3216fc, 0x596e4cc4, 0x37bac8dd, + 0x98b72921, 0x284260ab, 0xfef1b213, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0387ffff, 0x00000000, 0x00000000}, + {0x6fbc352a, 0x1e19f0b1, 0xcd2cd128, 0x15b018f2, 0xf1c50781, 0x9109d447, 0x634ac0de, 0x42e6b563, 0x5a5026d0, + 0xbb424b47, 0xd397000e, 0xfff4f28c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0389ffff, 0x00000000, 0x00000000}, + {0x9ee30d28, 0x85d85b77, 0x6ed4311f, 0xc3adaa7a, 0x202ff99a, 0x3560ce83, 0x7b6e5731, 0x123c440f, 0x10443b88, + 0x179267ad, 0x67268e87, 0xff49f8c0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x038bffff, 0x00000000, 0x00000000}, + {0xce09e526, 0xed96c63d, 0x107b9116, 0x71ab3c02, 0x4e9aebb4, 0xd9b7c8be, 0x9391ed83, 0xe191d2bb, 0xc638503f, + 0x73e28412, 0xfab61cff, 0xfe9efef3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x038dffff, 0x00000000, 0x00000000}, + {0xfd30bd25, 0xda5df103, 0xe222f10e, 0x36b42acd, 0x370f25ce, 0x9d022529, 0xacaa9765, 0xcb0a3b5a, 0xe8cdae32, + 0x966da638, 0xa60abc62, 0xffa23f6d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x038fffff, 0x00000000, 0x00000000}, + {0x2c579523, 0x421c5bca, 0x83ca5106, 0xe4b1bc55, 0x657a17e7, 0x41591f64, 0xc4ce2db8, 0x9a5fca06, 0x9ec1c2ea, + 0xf2bdc29e, 0x399a4ada, 0xfef745a1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0391ffff, 0x00000000, 0x00000000}, + {0x5b7e6d22, 0x2ee38690, 0x5571b0fe, 0xa9baab21, 0x4dee5201, 0x04a37bcf, 0xdde6d79a, 0x83d832a5, 0xc15720dd, + 0x1548e4c4, 0xe4eeea3e, 0xfffa861a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0393ffff, 0x00000000, 0x00000000}, + {0x8aa54520, 0x96a1f156, 0xf71910f5, 0x57b83ca8, 0x7c59441b, 0xa8fa760a, 0xf60a6dec, 0x532dc151, 0x774b3595, + 0x7199012a, 0x787e78b6, 0xff4f8c4e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0395ffff, 0x00000000, 0x00000000}, + {0xb9cc1d1e, 0xfe605c1c, 0x98c070ec, 0x05b5ce30, 0xaac43635, 0x4d517045, 0x0e2e043f, 0x22834ffe, 0x2d3f4a4d, + 0xcde91d90, 0x0c0e072e, 0xfea49282, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0397ffff, 0x00000000, 0x00000000}, + {0xe8f2f51d, 0xeb2786e2, 0x6a67d0e4, 0xcabebcfc, 0x9338704e, 0x109bccb0, 0x2746ae21, 0x0bfbb89d, 0x4fd4a840, + 0xf0743fb6, 0xb762a691, 0xffa7d2fb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0399ffff, 0x00000000, 0x00000000}, + {0x1819cd1b, 0x52e5f1a9, 0x0c0f30dc, 0x78bc4e84, 0xc1a36268, 0xb4f2c6eb, 0x3f6a4473, 0xdb514749, 0x05c8bcf7, + 0x4cc45c1c, 0x4af2350a, 0xfefcd92f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x039bffff, 0x00000000, 0x00000000}, + {0x4740a519, 0xbaa45c6f, 0xadb690d3, 0x26b9e00b, 0xf00e5482, 0x5949c126, 0x578ddac6, 0xaaa6d5f5, 0xbbbcd1af, + 0xa9147881, 0xde81c382, 0xfe51df62, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x039dffff, 0x00000000, 0x00000000}, + {0x76677d18, 0xa76b8735, 0x7f5df0cb, 0xebc2ced7, 0xd8828e9b, 0x1c941d91, 0x70a684a8, 0x941f3e94, 0xde522fa2, + 0xcb9f9aa7, 0x89d662e5, 0xff551fdc, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x039fffff, 0x00000000, 0x00000000}, + {0xa58e5516, 0x0f29f1fb, 0x210550c3, 0x99c0605f, 0x06ed80b5, 0xc0eb17cd, 0x88ca1afa, 0x6374cd40, 0x9446445a, + 0x27efb70d, 0x1d65f15e, 0xfeaa2610, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03a1ffff, 0x00000000, 0x00000000}, + {0xd4b52d15, 0xfbf11cc1, 0xf2acb0ba, 0x5ec94f2a, 0xef61bacf, 0x84357437, 0xa1e2c4dc, 0x4ced35df, 0xb6dba24d, + 0x4a7ad933, 0xc8ba90c1, 0xffad6689, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03a3ffff, 0x00000000, 0x00000000}, + {0x03dc0513, 0x63af8788, 0x945410b2, 0x0cc6e0b2, 0x1dccace9, 0x288c6e73, 0xba065b2f, 0x1c42c48b, 0x6ccfb705, + 0xa6caf599, 0x5c4a1f39, 0xff026cbd, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03a5ffff, 0x00000000, 0x00000000}, + {0x3302dd11, 0xcb6df24e, 0x35fb70a9, 0xbac4723a, 0x4c379f02, 0xcce368ae, 0xd229f181, 0xeb985337, 0x22c3cbbc, + 0x031b11ff, 0xefd9adb2, 0xfe5772f0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03a7ffff, 0x00000000, 0x00000000}, + {0x6229b510, 0xb8351d14, 0x07a2d0a1, 0x7fcd6106, 0x34abd91c, 0x902dc519, 0xeb429b63, 0xd510bbd6, 0x455929af, + 0x25a63425, 0x9b2e4d15, 0xff5ab36a, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03a9ffff, 0x00000000, 0x00000000}, + {0x91508d0e, 0x1ff387da, 0xa94a3099, 0x2dcaf28d, 0x6316cb36, 0x3484bf54, 0x036631b6, 0xa4664a83, 0xfb4d3e67, + 0x81f6508a, 0x2ebddb8d, 0xfeafb99e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03abffff, 0x00000000, 0x00000000}, + {0xc077650d, 0x0cbab2a0, 0x7af19091, 0xf2d3e159, 0x4b8b054f, 0xf7cf1bbf, 0x1c7edb97, 0x8ddeb322, 0x1de29c5a, + 0xa48172b1, 0xda127af0, 0xffb2fa17, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03adffff, 0x00000000, 0x00000000}, + {0xef9e3d0b, 0x74791d66, 0x1c98f088, 0xa0d172e1, 0x79f5f769, 0x9c2615fa, 0x34a271ea, 0x5d3441ce, 0xd3d6b112, + 0x00d18f16, 0x6da20969, 0xff08004b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03afffff, 0x00000000, 0x00000000}, + {0x1ec51509, 0xdc37882d, 0xbe40507f, 0x4ecf0468, 0xa860e983, 0x407d1035, 0x4cc6083d, 0x2c89d07a, 0x89cac5ca, + 0x5d21ab7c, 0x013197e1, 0xfe5d067f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03b1ffff, 0x00000000, 0x00000000}, + {0x4debed08, 0xc8feb2f3, 0x8fe7b077, 0x13d7f334, 0x90d5239d, 0x03c76ca0, 0x65deb21f, 0x16023919, 0xac6023bd, + 0x7faccda2, 0xac863744, 0xff6046f8, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03b3ffff, 0x00000000, 0x00000000}, + {0x7d12c506, 0x30bd1db9, 0x318f106f, 0xc1d584bc, 0xbf4015b6, 0xa81e66db, 0x7e024871, 0xe557c7c5, 0x62543874, + 0xdbfcea08, 0x4015c5bc, 0xfeb54d2c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03b5ffff, 0x00000000, 0x00000000}, + {0xac399d05, 0x1d84487f, 0x03367067, 0x86de7388, 0xa7b44fd0, 0x6b68c346, 0x971af253, 0xced03064, 0x84e99667, + 0xfe880c2e, 0xeb6a651f, 0xffb88da5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03b7ffff, 0x00000000, 0x00000000}, + {0xdb607503, 0x8542b345, 0xa4ddd05e, 0x34dc050f, 0xd61f41ea, 0x0fbfbd81, 0xaf3e88a6, 0x9e25bf10, 0x3addab1f, + 0x5ad82894, 0x7ef9f398, 0xff0d93d9, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03b9ffff, 0x00000000, 0x00000000}, + {0x0a874d01, 0xed011e0c, 0x46853055, 0xe2d99697, 0x048a3403, 0xb416b7bd, 0xc7621ef8, 0x6d7b4dbc, 0xf0d1bfd7, + 0xb72844f9, 0x12898210, 0xfe629a0d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03bbffff, 0x00000000, 0x00000000}, + {0x39ae2500, 0xd9c848d2, 0x182c904d, 0xa7e28563, 0xecfe6e1d, 0x77611427, 0xe07ac8da, 0x56f3b65b, 0x13671dca, + 0xd9b36720, 0xbdde2173, 0xff65da86, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03bdffff, 0x00000000, 0x00000000}, + {0x68d4fcfe, 0x4186b398, 0xb9d3f045, 0x55e016ea, 0x1b696037, 0x1bb80e63, 0xf89e5f2d, 0x26494507, 0xc95b3282, + 0x36038385, 0x516dafec, 0xfebae0ba, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03bfffff, 0x00000000, 0x00000000}, + {0x97fbd4fd, 0x2e4dde5e, 0x8b7b503d, 0x1ae905b6, 0x03dd9a51, 0xdf026ace, 0x11b7090e, 0x0fc1ada7, 0xebf09075, + 0x588ea5ab, 0xfcc24f4f, 0xffbe2133, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03c1ffff, 0x00000000, 0x00000000}, + {0xc722acfb, 0x960c4924, 0x2d22b034, 0xc8e6973e, 0x32488c6a, 0x83596509, 0x29da9f61, 0xdf173c53, 0xa1e4a52c, + 0xb4dec211, 0x9051ddc7, 0xff132767, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03c3ffff, 0x00000000, 0x00000000}, + {0xf64984f9, 0xfdcab3ea, 0xceca102b, 0x76e428c5, 0x60b37e84, 0x27b05f44, 0x41fe35b4, 0xae6ccaff, 0x57d8b9e4, + 0x112ede77, 0x23e16c40, 0xfe682d9b, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03c5ffff, 0x00000000, 0x00000000}, + {0x25705cf8, 0xea91deb1, 0xa0717023, 0x3bed1791, 0x4927b89e, 0xeafabbaf, 0x5b16df95, 0x97e5339e, 0x7a6e17d7, + 0x33ba009d, 0xcf360ba3, 0xff6b6e14, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03c7ffff, 0x00000000, 0x00000000}, + {0x549734f6, 0x52504977, 0x4218d01b, 0xe9eaa919, 0x7792aab7, 0x8f51b5ea, 0x733a75e8, 0x673ac24a, 0x30622c8f, + 0x900a1d03, 0x62c59a1b, 0xfec07448, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03c9ffff, 0x00000000, 0x00000000}, + {0x83be0cf5, 0x3f17743d, 0x13c03013, 0xaef397e5, 0x6006e4d1, 0x529c1255, 0x8c531fca, 0x50b32ae9, 0x52f78a82, + 0xb2953f29, 0x0e1a397e, 0xffc3b4c2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03cbffff, 0x00000000, 0x00000000}, + {0xb2e4e4f3, 0xa6d5df03, 0xb567900a, 0x5cf1296c, 0x8e71d6eb, 0xf6f30c90, 0xa476b61c, 0x2008b995, 0x08eb9f3a, + 0x0ee55b8f, 0xa1a9c7f7, 0xff18baf5, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03cdffff, 0x00000000, 0x00000000}, + {0xe20bbcf1, 0x0e9449c9, 0x570ef002, 0x0aeebaf4, 0xbcdcc905, 0x9b4a06cb, 0xbc9a4c6f, 0xef5e4841, 0xbedfb3f1, + 0x6b3577f4, 0x3539566f, 0xfe6dc129, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03cfffff, 0x00000000, 0x00000000}, + {0x113294f0, 0xfb5b7490, 0x28b64ff9, 0xcff7a9c0, 0xa551031e, 0x5e946336, 0xd5b2f651, 0xd8d6b0e0, 0xe17511e4, + 0x8dc09a1a, 0xe08df5d2, 0xff7101a2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03d1ffff, 0x00000000, 0x00000000}, + {0x40596cee, 0x6319df56, 0xca5daff1, 0x7df53b47, 0xd3bbf538, 0x02eb5d71, 0xedd68ca4, 0xa82c3f8c, 0x9769269c, + 0xea10b680, 0x741d844a, 0xfec607d6, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03d3ffff, 0x00000000, 0x00000000}, + {0x6f8044ed, 0x4fe10a1c, 0x9c050fe9, 0x42fe2a13, 0xbc302f52, 0xc635b9dc, 0x06ef3685, 0x91a4a82c, 0xb9fe848f, + 0x0c9bd8a6, 0x1f7223ae, 0xffc94850, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03d5ffff, 0x00000000, 0x00000000}, + {0x9ea71ceb, 0xb79f74e2, 0x3dac6fe0, 0xf0fbbb9b, 0xea9b216b, 0x6a8cb417, 0x1f12ccd8, 0x60fa36d8, 0x6ff29947, + 0x68ebf50c, 0xb301b226, 0xff1e4e83, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03d7ffff, 0x00000000, 0x00000000}, + {0xcdcdf4e9, 0x1f5ddfa8, 0xdf53cfd8, 0x9ef94d22, 0x19061385, 0x0ee3ae53, 0x3736632b, 0x304fc584, 0x25e6adff, + 0xc53c1172, 0x4691409e, 0xfe7354b7, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03d9ffff, 0x00000000, 0x00000000}, + {0xfcf4cce8, 0x0c250a6e, 0xb0fb2fd0, 0x64023bee, 0x017a4d9f, 0xd22e0abe, 0x504f0d0c, 0x19c82e23, 0x487c0bf2, + 0xe7c73398, 0xf1e5e001, 0xff769530, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03dbffff, 0x00000000, 0x00000000}, + {0x2c1ba4e6, 0x73e37535, 0x52a28fc7, 0x11ffcd76, 0x2fe53fb9, 0x768504f9, 0x6872a35f, 0xe91dbccf, 0xfe7020a9, + 0x44174ffd, 0x85756e7a, 0xfecb9b64, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03ddffff, 0x00000000, 0x00000000}, + {0x5b427ce5, 0x60aa9ffb, 0x2449efbf, 0xd708bc42, 0x185979d2, 0x39cf6164, 0x818b4d41, 0xd296256e, 0x21057e9c, + 0x66a27224, 0x30ca0ddd, 0xffcedbde, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03dfffff, 0x00000000, 0x00000000}, + {0x8a6954e3, 0xc8690ac1, 0xc5f14fb6, 0x85064dc9, 0x46c46bec, 0xde265b9f, 0x99aee393, 0xa1ebb41a, 0xd6f99354, + 0xc2f28e89, 0xc4599c55, 0xff23e211, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03e1ffff, 0x00000000, 0x00000000}, + {0xb9902ce1, 0x30277587, 0x6798afae, 0x3303df51, 0x752f5e06, 0x827d55da, 0xb1d279e6, 0x714142c6, 0x8ceda80c, + 0x1f42aaef, 0x57e92ace, 0xfe78e845, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03e3ffff, 0x00000000, 0x00000000}, + {0xe8b704e0, 0x1ceea04d, 0x39400fa6, 0xf80cce1d, 0x5da3981f, 0x45c7b245, 0xcaeb23c8, 0x5ab9ab65, 0xaf8305ff, + 0x41cdcd15, 0x033dca31, 0xff7c28bf, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03e5ffff, 0x00000000, 0x00000000}, + {0x17dddcde, 0x84ad0b14, 0xdae76f9d, 0xa60a5fa4, 0x8c0e8a39, 0xea1eac80, 0xe30eba1a, 0x2a0f3a11, 0x65771ab7, + 0x9e1de97b, 0x96cd58a9, 0xfed12ef2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03e7ffff, 0x00000000, 0x00000000}, + {0x4704b4dd, 0x717435da, 0xac8ecf95, 0x6b134e70, 0x7482c453, 0xad6908eb, 0xfc2763fc, 0x1387a2b0, 0x880c78aa, + 0xc0a90ba1, 0x4221f80c, 0xffd46f6c, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03e9ffff, 0x00000000, 0x00000000}, + {0x762b8cdb, 0xd932a0a0, 0x4e362f8c, 0x1910dff8, 0xa2edb66d, 0x51c00326, 0x144afa4f, 0xe2dd315d, 0x3e008d61, + 0x1cf92807, 0xd5b18685, 0xff29759f, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03ebffff, 0x00000000, 0x00000000}, + {0xa55264d9, 0x40f10b66, 0xefdd8f84, 0xc70e717f, 0xd158a886, 0xf616fd61, 0x2c6e90a1, 0xb232c009, 0xf3f4a219, + 0x7949446c, 0x694114fd, 0xfe7e7bd3, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03edffff, 0x00000000, 0x00000000}, + {0xd4793cd8, 0x2db8362c, 0xc184ef7c, 0x8c17604b, 0xb9cce2a0, 0xb96159cc, 0x45873a83, 0x9bab28a8, 0x168a000c, + 0x9bd46693, 0x1495b460, 0xff81bc4d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03efffff, 0x00000000, 0x00000000}, + {0x03a014d6, 0x9576a0f3, 0x632c4f73, 0x3a14f1d3, 0xe837d4ba, 0x5db85407, 0x5daad0d6, 0x6b00b754, 0xcc7e14c4, + 0xf82482f8, 0xa82542d8, 0xfed6c280, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03f1ffff, 0x00000000, 0x00000000}, + {0x32c6ecd5, 0x823dcbb9, 0x34d3af6b, 0xff1de09f, 0xd0ac0ed3, 0x2102b072, 0x76c37ab8, 0x54791ff3, 0xef1372b7, + 0x1aafa51e, 0x5379e23c, 0xffda02fa, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03f3ffff, 0x00000000, 0x00000000}, + {0x61edc4d3, 0xe9fc367f, 0xd67b0f62, 0xad1b7226, 0xff1700ed, 0xc559aaad, 0x8ee7110a, 0x23ceae9f, 0xa507876f, + 0x76ffc184, 0xe70970b4, 0xff2f092d, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03f5ffff, 0x00000000, 0x00000000}, + {0x91149cd1, 0x51baa145, 0x78226f5a, 0x5b1903ae, 0x2d81f307, 0x69b0a4e9, 0xa70aa75d, 0xf3243d4b, 0x5afb9c26, + 0xd34fddea, 0x7a98ff2c, 0xfe840f61, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03f7ffff, 0x00000000, 0x00000000}, + {0xc03b74d0, 0x3e81cc0b, 0x49c9cf52, 0x2021f27a, 0x15f62d21, 0x2cfb0154, 0xc023513f, 0xdc9ca5ea, 0x7d90fa19, + 0xf5db0010, 0x25ed9e8f, 0xff874fdb, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03f9ffff, 0x00000000, 0x00000000}, + {0xef624cce, 0xa64036d1, 0xeb712f49, 0xce1f8401, 0x44611f3a, 0xd151fb8f, 0xd846e791, 0xabf23496, 0x33850ed1, + 0x522b1c76, 0xb97d2d08, 0xfedc560e, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03fbffff, 0x00000000, 0x00000000}, + {0x1e8924cd, 0x93076198, 0xbd188f41, 0x932872cd, 0x2cd55954, 0x949c57fa, 0xf15f9173, 0x956a9d35, 0x561a6cc4, + 0x74b63e9c, 0x64d1cc6b, 0xffdf9688, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03fdffff, 0x00000000, 0x00000000}}}; static constexpr storage<12> rou = {0xc563b9a1, 0x7eca603c, 0x06fe0bc3, 0x06df0a43, 0x0ddff8c6, 0xb44d994a, 0x4512a3d4, 0x40fbe05b, 0x8aeffc9b, 0x30f15248, 0x05198a80, 0x0036a92e}; diff --git a/icicle/include/icicle/fields/snark_fields/bls12_377_scalar.h b/icicle/include/icicle/fields/snark_fields/bls12_377_scalar.h index 54a56db694..c88b36df21 100644 --- a/icicle/include/icicle/fields/snark_fields/bls12_377_scalar.h +++ b/icicle/include/icicle/fields/snark_fields/bls12_377_scalar.h @@ -8,7 +8,110 @@ namespace bls12_377 { struct fp_config { static constexpr storage<8> modulus = {0x00000001, 0x0a118000, 0xd0000001, 0x59aa76fe, 0x5c37b001, 0x60b44d1e, 0x9a2ca556, 0x12ab655e}; + static constexpr unsigned reduced_digits_count = 3; + static constexpr storage_array reduced_digits = { + {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0xfffffff3, 0x7d1c7fff, 0x6ffffff2, 0x7257f50f, 0x512c0fee, 0x16d81575, 0x2bbb9a9d, 0x0d4bda32}, + {0xb861857b, 0x25d577ba, 0x8860591f, 0xcc2c27b5, 0xe5dc8593, 0xa7cc008f, 0xeff1c939, 0x011fdae7}}}; PARAMS(modulus) + MOD_SQR_SUBS() + static constexpr storage_array mod_subs = { + {{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x8a8f3cf5, 0xb74fa610, 0xa0cf3f4d, 0xcae6ff0a, 0xb09a1a14, 0x2ce95cfb, 0x7e1a5df8, 0xff430e54, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff, 0x00000000, 0x00000000}, + {0x151e79ea, 0x6e9f4c21, 0x419e7e9b, 0x95cdfe15, 0x61343429, 0x59d2b9f7, 0xfc34bbf0, 0xfe861ca8, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03ffffff, 0x00000000, 0x00000000}, + {0x9fadb6df, 0x25eef231, 0xe26dbde9, 0x60b4fd1f, 0x11ce4e3e, 0x86bc16f3, 0x7a4f19e8, 0xfdc92afd, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x05ffffff, 0x00000000, 0x00000000}, + {0x2a3cf3d4, 0xdd3e9842, 0x833cfd36, 0x2b9bfc2a, 0xc2686853, 0xb3a573ee, 0xf86977e0, 0xfd0c3951, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x07ffffff, 0x00000000, 0x00000000}, + {0xb4cc30c9, 0x948e3e52, 0x240c3c84, 0xf682fb35, 0x73028267, 0xe08ed0ea, 0x7683d5d8, 0xfc4f47a6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x09ffffff, 0x00000000, 0x00000000}, + {0x3f5b6dbe, 0x4bdde463, 0xc4db7bd2, 0xc169fa3f, 0x239c9c7c, 0x0d782de6, 0xf49e33d1, 0xfb9255fa, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0bffffff, 0x00000000, 0x00000000}, + {0xc9eaaab3, 0x032d8a73, 0x65aabb20, 0x8c50f94a, 0xd436b691, 0x3a618ae1, 0x72b891c9, 0xfad5644f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0dffffff, 0x00000000, 0x00000000}, + {0x5479e7a8, 0xba7d3084, 0x0679fa6d, 0x5737f855, 0x84d0d0a6, 0x674ae7dd, 0xf0d2efc1, 0xfa1872a3, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0fffffff, 0x00000000, 0x00000000}, + {0xdf09249d, 0x71ccd694, 0xa74939bb, 0x221ef75f, 0x356aeabb, 0x943444d9, 0x6eed4db9, 0xf95b80f8, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x11ffffff, 0x00000000, 0x00000000}, + {0x69986192, 0x291c7ca5, 0x48187909, 0xed05f66a, 0xe60504cf, 0xc11da1d4, 0xed07abb1, 0xf89e8f4c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x13ffffff, 0x00000000, 0x00000000}, + {0xf4279e87, 0xe06c22b5, 0xe8e7b856, 0xb7ecf574, 0x969f1ee4, 0xee06fed0, 0x6b2209a9, 0xf7e19da1, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x15ffffff, 0x00000000, 0x00000000}, + {0x7eb6db7c, 0x97bbc8c6, 0x89b6f7a4, 0x82d3f47f, 0x473938f9, 0x1af05bcc, 0xe93c67a2, 0xf724abf5, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x17ffffff, 0x00000000, 0x00000000}, + {0x09461871, 0x4f0b6ed7, 0x2a8636f2, 0x4dbaf38a, 0xf7d3530e, 0x47d9b8c7, 0x6756c59a, 0xf667ba4a, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x19ffffff, 0x00000000, 0x00000000}, + {0x93d55566, 0x065b14e7, 0xcb557640, 0x18a1f294, 0xa86d6d23, 0x74c315c3, 0xe5712392, 0xf5aac89e, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1bffffff, 0x00000000, 0x00000000}, + {0x1e64925b, 0xbdaabaf8, 0x6c24b58d, 0xe388f19f, 0x59078737, 0xa1ac72bf, 0x638b818a, 0xf4edd6f3, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1dffffff, 0x00000000, 0x00000000}, + {0xa8f3cf50, 0x74fa6108, 0x0cf3f4db, 0xae6ff0aa, 0x09a1a14c, 0xce95cfbb, 0xe1a5df82, 0xf430e547, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0x00000000, 0x00000000}, + {0x33830c45, 0x2c4a0719, 0xadc33429, 0x7956efb4, 0xba3bbb61, 0xfb7f2cb6, 0x5fc03d7a, 0xf373f39c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x21ffffff, 0x00000000, 0x00000000}, + {0xbe12493a, 0xe399ad29, 0x4e927376, 0x443deebf, 0x6ad5d576, 0x286889b2, 0xddda9b73, 0xf2b701f0, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x23ffffff, 0x00000000, 0x00000000}, + {0x48a1862f, 0x9ae9533a, 0xef61b2c4, 0x0f24edc9, 0x1b6fef8b, 0x5551e6ae, 0x5bf4f96b, 0xf1fa1045, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x25ffffff, 0x00000000, 0x00000000}, + {0xd330c324, 0x5238f94a, 0x9030f212, 0xda0becd4, 0xcc0a099f, 0x823b43a9, 0xda0f5763, 0xf13d1e99, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x27ffffff, 0x00000000, 0x00000000}, + {0x5dc00019, 0x09889f5b, 0x31003160, 0xa4f2ebdf, 0x7ca423b4, 0xaf24a0a5, 0x5829b55b, 0xf0802cee, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x29ffffff, 0x00000000, 0x00000000}, + {0xe84f3d0e, 0xc0d8456b, 0xd1cf70ad, 0x6fd9eae9, 0x2d3e3dc9, 0xdc0dfda1, 0xd6441353, 0xefc33b42, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2bffffff, 0x00000000, 0x00000000}, + {0x72de7a03, 0x7827eb7c, 0x729eaffb, 0x3ac0e9f4, 0xddd857de, 0x08f75a9c, 0x545e714c, 0xef064997, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2dffffff, 0x00000000, 0x00000000}, + {0xfd6db6f8, 0x2f77918c, 0x136def49, 0x05a7e8ff, 0x8e7271f3, 0x35e0b798, 0xd278cf44, 0xee4957eb, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2fffffff, 0x00000000, 0x00000000}, + {0x87fcf3ed, 0xe6c7379d, 0xb43d2e96, 0xd08ee809, 0x3f0c8c07, 0x62ca1494, 0x50932d3c, 0xed8c6640, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x31ffffff, 0x00000000, 0x00000000}, + {0x128c30e3, 0xa8285dae, 0x250c6de5, 0xf5205e13, 0x4bde561d, 0xf067beae, 0x68da308a, 0xff7ad9f3, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x33ffffff, 0x00000000, 0x00000000}, + {0x9d1b6dd8, 0x5f7803be, 0xc5dbad33, 0xc0075d1d, 0xfc787032, 0x1d511ba9, 0xe6f48e83, 0xfebde847, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x35ffffff, 0x00000000, 0x00000000}, + {0x27aaaacd, 0x16c7a9cf, 0x66aaec81, 0x8aee5c28, 0xad128a47, 0x4a3a78a5, 0x650eec7b, 0xfe00f69c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x37ffffff, 0x00000000, 0x00000000}, + {0xb239e7c2, 0xce174fdf, 0x077a2bce, 0x55d55b33, 0x5daca45c, 0x7723d5a1, 0xe3294a73, 0xfd4404f0, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x39ffffff, 0x00000000, 0x00000000}, + {0x3cc924b7, 0x8566f5f0, 0xa8496b1c, 0x20bc5a3d, 0x0e46be71, 0xa40d329d, 0x6143a86b, 0xfc871345, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3bffffff, 0x00000000, 0x00000000}, + {0xc75861ac, 0x3cb69c00, 0x4918aa6a, 0xeba35948, 0xbee0d885, 0xd0f68f98, 0xdf5e0663, 0xfbca2199, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3dffffff, 0x00000000, 0x00000000}, + {0x51e79ea1, 0xf4064211, 0xe9e7e9b7, 0xb68a5852, 0x6f7af29a, 0xfddfec94, 0x5d78645b, 0xfb0d2fee, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffffff, 0x00000000, 0x00000000}, + {0xdc76db96, 0xab55e821, 0x8ab72905, 0x8171575d, 0x20150caf, 0x2ac94990, 0xdb92c254, 0xfa503e42, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x41ffffff, 0x00000000, 0x00000000}, + {0x6706188b, 0x62a58e32, 0x2b866853, 0x4c585668, 0xd0af26c4, 0x57b2a68b, 0x59ad204c, 0xf9934c97, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x43ffffff, 0x00000000, 0x00000000}, + {0xf1955580, 0x19f53442, 0xcc55a7a1, 0x173f5572, 0x814940d9, 0x849c0387, 0xd7c77e44, 0xf8d65aeb, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x45ffffff, 0x00000000, 0x00000000}, + {0x7c249275, 0xd144da53, 0x6d24e6ee, 0xe226547d, 0x31e35aed, 0xb1856083, 0x55e1dc3c, 0xf8196940, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x47ffffff, 0x00000000, 0x00000000}, + {0x06b3cf6a, 0x88948064, 0x0df4263c, 0xad0d5388, 0xe27d7502, 0xde6ebd7e, 0xd3fc3a34, 0xf75c7794, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x49ffffff, 0x00000000, 0x00000000}, + {0x91430c5f, 0x3fe42674, 0xaec3658a, 0x77f45292, 0x93178f17, 0x0b581a7a, 0x5216982d, 0xf69f85e9, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x4bffffff, 0x00000000, 0x00000000}, + {0x1bd24954, 0xf733cc85, 0x4f92a4d7, 0x42db519d, 0x43b1a92c, 0x38417776, 0xd030f625, 0xf5e2943d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x4dffffff, 0x00000000, 0x00000000}, + {0xa6618649, 0xae837295, 0xf061e425, 0x0dc250a7, 0xf44bc341, 0x652ad471, 0x4e4b541d, 0xf525a292, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x4fffffff, 0x00000000, 0x00000000}, + {0x30f0c33e, 0x65d318a6, 0x91312373, 0xd8a94fb2, 0xa4e5dd55, 0x9214316d, 0xcc65b215, 0xf468b0e6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x51ffffff, 0x00000000, 0x00000000}, + {0xbb800033, 0x1d22beb6, 0x320062c1, 0xa3904ebd, 0x557ff76a, 0xbefd8e69, 0x4a80100d, 0xf3abbf3b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x53ffffff, 0x00000000, 0x00000000}, + {0x460f3d28, 0xd47264c7, 0xd2cfa20e, 0x6e774dc7, 0x061a117f, 0xebe6eb65, 0xc89a6e05, 0xf2eecd8f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x55ffffff, 0x00000000, 0x00000000}, + {0xd09e7a1d, 0x8bc20ad7, 0x739ee15c, 0x395e4cd2, 0xb6b42b94, 0x18d04860, 0x46b4cbfe, 0xf231dbe4, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x57ffffff, 0x00000000, 0x00000000}, + {0x5b2db712, 0x4311b0e8, 0x146e20aa, 0x04454bdd, 0x674e45a9, 0x45b9a55c, 0xc4cf29f6, 0xf174ea38, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x59ffffff, 0x00000000, 0x00000000}, + {0xe5bcf407, 0xfa6156f8, 0xb53d5ff7, 0xcf2c4ae7, 0x17e85fbd, 0x72a30258, 0x42e987ee, 0xf0b7f88d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x5bffffff, 0x00000000, 0x00000000}, + {0x704c30fc, 0xb1b0fd09, 0x560c9f45, 0x9a1349f2, 0xc88279d2, 0x9f8c5f53, 0xc103e5e6, 0xeffb06e1, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x5dffffff, 0x00000000, 0x00000000}}}; static constexpr storage<8> rou = {0xec2a895e, 0x476ef4a4, 0x63e3f04a, 0x9b506ee3, 0xd1a8a12f, 0x60c69477, 0x0cb92cc1, 0x11d4b7f6}; diff --git a/icicle/include/icicle/fields/snark_fields/bls12_381_scalar.h b/icicle/include/icicle/fields/snark_fields/bls12_381_scalar.h index 3d1027534b..9e254cded6 100644 --- a/icicle/include/icicle/fields/snark_fields/bls12_381_scalar.h +++ b/icicle/include/icicle/fields/snark_fields/bls12_381_scalar.h @@ -10,7 +10,38 @@ namespace bls12_381 { struct fp_config { static constexpr storage<8> modulus = {0x00000001, 0xffffffff, 0xfffe5bfe, 0x53bda402, 0x09a1d805, 0x3339d808, 0x299d7d48, 0x73eda753}; + static constexpr unsigned reduced_digits_count = 3; + static constexpr storage_array reduced_digits = { + {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0xfffffffe, 0x00000001, 0x00034802, 0x5884b7fa, 0xecbc4ff5, 0x998c4fef, 0xacc5056f, 0x1824b159}, + {0xf3f29c6d, 0xc999e990, 0x87925c23, 0x2b6cedcb, 0x7254398f, 0x05d31496, 0x9f59ff11, 0x0748d9d9}}}; PARAMS(modulus) + MOD_SQR_SUBS() + static constexpr storage_array mod_subs = { + {{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x4181ac72, 0xe6ccc2ce, 0x6f0e51fb, 0x1b2b44c5, 0x2e18c7cc, 0xcc0fec6a, 0x9c79b122, 0xd39dc605, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0x00000000, 0x00000000}, + {0x830358e4, 0xcd99859c, 0xde1ca3f7, 0x3656898a, 0x5c318f98, 0x981fd8d4, 0x38f36245, 0xa73b8c0b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffffff, 0x00000000, 0x00000000}, + {0xc4850557, 0xb4664869, 0x4d2951f2, 0xa53f7253, 0x93ec2f69, 0x97699d46, 0xff0a90b0, 0xeec6f963, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x5fffffff, 0x00000000, 0x00000000}, + {0x0606b1c9, 0x9b330b38, 0xbc37a3ee, 0xc06ab718, 0xc204f735, 0x637989b0, 0x9b8441d3, 0xc264bf69, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff, 0x00000000, 0x00000000}, + {0x47885e3b, 0x81ffce06, 0x2b45f5ea, 0xdb95fbde, 0xf01dbf01, 0x2f89761a, 0x37fdf2f6, 0x9602856f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x9fffffff, 0x00000000, 0x00000000}, + {0x890a0aae, 0x68cc90d3, 0x9a52a3e5, 0x4a7ee4a6, 0x27d85ed3, 0x2ed33a8d, 0xfe152161, 0xdd8df2c7, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xbfffffff, 0x00000000, 0x00000000}, + {0xca8bb720, 0x4f9953a1, 0x0960f5e1, 0x65aa296c, 0x55f1269f, 0xfae326f7, 0x9a8ed283, 0xb12bb8cd, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xdfffffff, 0x00000000, 0x00000000}, + {0x0c0d6393, 0x3666166f, 0x786da3dc, 0xd4931234, 0x8dabc670, 0xfa2ceb69, 0x60a600ee, 0xf8b72626, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000}, + {0x4d8f1005, 0x1d32d93d, 0xe77bf5d8, 0xefbe56f9, 0xbbc48e3c, 0xc63cd7d3, 0xfd1fb211, 0xcc54ec2b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0x00000001, 0x00000000}, + {0x8f10bc77, 0x03ff9c0b, 0x568a47d4, 0x0ae99bbf, 0xe9dd5609, 0x924cc43d, 0x99996334, 0x9ff2b231, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffffff, 0x00000001, 0x00000000}, + {0xd09268ea, 0xeacc5ed8, 0xc596f5ce, 0x79d28487, 0x2197f5da, 0x919688b0, 0x5fb0919f, 0xe77e1f8a, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x5fffffff, 0x00000001, 0x00000000}}}; static constexpr storage<8> rou = {0x0b912f1f, 0x1b788f50, 0x70b3e094, 0xc4024ff2, 0xd168d6c0, 0x0fd56dc8, 0x5b416b6f, 0x0212d79e}; diff --git a/icicle/include/icicle/fields/snark_fields/bn254_base.h b/icicle/include/icicle/fields/snark_fields/bn254_base.h index 6ff23e1bc6..57ab68825e 100644 --- a/icicle/include/icicle/fields/snark_fields/bn254_base.h +++ b/icicle/include/icicle/fields/snark_fields/bn254_base.h @@ -7,7 +7,62 @@ namespace bn254 { struct fq_config { static constexpr storage<8> modulus = {0xd87cfd47, 0x3c208c16, 0x6871ca8d, 0x97816a91, 0x8181585d, 0xb85045b6, 0xe131a029, 0x30644e72}; + static constexpr unsigned reduced_digits_count = 3; + static constexpr storage_array reduced_digits = { + {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0xc58f0d9d, 0xd35d438d, 0xf5c70b3d, 0x0a78eb28, 0x7879462c, 0x666ea36f, 0x9a07df2f, 0x0e0a77c1}, + {0x538afa89, 0xf32cfc5b, 0xd44501fb, 0xb5e71911, 0x0a417ff6, 0x47ab1eff, 0xcab8351f, 0x06d89f71}}}; PARAMS(modulus) + MOD_SQR_SUBS() + static constexpr storage_array mod_subs = { + {{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0261419e, 0x18754db1, 0x31e16455, 0x91d4069a, 0x12e13d0e, 0xdbd801ff, 0x6a07e140, 0xe613f157, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x07ffffff, 0x00000000, 0x00000000}, + {0xdd3f8083, 0x6d0b2778, 0xcc349337, 0xbb2977c5, 0xa743d27a, 0x700049b4, 0xb54162ab, 0xfc8c3121, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0fffffff, 0x00000000, 0x00000000}, + {0xdfa0c221, 0x85807529, 0xfe15f78c, 0x4cfd7e5f, 0xba250f89, 0x4bd84bb3, 0x1f4943ec, 0xe2a02279, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x17ffffff, 0x00000000, 0x00000000}, + {0xba7f0106, 0xda164ef1, 0x9869266e, 0x7652ef8b, 0x4e87a4f5, 0xe0009369, 0x6a82c556, 0xf9186243, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0x00000000, 0x00000000}, + {0xbce042a4, 0xf28b9ca2, 0xca4a8ac3, 0x0826f625, 0x6168e204, 0xbbd89568, 0xd48aa697, 0xdf2c539a, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x27ffffff, 0x00000000, 0x00000000}, + {0x97be8189, 0x4721766a, 0x649db9a6, 0x317c6751, 0xf5cb7770, 0x5000dd1d, 0x1fc42802, 0xf5a49365, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2fffffff, 0x00000000, 0x00000000}, + {0x9a1fc327, 0x5f96c41b, 0x967f1dfb, 0xc3506deb, 0x08acb47e, 0x2bd8df1d, 0x89cc0943, 0xdbb884bc, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x37ffffff, 0x00000000, 0x00000000}, + {0x74fe020c, 0xb42c9de3, 0x30d24cdd, 0xeca5df17, 0x9d0f49ea, 0xc00126d2, 0xd5058aad, 0xf230c486, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffffff, 0x00000000, 0x00000000}, + {0x775f43aa, 0xcca1eb94, 0x62b3b132, 0x7e79e5b1, 0xaff086f9, 0x9bd928d1, 0x3f0d6bee, 0xd844b5de, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x47ffffff, 0x00000000, 0x00000000}, + {0x523d828f, 0x2137c55c, 0xfd06e015, 0xa7cf56dc, 0x44531c65, 0x30017087, 0x8a46ed59, 0xeebcf5a8, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x4fffffff, 0x00000000, 0x00000000}, + {0x549ec42d, 0x39ad130d, 0x2ee8446a, 0x39a35d77, 0x57345974, 0x0bd97286, 0xf44ece9a, 0xd4d0e6ff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x57ffffff, 0x00000000, 0x00000000}, + {0x2f7d0312, 0x8e42ecd5, 0xc93b734c, 0x62f8cea2, 0xeb96eee0, 0xa001ba3b, 0x3f885004, 0xeb4926ca, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x5fffffff, 0x00000000, 0x00000000}, + {0x31de44b0, 0xa6b83a86, 0xfb1cd7a1, 0xf4ccd53c, 0xfe782bee, 0x7bd9bc3a, 0xa9903145, 0xd15d1821, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x67ffffff, 0x00000000, 0x00000000}, + {0x0cbc8395, 0xfb4e144e, 0x95700683, 0x1e224668, 0x92dac15b, 0x100203f0, 0xf4c9b2b0, 0xe7d557eb, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x6fffffff, 0x00000000, 0x00000000}, + {0xe79ac27a, 0x4fe3ee15, 0x2fc33566, 0x4777b794, 0x273d56c7, 0xa42a4ba6, 0x4003341a, 0xfe4d97b6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x77ffffff, 0x00000000, 0x00000000}, + {0xe9fc0418, 0x68593bc6, 0x61a499bb, 0xd94bbe2e, 0x3a1e93d5, 0x80024da5, 0xaa0b155b, 0xe461890d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff, 0x00000000, 0x00000000}, + {0xc4da42fd, 0xbcef158e, 0xfbf7c89d, 0x02a12f59, 0xce812942, 0x142a955a, 0xf54496c6, 0xfad9c8d7, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x87ffffff, 0x00000000, 0x00000000}, + {0xc73b849b, 0xd564633f, 0x2dd92cf2, 0x947535f4, 0xe1626650, 0xf0029759, 0x5f4c7806, 0xe0edba2f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x8fffffff, 0x00000000, 0x00000000}, + {0xa219c380, 0x29fa3d07, 0xc82c5bd5, 0xbdcaa71f, 0x75c4fbbc, 0x842adf0f, 0xaa85f971, 0xf765f9f9, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x97ffffff, 0x00000000, 0x00000000}, + {0xa47b051e, 0x426f8ab8, 0xfa0dc02a, 0x4f9eadb9, 0x88a638cb, 0x6002e10e, 0x148ddab2, 0xdd79eb51, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x9fffffff, 0x00000000, 0x00000000}, + {0x7f594403, 0x97056480, 0x9460ef0c, 0x78f41ee5, 0x1d08ce37, 0xf42b28c4, 0x5fc75c1c, 0xf3f22b1b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xa7ffffff, 0x00000000, 0x00000000}, + {0x81ba85a1, 0xaf7ab231, 0xc6425361, 0x0ac8257f, 0x2fea0b46, 0xd0032ac3, 0xc9cf3d5d, 0xda061c72, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xafffffff, 0x00000000, 0x00000000}, + {0x5c98c486, 0x04108bf9, 0x60958244, 0x341d96ab, 0xc44ca0b2, 0x642b7278, 0x1508bec8, 0xf07e5c3d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xb7ffffff, 0x00000000, 0x00000000}}}; // nonresidue to generate the extension field static constexpr uint32_t nonresidue = 1; diff --git a/icicle/include/icicle/fields/snark_fields/bn254_scalar.h b/icicle/include/icicle/fields/snark_fields/bn254_scalar.h index edaecee208..737e5df877 100644 --- a/icicle/include/icicle/fields/snark_fields/bn254_scalar.h +++ b/icicle/include/icicle/fields/snark_fields/bn254_scalar.h @@ -8,7 +8,62 @@ namespace bn254 { struct fp_config { static constexpr storage<8> modulus = {0xf0000001, 0x43e1f593, 0x79b97091, 0x2833e848, 0x8181585d, 0xb85045b6, 0xe131a029, 0x30644e72}; + static constexpr unsigned reduced_digits_count = 3; + static constexpr storage_array reduced_digits = { + {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x4ffffffb, 0xac96341c, 0x9f60cd29, 0x36fc7695, 0x7879462e, 0x666ea36f, 0x9a07df2f, 0x0e0a77c1}, + {0xae216da7, 0x1bb8e645, 0xe35c59e3, 0x53fe3ab1, 0x53bb8085, 0x8c49833d, 0x7f4e44a5, 0x0216d0b1}}}; PARAMS(modulus) + MOD_SQR_SUBS() + static constexpr storage_array mod_subs = { + {{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x3f0ef492, 0x6a19b0f2, 0xd1cc3d3f, 0x0df780b1, 0x803516f3, 0x3b9efd6f, 0xb416c8ba, 0xda20ec30, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x07ffffff, 0x00000000, 0x00000000}, + {0x6e1de925, 0x18155778, 0x1d51eb10, 0x4422e9ac, 0x81eb8643, 0x2f8e4095, 0x495f319e, 0xe4a626d4, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0fffffff, 0x00000000, 0x00000000}, + {0x9d2cddb8, 0xc610fdfe, 0x68d798e0, 0x7a4e52a6, 0x83a1f593, 0x237d83bb, 0xdea79a82, 0xef2b6177, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x17ffffff, 0x00000000, 0x00000000}, + {0xcc3bd24b, 0x740ca484, 0xb45d46b1, 0xb079bba0, 0x855864e3, 0x176cc6e1, 0x73f00366, 0xf9b09c1b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0x00000000, 0x00000000}, + {0x0b4ac6dd, 0xde265577, 0x862983f0, 0xbe713c52, 0x058d7bd6, 0x530bc451, 0x2806cc20, 0xd3d1884c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x27ffffff, 0x00000000, 0x00000000}, + {0x3a59bb70, 0x8c21fbfd, 0xd1af31c1, 0xf49ca54c, 0x0743eb26, 0x46fb0777, 0xbd4f3504, 0xde56c2ef, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2fffffff, 0x00000000, 0x00000000}, + {0x6968b003, 0x3a1da283, 0x1d34df92, 0x2ac80e47, 0x08fa5a77, 0x3aea4a9d, 0x52979de8, 0xe8dbfd93, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x37ffffff, 0x00000000, 0x00000000}, + {0x9877a496, 0xe8194909, 0x68ba8d62, 0x60f37741, 0x0ab0c9c7, 0x2ed98dc3, 0xe7e006cc, 0xf3613836, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3fffffff, 0x00000000, 0x00000000}, + {0xc7869929, 0x9614ef8f, 0xb4403b33, 0x971ee03b, 0x0c673917, 0x22c8d0e9, 0x7d286fb0, 0xfde672da, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x47ffffff, 0x00000000, 0x00000000}, + {0x06958dbb, 0x002ea082, 0x860c7873, 0xa51660ed, 0x8c9c500a, 0x5e67ce58, 0x313f386a, 0xd8075f0b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x4fffffff, 0x00000000, 0x00000000}, + {0x35a4824e, 0xae2a4708, 0xd1922643, 0xdb41c9e7, 0x8e52bf5a, 0x5257117e, 0xc687a14e, 0xe28c99ae, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x57ffffff, 0x00000000, 0x00000000}, + {0x64b376e1, 0x5c25ed8e, 0x1d17d414, 0x116d32e2, 0x90092eab, 0x464654a4, 0x5bd00a32, 0xed11d452, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x5fffffff, 0x00000000, 0x00000000}, + {0x93c26b74, 0x0a219414, 0x689d81e5, 0x47989bdc, 0x91bf9dfb, 0x3a3597ca, 0xf1187316, 0xf7970ef5, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x67ffffff, 0x00000000, 0x00000000}, + {0xd2d16006, 0x743b4506, 0x3a69bf24, 0x55901c8e, 0x11f4b4ee, 0x75d4953a, 0xa52f3bd0, 0xd1b7fb26, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x6fffffff, 0x00000000, 0x00000000}, + {0x01e05499, 0x2236eb8d, 0x85ef6cf5, 0x8bbb8588, 0x13ab243e, 0x69c3d860, 0x3a77a4b4, 0xdc3d35ca, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x77ffffff, 0x00000000, 0x00000000}, + {0x30ef492c, 0xd0329213, 0xd1751ac5, 0xc1e6ee82, 0x1561938e, 0x5db31b86, 0xcfc00d98, 0xe6c2706d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff, 0x00000000, 0x00000000}, + {0x5ffe3dbf, 0x7e2e3899, 0x1cfac896, 0xf812577d, 0x171802de, 0x51a25eac, 0x6508767c, 0xf147ab11, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x87ffffff, 0x00000000, 0x00000000}, + {0x8f0d3252, 0x2c29df1f, 0x68807667, 0x2e3dc077, 0x18ce722f, 0x4591a1d2, 0xfa50df60, 0xfbcce5b4, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x8fffffff, 0x00000000, 0x00000000}, + {0xce1c26e4, 0x96439011, 0x3a4cb3a6, 0x3c354129, 0x99038922, 0x81309f41, 0xae67a81a, 0xd5edd1e5, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x97ffffff, 0x00000000, 0x00000000}, + {0xfd2b1b77, 0x443f3697, 0x85d26177, 0x7260aa23, 0x9ab9f872, 0x751fe267, 0x43b010fe, 0xe0730c89, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x9fffffff, 0x00000000, 0x00000000}, + {0x2c3a100a, 0xf23add1e, 0xd1580f47, 0xa88c131d, 0x9c7067c2, 0x690f258d, 0xd8f879e2, 0xeaf8472c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xa7ffffff, 0x00000000, 0x00000000}, + {0x5b49049d, 0xa03683a4, 0x1cddbd18, 0xdeb77c18, 0x9e26d712, 0x5cfe68b3, 0x6e40e2c6, 0xf57d81d0, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xafffffff, 0x00000000, 0x00000000}, + {0x9a57f92f, 0x0a503496, 0xeea9fa58, 0xecaefcc9, 0x1e5bee05, 0x989d6623, 0x2257ab80, 0xcf9e6e01, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xb7ffffff, 0x00000000, 0x00000000}}}; static constexpr storage<8> rou = {0x725b19f0, 0x9bd61b6e, 0x41112ed4, 0x402d111e, 0x8ef62abc, 0x00e0a7eb, 0xa58a7e85, 0x2a3c09f0}; diff --git a/icicle/include/icicle/fields/stark_fields/babybear.h b/icicle/include/icicle/fields/stark_fields/babybear.h index 8000431aac..46ff043e60 100644 --- a/icicle/include/icicle/fields/stark_fields/babybear.h +++ b/icicle/include/icicle/fields/stark_fields/babybear.h @@ -8,7 +8,65 @@ namespace babybear { struct fp_config { static constexpr storage<1> modulus = {0x78000001}; + static constexpr unsigned reduced_digits_count = 18; + static constexpr storage_array reduced_digits = { + {{0x1}, + {0xffffffe}, + {0x45dddde3}, + {0x12f37bfb}, + {0x27922ab6}, + {0x6394fa39}, + {0xb8efb44}, + {0x57578192}, + {0x25abb864}, + {0x6fa2bae8}, + {0x11d80ae0}, + {0x71eed7bd}, + {0x4cf166f8}, + {0x43dae013}, + {0x173e21fb}, + {0x5e6a622e}, + {0x169483e4}, + {0x0fd43bf8}}}; PARAMS(modulus) + MOD_SQR_SUBS() + static constexpr storage_array mod_subs = { + {{0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0xac444443, 0x1fffffff, 0x00000000, 0x00000000}, + {0xd0888887, 0x3fffffff, 0x00000000, 0x00000000}, {0xf4cccccb, 0x5fffffff, 0x00000000, 0x00000000}, + {0xa111110e, 0x7fffffff, 0x00000000, 0x00000000}, {0xc5555552, 0x9fffffff, 0x00000000, 0x00000000}, + {0xe9999996, 0xbfffffff, 0x00000000, 0x00000000}, {0x95ddddd9, 0xdfffffff, 0x00000000, 0x00000000}, + {0xba22221d, 0xffffffff, 0x00000000, 0x00000000}, {0xde666661, 0x1fffffff, 0x00000001, 0x00000000}, + {0x8aaaaaa4, 0x3fffffff, 0x00000001, 0x00000000}, {0xaeeeeee8, 0x5fffffff, 0x00000001, 0x00000000}, + {0xd333332c, 0x7fffffff, 0x00000001, 0x00000000}, {0xf7777770, 0x9fffffff, 0x00000001, 0x00000000}, + {0xa3bbbbb3, 0xbfffffff, 0x00000001, 0x00000000}, {0xc7fffff7, 0xdfffffff, 0x00000001, 0x00000000}, + {0xec44443b, 0xffffffff, 0x00000001, 0x00000000}, {0x9888887e, 0x1fffffff, 0x00000002, 0x00000000}, + {0xbcccccc2, 0x3fffffff, 0x00000002, 0x00000000}, {0xe1111106, 0x5fffffff, 0x00000002, 0x00000000}, + {0x8d555549, 0x7fffffff, 0x00000002, 0x00000000}, {0xb199998d, 0x9fffffff, 0x00000002, 0x00000000}, + {0xd5ddddd1, 0xbfffffff, 0x00000002, 0x00000000}, {0xfa222215, 0xdfffffff, 0x00000002, 0x00000000}, + {0xa6666658, 0xffffffff, 0x00000002, 0x00000000}, {0xcaaaaa9c, 0x1fffffff, 0x00000003, 0x00000000}, + {0xeeeeeee0, 0x3fffffff, 0x00000003, 0x00000000}, {0x9b333323, 0x5fffffff, 0x00000003, 0x00000000}, + {0xbf777767, 0x7fffffff, 0x00000003, 0x00000000}, {0xe3bbbbab, 0x9fffffff, 0x00000003, 0x00000000}, + {0x8fffffee, 0xbfffffff, 0x00000003, 0x00000000}, {0xb4444432, 0xdfffffff, 0x00000003, 0x00000000}, + {0xd8888876, 0xffffffff, 0x00000003, 0x00000000}, {0xfcccccba, 0x1fffffff, 0x00000004, 0x00000000}, + {0xa91110fd, 0x3fffffff, 0x00000004, 0x00000000}, {0xcd555541, 0x5fffffff, 0x00000004, 0x00000000}, + {0xf1999985, 0x7fffffff, 0x00000004, 0x00000000}, {0x9dddddc8, 0x9fffffff, 0x00000004, 0x00000000}, + {0xc222220c, 0xbfffffff, 0x00000004, 0x00000000}, {0xe6666650, 0xdfffffff, 0x00000004, 0x00000000}, + {0x92aaaa93, 0xffffffff, 0x00000004, 0x00000000}, {0xb6eeeed7, 0x1fffffff, 0x00000005, 0x00000000}, + {0xdb33331b, 0x3fffffff, 0x00000005, 0x00000000}, {0xff77775f, 0x5fffffff, 0x00000005, 0x00000000}, + {0xabbbbba2, 0x7fffffff, 0x00000005, 0x00000000}, {0xcfffffe6, 0x9fffffff, 0x00000005, 0x00000000}, + {0xf444442a, 0xbfffffff, 0x00000005, 0x00000000}, {0xa088886d, 0xdfffffff, 0x00000005, 0x00000000}, + {0xc4ccccb1, 0xffffffff, 0x00000005, 0x00000000}, {0xe91110f5, 0x1fffffff, 0x00000006, 0x00000000}, + {0x95555538, 0x3fffffff, 0x00000006, 0x00000000}, {0xb999997c, 0x5fffffff, 0x00000006, 0x00000000}, + {0xddddddc0, 0x7fffffff, 0x00000006, 0x00000000}, {0x8a222203, 0x9fffffff, 0x00000006, 0x00000000}, + {0xae666647, 0xbfffffff, 0x00000006, 0x00000000}, {0xd2aaaa8b, 0xdfffffff, 0x00000006, 0x00000000}, + {0xf6eeeecf, 0xffffffff, 0x00000006, 0x00000000}, {0xa3333312, 0x1fffffff, 0x00000007, 0x00000000}, + {0xc7777756, 0x3fffffff, 0x00000007, 0x00000000}, {0xebbbbb9a, 0x5fffffff, 0x00000007, 0x00000000}, + {0x97ffffdd, 0x7fffffff, 0x00000007, 0x00000000}, {0xbc444421, 0x9fffffff, 0x00000007, 0x00000000}, + {0xe0888865, 0xbfffffff, 0x00000007, 0x00000000}, {0x8ccccca8, 0xdfffffff, 0x00000007, 0x00000000}, + {0xb11110ec, 0xffffffff, 0x00000007, 0x00000000}, {0xd5555530, 0x1fffffff, 0x00000008, 0x00000000}, + {0xf9999974, 0x3fffffff, 0x00000008, 0x00000000}, {0xa5ddddb7, 0x5fffffff, 0x00000008, 0x00000000}, + {0xca2221fb, 0x7fffffff, 0x00000008, 0x00000000}, {0xee66663f, 0x9fffffff, 0x00000008, 0x00000000}, + {0x9aaaaa82, 0xbfffffff, 0x00000008, 0x00000000}, {0xbeeeeec6, 0xdfffffff, 0x00000008, 0x00000000}}}; static constexpr storage<1> rou = {0x00000089}; TWIDDLES(modulus, rou) diff --git a/icicle/include/icicle/fields/stark_fields/koalabear.h b/icicle/include/icicle/fields/stark_fields/koalabear.h index e276816788..438da210b0 100644 --- a/icicle/include/icicle/fields/stark_fields/koalabear.h +++ b/icicle/include/icicle/fields/stark_fields/koalabear.h @@ -8,7 +8,65 @@ namespace koalabear { struct fp_config { static constexpr storage<1> modulus = {0x7f000001}; + static constexpr unsigned reduced_digits_count = 18; + static constexpr storage_array reduced_digits = { + {{0x00000001}, + {0x01fffffe}, + {0x17f7efe4}, + {0x18af7f37}, + {0x423d7c8c}, + {0x1b79fadf}, + {0x7b9d44cd}, + {0x64d31ca2}, + {0x5bc34d59}, + {0x0f077438}, + {0x4fb48092}, + {0x2d55aa32}, + {0x389de76c}, + {0x02dff10b}, + {0x023486f8}, + {0x4e8e0e2d}, + {0x55a7320c}, + {0x50584c83}}}; PARAMS(modulus) + MOD_SQR_SUBS() + static constexpr storage_array mod_subs = { + {{0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0xbd810203, 0x1fffffff, 0x00000000, 0x00000000}, + {0xfa020407, 0x3fffffff, 0x00000000, 0x00000000}, {0xb783060a, 0x5fffffff, 0x00000000, 0x00000000}, + {0xf404080e, 0x7fffffff, 0x00000000, 0x00000000}, {0xb1850a11, 0x9fffffff, 0x00000000, 0x00000000}, + {0xee060c15, 0xbfffffff, 0x00000000, 0x00000000}, {0xab870e18, 0xdfffffff, 0x00000000, 0x00000000}, + {0xe808101c, 0xffffffff, 0x00000000, 0x00000000}, {0xa589121f, 0x1fffffff, 0x00000001, 0x00000000}, + {0xe20a1423, 0x3fffffff, 0x00000001, 0x00000000}, {0x9f8b1626, 0x5fffffff, 0x00000001, 0x00000000}, + {0xdc0c182a, 0x7fffffff, 0x00000001, 0x00000000}, {0x998d1a2d, 0x9fffffff, 0x00000001, 0x00000000}, + {0xd60e1c31, 0xbfffffff, 0x00000001, 0x00000000}, {0x938f1e34, 0xdfffffff, 0x00000001, 0x00000000}, + {0xd0102038, 0xffffffff, 0x00000001, 0x00000000}, {0x8d91223b, 0x1fffffff, 0x00000002, 0x00000000}, + {0xca12243f, 0x3fffffff, 0x00000002, 0x00000000}, {0x87932642, 0x5fffffff, 0x00000002, 0x00000000}, + {0xc4142846, 0x7fffffff, 0x00000002, 0x00000000}, {0x81952a49, 0x9fffffff, 0x00000002, 0x00000000}, + {0xbe162c4d, 0xbfffffff, 0x00000002, 0x00000000}, {0xfa972e51, 0xdfffffff, 0x00000002, 0x00000000}, + {0xb8183054, 0xffffffff, 0x00000002, 0x00000000}, {0xf4993258, 0x1fffffff, 0x00000003, 0x00000000}, + {0xb21a345b, 0x3fffffff, 0x00000003, 0x00000000}, {0xee9b365f, 0x5fffffff, 0x00000003, 0x00000000}, + {0xac1c3862, 0x7fffffff, 0x00000003, 0x00000000}, {0xe89d3a66, 0x9fffffff, 0x00000003, 0x00000000}, + {0xa61e3c69, 0xbfffffff, 0x00000003, 0x00000000}, {0xe29f3e6d, 0xdfffffff, 0x00000003, 0x00000000}, + {0xa0204070, 0xffffffff, 0x00000003, 0x00000000}, {0xdca14274, 0x1fffffff, 0x00000004, 0x00000000}, + {0xd6a3467b, 0x5fffffff, 0x00000004, 0x00000000}, {0x9a224477, 0x3fffffff, 0x00000004, 0x00000000}, + {0x9424487e, 0x7fffffff, 0x00000004, 0x00000000}, {0xd0a54a82, 0x9fffffff, 0x00000004, 0x00000000}, + {0x8e264c85, 0xbfffffff, 0x00000004, 0x00000000}, {0xcaa74e89, 0xdfffffff, 0x00000004, 0x00000000}, + {0x8828508c, 0xffffffff, 0x00000004, 0x00000000}, {0xc4a95290, 0x1fffffff, 0x00000005, 0x00000000}, + {0x822a5493, 0x3fffffff, 0x00000005, 0x00000000}, {0xbeab5697, 0x5fffffff, 0x00000005, 0x00000000}, + {0xfb2c589b, 0x7fffffff, 0x00000005, 0x00000000}, {0xb8ad5a9e, 0x9fffffff, 0x00000005, 0x00000000}, + {0xf52e5ca2, 0xbfffffff, 0x00000005, 0x00000000}, {0xb2af5ea5, 0xdfffffff, 0x00000005, 0x00000000}, + {0xef3060a9, 0xffffffff, 0x00000005, 0x00000000}, {0xacb162ac, 0x1fffffff, 0x00000006, 0x00000000}, + {0xe93264b0, 0x3fffffff, 0x00000006, 0x00000000}, {0xa6b366b3, 0x5fffffff, 0x00000006, 0x00000000}, + {0xe33468b7, 0x7fffffff, 0x00000006, 0x00000000}, {0xa0b56aba, 0x9fffffff, 0x00000006, 0x00000000}, + {0xdd366cbe, 0xbfffffff, 0x00000006, 0x00000000}, {0x9ab76ec1, 0xdfffffff, 0x00000006, 0x00000000}, + {0xd73870c5, 0xffffffff, 0x00000006, 0x00000000}, {0x94b972c8, 0x1fffffff, 0x00000007, 0x00000000}, + {0xd13a74cc, 0x3fffffff, 0x00000007, 0x00000000}, {0x8ebb76cf, 0x5fffffff, 0x00000007, 0x00000000}, + {0xcb3c78d3, 0x7fffffff, 0x00000007, 0x00000000}, {0x88bd7ad6, 0x9fffffff, 0x00000007, 0x00000000}, + {0xc53e7cda, 0xbfffffff, 0x00000007, 0x00000000}, {0x82bf7edd, 0xdfffffff, 0x00000007, 0x00000000}, + {0xbf4080e1, 0xffffffff, 0x00000007, 0x00000000}, {0xfbc182e5, 0x1fffffff, 0x00000008, 0x00000000}, + {0xb94284e8, 0x3fffffff, 0x00000008, 0x00000000}, {0xf5c386ec, 0x5fffffff, 0x00000008, 0x00000000}, + {0xb34488ef, 0x7fffffff, 0x00000008, 0x00000000}, {0xefc58af3, 0x9fffffff, 0x00000008, 0x00000000}, + {0xad468cf6, 0xbfffffff, 0x00000008, 0x00000000}, {0xe9c78efa, 0xdfffffff, 0x00000008, 0x00000000}}}; static constexpr storage<1> rou = {0x6ac49f88}; TWIDDLES(modulus, rou) diff --git a/icicle/include/icicle/fields/stark_fields/m31.h b/icicle/include/icicle/fields/stark_fields/m31.h index d2b831a002..36f4b8047a 100644 --- a/icicle/include/icicle/fields/stark_fields/m31.h +++ b/icicle/include/icicle/fields/stark_fields/m31.h @@ -6,6 +6,10 @@ #include "icicle/fields/quartic_extension.h" #include "icicle/fields/params_gen.h" +#include +#include +#include + namespace m31 { template class MersenneField : public Field @@ -22,6 +26,58 @@ namespace m31 { static constexpr HOST_DEVICE_INLINE MersenneField from(uint32_t value) { return MersenneField(value); } + /* This function receives a storage object (currently supports up to 576 bits) and reduces it to a field element + between 0 and p. This is done using 2 steps: + 1. Splitting the number into TLC sized digits - xs = x_i * p_i = x_i * 2^(TLC*32*i). + In the case of Mersenne, p_i modulo p turn out to be 2^i, therefore, we can replace the multiplication with + shifts. At the end of this step the number is reduced from to 48 bits max (for a 576 input). + 2. The second step uses Mersenne reduction (splitting into digitd of 31 bits and adding) twice.*/ + template + static constexpr HOST_DEVICE_INLINE MersenneField from(const storage& xs) + { + static_assert(NLIMBS * 32 <= 576); // for now we support up to 576 bits + storage<2> rs = {}; + // first reduction step: + for (int i = 0; i < NLIMBS; i++) { + const MersenneField& xi = + *reinterpret_cast(xs.limbs + i); // use casting instead of copying + storage<2> temp = {}; + temp.limbs[0] = xi.limbs_storage.limbs[0] << i; // in mersenne pi become shifts + temp.limbs[1] = i ? xi.limbs_storage.limbs[0] >> (32 - i) : 0; + base_math::template add_sub_limbs<2, false, false, true>(rs, temp, rs); // accumulation + } + // second reduction step: + const uint32_t modulus = MersenneField::get_modulus().limbs[0]; + uint32_t tmp = ((rs.limbs[0] >> 31) | (rs.limbs[1] << 1)) + + (rs.limbs[0] & modulus); // mersenne reduction - max: 2^17 + 2^31-1 <= 2^32 + tmp = (tmp >> 31) + (tmp & modulus); // max: 1 + 0 = 1 + return MersenneField{{tmp == modulus ? 0 : tmp}}; + } + + /* This is the non-template version of the from(storage) function above. It receives an array of bytes and its size + and returns a field element after modular reduction. For now we support up to 576 bits. */ + static constexpr HOST_DEVICE_INLINE MersenneField from(const std::byte* in, unsigned nof_bytes) + { + storage<2> rs = {}; + unsigned constexpr bytes_per_field = 4; + int size = nof_bytes / bytes_per_field; + // first reduction step: + for (int i = 0; i < size; i++) { + const MersenneField& xi = + *reinterpret_cast(in + i * bytes_per_field); // use casting instead of copying + storage<2> temp = {}; + temp.limbs[0] = xi.limbs_storage.limbs[0] << i; // in mersenne pi become shifts + temp.limbs[1] = i ? xi.limbs_storage.limbs[0] >> (32 - i) : 0; + base_math::template add_sub_limbs<2, false, false, true>(rs, temp, rs); // accumulation + } + // second reduction step: + const uint32_t modulus = MersenneField::get_modulus().limbs[0]; + uint32_t tmp = ((rs.limbs[0] >> 31) | (rs.limbs[1] << 1)) + + (rs.limbs[0] & modulus); // mersenne reduction - max: 2^17 + 2^31-1 <= 2^32 + tmp = (tmp >> 31) + (tmp & modulus); // max: 1 + 0 = 1 + return MersenneField{{tmp == modulus ? 0 : tmp}}; + } + static HOST_INLINE MersenneField rand_host() { return MersenneField(Field::rand_host()); } static void rand_host_many(MersenneField* out, int size) @@ -207,7 +263,6 @@ namespace m31 { static constexpr storage_array omega_inv = {{{0x7ffffffe}}}; static constexpr storage_array inv = {{{0x40000000}}}; - // nonresidue to generate the extension field static constexpr uint32_t nonresidue = 1; // true if nonresidue is negative. diff --git a/icicle/include/icicle/fields/stark_fields/stark252.h b/icicle/include/icicle/fields/stark_fields/stark252.h index 6fb3da62e5..a971ee3b00 100644 --- a/icicle/include/icicle/fields/stark_fields/stark252.h +++ b/icicle/include/icicle/fields/stark_fields/stark252.h @@ -10,7 +10,207 @@ namespace stark252 { struct fp_config { static constexpr storage<8> modulus = {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000011, 0x08000000}; + + static constexpr unsigned reduced_digits_count = 3; + static constexpr storage_array reduced_digits = { + {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0xffffffe1, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffdf0, 0x07ffffff}, + {0x7e000401, 0xfffffd73, 0x330fffff, 0x00000001, 0xff6f8000, 0xffffffff, 0x5e008810, 0x07ffd4ab}}}; PARAMS(modulus) + MOD_SQR_SUBS() + static constexpr storage_array mod_subs = { + {{0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x4640fffd, 0x00000001, 0xff667800, 0xffffffff, 0x0000483f, 0x00000000, 0xaa50ffab, 0xf8000015, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x007fffff, 0x00000000, 0x00000000}, + {0x8c81fffb, 0x00000002, 0xfeccf000, 0xffffffff, 0x0000907f, 0x00000000, 0x54a1ff67, 0xf800002b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00ffffff, 0x00000000, 0x00000000}, + {0xd2c2fff9, 0x00000003, 0xfe336800, 0xffffffff, 0x0000d8bf, 0x00000000, 0xfef2ff23, 0xf8000040, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x017fffff, 0x00000000, 0x00000000}, + {0x1903fff7, 0x00000005, 0xfd99e000, 0xffffffff, 0x000120ff, 0x00000000, 0xa943fedf, 0xf8000056, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x01ffffff, 0x00000000, 0x00000000}, + {0x5f44fff5, 0x00000006, 0xfd005800, 0xffffffff, 0x0001693f, 0x00000000, 0x5394fe9b, 0xf800006c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x027fffff, 0x00000000, 0x00000000}, + {0xa585fff3, 0x00000007, 0xfc66d000, 0xffffffff, 0x0001b17f, 0x00000000, 0xfde5fe57, 0xf8000081, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x02ffffff, 0x00000000, 0x00000000}, + {0xebc6fff1, 0x00000008, 0xfbcd4800, 0xffffffff, 0x0001f9bf, 0x00000000, 0xa836fe13, 0xf8000097, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x037fffff, 0x00000000, 0x00000000}, + {0x3207ffef, 0x0000000a, 0xfb33c000, 0xffffffff, 0x000241ff, 0x00000000, 0x5287fdcf, 0xf80000ad, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03ffffff, 0x00000000, 0x00000000}, + {0x7848ffed, 0x0000000b, 0xfa9a3800, 0xffffffff, 0x00028a3f, 0x00000000, 0xfcd8fd8b, 0xf80000c2, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x047fffff, 0x00000000, 0x00000000}, + {0xbe89ffeb, 0x0000000c, 0xfa00b000, 0xffffffff, 0x0002d27f, 0x00000000, 0xa729fd47, 0xf80000d8, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x04ffffff, 0x00000000, 0x00000000}, + {0x04caffe9, 0x0000000e, 0xf9672800, 0xffffffff, 0x00031abf, 0x00000000, 0x517afd03, 0xf80000ee, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x057fffff, 0x00000000, 0x00000000}, + {0x4b0bffe7, 0x0000000f, 0xf8cda000, 0xffffffff, 0x000362ff, 0x00000000, 0xfbcbfcbf, 0xf8000103, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x05ffffff, 0x00000000, 0x00000000}, + {0x914cffe5, 0x00000010, 0xf8341800, 0xffffffff, 0x0003ab3f, 0x00000000, 0xa61cfc7b, 0xf8000119, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x067fffff, 0x00000000, 0x00000000}, + {0xd78dffe3, 0x00000011, 0xf79a9000, 0xffffffff, 0x0003f37f, 0x00000000, 0x506dfc37, 0xf800012f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x06ffffff, 0x00000000, 0x00000000}, + {0x1dceffe1, 0x00000013, 0xf7010800, 0xffffffff, 0x00043bbf, 0x00000000, 0xfabefbf3, 0xf8000144, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x077fffff, 0x00000000, 0x00000000}, + {0x640fffdf, 0x00000014, 0xf6678000, 0xffffffff, 0x000483ff, 0x00000000, 0xa50ffbaf, 0xf800015a, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x07ffffff, 0x00000000, 0x00000000}, + {0xaa50ffdd, 0x00000015, 0xf5cdf800, 0xffffffff, 0x0004cc3f, 0x00000000, 0x4f60fb6b, 0xf8000170, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x087fffff, 0x00000000, 0x00000000}, + {0xf091ffdb, 0x00000016, 0xf5347000, 0xffffffff, 0x0005147f, 0x00000000, 0xf9b1fb27, 0xf8000185, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x08ffffff, 0x00000000, 0x00000000}, + {0x36d2ffd9, 0x00000018, 0xf49ae800, 0xffffffff, 0x00055cbf, 0x00000000, 0xa402fae3, 0xf800019b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x097fffff, 0x00000000, 0x00000000}, + {0x7d13ffd7, 0x00000019, 0xf4016000, 0xffffffff, 0x0005a4ff, 0x00000000, 0x4e53fa9f, 0xf80001b1, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x09ffffff, 0x00000000, 0x00000000}, + {0xc354ffd5, 0x0000001a, 0xf367d800, 0xffffffff, 0x0005ed3f, 0x00000000, 0xf8a4fa5b, 0xf80001c6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0a7fffff, 0x00000000, 0x00000000}, + {0x0995ffd3, 0x0000001c, 0xf2ce5000, 0xffffffff, 0x0006357f, 0x00000000, 0xa2f5fa17, 0xf80001dc, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0affffff, 0x00000000, 0x00000000}, + {0x4fd6ffd1, 0x0000001d, 0xf234c800, 0xffffffff, 0x00067dbf, 0x00000000, 0x4d46f9d3, 0xf80001f2, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0b7fffff, 0x00000000, 0x00000000}, + {0x9617ffcf, 0x0000001e, 0xf19b4000, 0xffffffff, 0x0006c5ff, 0x00000000, 0xf797f98f, 0xf8000207, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0bffffff, 0x00000000, 0x00000000}, + {0xdc58ffcd, 0x0000001f, 0xf101b800, 0xffffffff, 0x00070e3f, 0x00000000, 0xa1e8f94b, 0xf800021d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0c7fffff, 0x00000000, 0x00000000}, + {0x2299ffcb, 0x00000021, 0xf0683000, 0xffffffff, 0x0007567f, 0x00000000, 0x4c39f907, 0xf8000233, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0cffffff, 0x00000000, 0x00000000}, + {0x68daffc9, 0x00000022, 0xefcea800, 0xffffffff, 0x00079ebf, 0x00000000, 0xf68af8c3, 0xf8000248, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0d7fffff, 0x00000000, 0x00000000}, + {0xaf1bffc7, 0x00000023, 0xef352000, 0xffffffff, 0x0007e6ff, 0x00000000, 0xa0dbf87f, 0xf800025e, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0dffffff, 0x00000000, 0x00000000}, + {0xf55cffc5, 0x00000024, 0xee9b9800, 0xffffffff, 0x00082f3f, 0x00000000, 0x4b2cf83b, 0xf8000274, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0e7fffff, 0x00000000, 0x00000000}, + {0x3b9dffc3, 0x00000026, 0xee021000, 0xffffffff, 0x0008777f, 0x00000000, 0xf57df7f7, 0xf8000289, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0effffff, 0x00000000, 0x00000000}, + {0x81deffc1, 0x00000027, 0xed688800, 0xffffffff, 0x0008bfbf, 0x00000000, 0x9fcef7b3, 0xf800029f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0f7fffff, 0x00000000, 0x00000000}, + {0xc81fffbf, 0x00000028, 0xeccf0000, 0xffffffff, 0x000907ff, 0x00000000, 0x4a1ff76f, 0xf80002b5, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0fffffff, 0x00000000, 0x00000000}, + {0x0e60ffbd, 0x0000002a, 0xec357800, 0xffffffff, 0x0009503f, 0x00000000, 0xf470f72b, 0xf80002ca, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x107fffff, 0x00000000, 0x00000000}, + {0x54a1ffbb, 0x0000002b, 0xeb9bf000, 0xffffffff, 0x0009987f, 0x00000000, 0x9ec1f6e7, 0xf80002e0, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x10ffffff, 0x00000000, 0x00000000}, + {0x9ae2ffb9, 0x0000002c, 0xeb026800, 0xffffffff, 0x0009e0bf, 0x00000000, 0x4912f6a3, 0xf80002f6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x117fffff, 0x00000000, 0x00000000}, + {0xe123ffb7, 0x0000002d, 0xea68e000, 0xffffffff, 0x000a28ff, 0x00000000, 0xf363f65f, 0xf800030b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x11ffffff, 0x00000000, 0x00000000}, + {0x2764ffb5, 0x0000002f, 0xe9cf5800, 0xffffffff, 0x000a713f, 0x00000000, 0x9db4f61b, 0xf8000321, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x127fffff, 0x00000000, 0x00000000}, + {0x6da5ffb3, 0x00000030, 0xe935d000, 0xffffffff, 0x000ab97f, 0x00000000, 0x4805f5d7, 0xf8000337, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x12ffffff, 0x00000000, 0x00000000}, + {0xb3e6ffb1, 0x00000031, 0xe89c4800, 0xffffffff, 0x000b01bf, 0x00000000, 0xf256f593, 0xf800034c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x137fffff, 0x00000000, 0x00000000}, + {0xfa27ffaf, 0x00000032, 0xe802c000, 0xffffffff, 0x000b49ff, 0x00000000, 0x9ca7f54f, 0xf8000362, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x13ffffff, 0x00000000, 0x00000000}, + {0x4068ffad, 0x00000034, 0xe7693800, 0xffffffff, 0x000b923f, 0x00000000, 0x46f8f50b, 0xf8000378, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x147fffff, 0x00000000, 0x00000000}, + {0x86a9ffab, 0x00000035, 0xe6cfb000, 0xffffffff, 0x000bda7f, 0x00000000, 0xf149f4c7, 0xf800038d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x14ffffff, 0x00000000, 0x00000000}, + {0xcceaffa9, 0x00000036, 0xe6362800, 0xffffffff, 0x000c22bf, 0x00000000, 0x9b9af483, 0xf80003a3, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x157fffff, 0x00000000, 0x00000000}, + {0x132bffa7, 0x00000038, 0xe59ca000, 0xffffffff, 0x000c6aff, 0x00000000, 0x45ebf43f, 0xf80003b9, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x15ffffff, 0x00000000, 0x00000000}, + {0x596cffa5, 0x00000039, 0xe5031800, 0xffffffff, 0x000cb33f, 0x00000000, 0xf03cf3fb, 0xf80003ce, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x167fffff, 0x00000000, 0x00000000}, + {0x9fadffa3, 0x0000003a, 0xe4699000, 0xffffffff, 0x000cfb7f, 0x00000000, 0x9a8df3b7, 0xf80003e4, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x16ffffff, 0x00000000, 0x00000000}, + {0xe5eeffa1, 0x0000003b, 0xe3d00800, 0xffffffff, 0x000d43bf, 0x00000000, 0x44def373, 0xf80003fa, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x177fffff, 0x00000000, 0x00000000}, + {0x2c2fff9f, 0x0000003d, 0xe3368000, 0xffffffff, 0x000d8bff, 0x00000000, 0xef2ff32f, 0xf800040f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x17ffffff, 0x00000000, 0x00000000}, + {0x7270ff9d, 0x0000003e, 0xe29cf800, 0xffffffff, 0x000dd43f, 0x00000000, 0x9980f2eb, 0xf8000425, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x187fffff, 0x00000000, 0x00000000}, + {0xb8b1ff9b, 0x0000003f, 0xe2037000, 0xffffffff, 0x000e1c7f, 0x00000000, 0x43d1f2a7, 0xf800043b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x18ffffff, 0x00000000, 0x00000000}, + {0xfef2ff99, 0x00000040, 0xe169e800, 0xffffffff, 0x000e64bf, 0x00000000, 0xee22f263, 0xf8000450, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x197fffff, 0x00000000, 0x00000000}, + {0x4533ff97, 0x00000042, 0xe0d06000, 0xffffffff, 0x000eacff, 0x00000000, 0x9873f21f, 0xf8000466, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x19ffffff, 0x00000000, 0x00000000}, + {0x8b74ff95, 0x00000043, 0xe036d800, 0xffffffff, 0x000ef53f, 0x00000000, 0x42c4f1db, 0xf800047c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1a7fffff, 0x00000000, 0x00000000}, + {0xd1b5ff93, 0x00000044, 0xdf9d5000, 0xffffffff, 0x000f3d7f, 0x00000000, 0xed15f197, 0xf8000491, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1affffff, 0x00000000, 0x00000000}, + {0x17f6ff91, 0x00000046, 0xdf03c800, 0xffffffff, 0x000f85bf, 0x00000000, 0x9766f153, 0xf80004a7, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1b7fffff, 0x00000000, 0x00000000}, + {0x5e37ff8f, 0x00000047, 0xde6a4000, 0xffffffff, 0x000fcdff, 0x00000000, 0x41b7f10f, 0xf80004bd, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1bffffff, 0x00000000, 0x00000000}, + {0xa478ff8d, 0x00000048, 0xddd0b800, 0xffffffff, 0x0010163f, 0x00000000, 0xec08f0cb, 0xf80004d2, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1c7fffff, 0x00000000, 0x00000000}, + {0xeab9ff8b, 0x00000049, 0xdd373000, 0xffffffff, 0x00105e7f, 0x00000000, 0x9659f087, 0xf80004e8, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1cffffff, 0x00000000, 0x00000000}, + {0x30faff89, 0x0000004b, 0xdc9da800, 0xffffffff, 0x0010a6bf, 0x00000000, 0x40aaf043, 0xf80004fe, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1d7fffff, 0x00000000, 0x00000000}, + {0x773bff87, 0x0000004c, 0xdc042000, 0xffffffff, 0x0010eeff, 0x00000000, 0xeafbefff, 0xf8000513, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1dffffff, 0x00000000, 0x00000000}, + {0xbd7cff85, 0x0000004d, 0xdb6a9800, 0xffffffff, 0x0011373f, 0x00000000, 0x954cefbb, 0xf8000529, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1e7fffff, 0x00000000, 0x00000000}, + {0x03bdff83, 0x0000004f, 0xdad11000, 0xffffffff, 0x00117f7f, 0x00000000, 0x3f9def77, 0xf800053f, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1effffff, 0x00000000, 0x00000000}, + {0x49feff81, 0x00000050, 0xda378800, 0xffffffff, 0x0011c7bf, 0x00000000, 0xe9eeef33, 0xf8000554, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1f7fffff, 0x00000000, 0x00000000}, + {0x903fff7f, 0x00000051, 0xd99e0000, 0xffffffff, 0x00120fff, 0x00000000, 0x943feeef, 0xf800056a, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x1fffffff, 0x00000000, 0x00000000}, + {0xd680ff7d, 0x00000052, 0xd9047800, 0xffffffff, 0x0012583f, 0x00000000, 0x3e90eeab, 0xf8000580, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x207fffff, 0x00000000, 0x00000000}, + {0x1cc1ff7b, 0x00000054, 0xd86af000, 0xffffffff, 0x0012a07f, 0x00000000, 0xe8e1ee67, 0xf8000595, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x20ffffff, 0x00000000, 0x00000000}, + {0x6302ff79, 0x00000055, 0xd7d16800, 0xffffffff, 0x0012e8bf, 0x00000000, 0x9332ee23, 0xf80005ab, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x217fffff, 0x00000000, 0x00000000}, + {0xa943ff77, 0x00000056, 0xd737e000, 0xffffffff, 0x001330ff, 0x00000000, 0x3d83eddf, 0xf80005c1, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x21ffffff, 0x00000000, 0x00000000}, + {0xef84ff75, 0x00000057, 0xd69e5800, 0xffffffff, 0x0013793f, 0x00000000, 0xe7d4ed9b, 0xf80005d6, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x227fffff, 0x00000000, 0x00000000}, + {0x35c5ff73, 0x00000059, 0xd604d000, 0xffffffff, 0x0013c17f, 0x00000000, 0x9225ed57, 0xf80005ec, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x22ffffff, 0x00000000, 0x00000000}, + {0x7c06ff71, 0x0000005a, 0xd56b4800, 0xffffffff, 0x001409bf, 0x00000000, 0x3c76ed13, 0xf8000602, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x237fffff, 0x00000000, 0x00000000}, + {0xc247ff6f, 0x0000005b, 0xd4d1c000, 0xffffffff, 0x001451ff, 0x00000000, 0xe6c7eccf, 0xf8000617, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x23ffffff, 0x00000000, 0x00000000}, + {0x0888ff6d, 0x0000005d, 0xd4383800, 0xffffffff, 0x00149a3f, 0x00000000, 0x9118ec8b, 0xf800062d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x247fffff, 0x00000000, 0x00000000}, + {0x4ec9ff6b, 0x0000005e, 0xd39eb000, 0xffffffff, 0x0014e27f, 0x00000000, 0x3b69ec47, 0xf8000643, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x24ffffff, 0x00000000, 0x00000000}, + {0x950aff69, 0x0000005f, 0xd3052800, 0xffffffff, 0x00152abf, 0x00000000, 0xe5baec03, 0xf8000658, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x257fffff, 0x00000000, 0x00000000}, + {0xdb4bff67, 0x00000060, 0xd26ba000, 0xffffffff, 0x001572ff, 0x00000000, 0x900bebbf, 0xf800066e, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x25ffffff, 0x00000000, 0x00000000}, + {0x218cff65, 0x00000062, 0xd1d21800, 0xffffffff, 0x0015bb3f, 0x00000000, 0x3a5ceb7b, 0xf8000684, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x267fffff, 0x00000000, 0x00000000}, + {0x67cdff63, 0x00000063, 0xd1389000, 0xffffffff, 0x0016037f, 0x00000000, 0xe4adeb37, 0xf8000699, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x26ffffff, 0x00000000, 0x00000000}, + {0xae0eff61, 0x00000064, 0xd09f0800, 0xffffffff, 0x00164bbf, 0x00000000, 0x8efeeaf3, 0xf80006af, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x277fffff, 0x00000000, 0x00000000}, + {0xf44fff5f, 0x00000065, 0xd0058000, 0xffffffff, 0x001693ff, 0x00000000, 0x394feaaf, 0xf80006c5, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x27ffffff, 0x00000000, 0x00000000}, + {0x3a90ff5d, 0x00000067, 0xcf6bf800, 0xffffffff, 0x0016dc3f, 0x00000000, 0xe3a0ea6b, 0xf80006da, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x287fffff, 0x00000000, 0x00000000}, + {0x80d1ff5b, 0x00000068, 0xced27000, 0xffffffff, 0x0017247f, 0x00000000, 0x8df1ea27, 0xf80006f0, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x28ffffff, 0x00000000, 0x00000000}, + {0xc712ff59, 0x00000069, 0xce38e800, 0xffffffff, 0x00176cbf, 0x00000000, 0x3842e9e3, 0xf8000706, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x297fffff, 0x00000000, 0x00000000}, + {0x0d53ff57, 0x0000006b, 0xcd9f6000, 0xffffffff, 0x0017b4ff, 0x00000000, 0xe293e99f, 0xf800071b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x29ffffff, 0x00000000, 0x00000000}, + {0x5394ff55, 0x0000006c, 0xcd05d800, 0xffffffff, 0x0017fd3f, 0x00000000, 0x8ce4e95b, 0xf8000731, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2a7fffff, 0x00000000, 0x00000000}, + {0x99d5ff53, 0x0000006d, 0xcc6c5000, 0xffffffff, 0x0018457f, 0x00000000, 0x3735e917, 0xf8000747, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2affffff, 0x00000000, 0x00000000}, + {0xe016ff51, 0x0000006e, 0xcbd2c800, 0xffffffff, 0x00188dbf, 0x00000000, 0xe186e8d3, 0xf800075c, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2b7fffff, 0x00000000, 0x00000000}, + {0x2657ff4f, 0x00000070, 0xcb394000, 0xffffffff, 0x0018d5ff, 0x00000000, 0x8bd7e88f, 0xf8000772, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2bffffff, 0x00000000, 0x00000000}, + {0x6c98ff4d, 0x00000071, 0xca9fb800, 0xffffffff, 0x00191e3f, 0x00000000, 0x3628e84b, 0xf8000788, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2c7fffff, 0x00000000, 0x00000000}, + {0xb2d9ff4b, 0x00000072, 0xca063000, 0xffffffff, 0x0019667f, 0x00000000, 0xe079e807, 0xf800079d, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2cffffff, 0x00000000, 0x00000000}, + {0xf91aff49, 0x00000073, 0xc96ca800, 0xffffffff, 0x0019aebf, 0x00000000, 0x8acae7c3, 0xf80007b3, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2d7fffff, 0x00000000, 0x00000000}, + {0x3f5bff47, 0x00000075, 0xc8d32000, 0xffffffff, 0x0019f6ff, 0x00000000, 0x351be77f, 0xf80007c9, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2dffffff, 0x00000000, 0x00000000}, + {0x859cff45, 0x00000076, 0xc8399800, 0xffffffff, 0x001a3f3f, 0x00000000, 0xdf6ce73b, 0xf80007de, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2e7fffff, 0x00000000, 0x00000000}, + {0xcbddff43, 0x00000077, 0xc7a01000, 0xffffffff, 0x001a877f, 0x00000000, 0x89bde6f7, 0xf80007f4, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2effffff, 0x00000000, 0x00000000}, + {0x121eff41, 0x00000079, 0xc7068800, 0xffffffff, 0x001acfbf, 0x00000000, 0x340ee6b3, 0xf800080a, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x2f7fffff, 0x00000000, 0x00000000}}}; static constexpr storage<8> rou = {0x42f8ef94, 0x6070024f, 0xe11a6161, 0xad187148, 0x9c8b0fa5, 0x3f046451, 0x87529cfa, 0x005282db}; diff --git a/icicle/include/icicle/gate_ops.h b/icicle/include/icicle/gate_ops.h new file mode 100644 index 0000000000..1cde26bc25 --- /dev/null +++ b/icicle/include/icicle/gate_ops.h @@ -0,0 +1,161 @@ +#pragma once + +#include +#include + +#include "errors.h" +#include "runtime.h" + +#include "icicle/fields/field.h" +#include "icicle/utils/utils.h" +#include "icicle/config_extension.h" +#include "icicle/program/program.h" + +namespace icicle { + + /*************************** Frontend APIs ***************************/ + /** + * @brief Configuration for gate operations. + */ + struct GateOpsConfig { + icicleStreamHandle stream; /** Stream for asynchronous execution. */ + bool is_constants_on_device; /** True if `constants` is on the device. Default: false. */ + bool is_fixed_on_device; /** True if `fixed` columns are on the device. Default: false. */ + bool is_advice_on_device; /** True if `advice` columns are on the device. Default: false. */ + bool is_instance_on_device; /** True if `instance` columns are on the device. Default: false. */ + bool is_rotations_on_device; /** True if `rotations` array is on the device. Default: false. */ + bool is_challenges_on_device; /** True if `challenges` array is on the device. Default: false. */ + bool is_calculations_on_device; /** True if `calculations` array is on the device. Default: false. */ + bool is_previous_value_on_device; /** True if `previous_value` array is on the device. Default: false. */ + bool is_horners_on_device; /** True if `horners` array is on the device. Default: false. */ + bool is_result_on_device; /** True to keep results on device. Default: false. */ + bool is_async; /** Async execution flag. Default: false. */ + }; + + + struct LookupConfig { + icicleStreamHandle stream; /** Stream for asynchronous execution. */ + bool is_table_values_on_device; /** True if `table_values` columns are on the device. Default: false. */ + bool is_inputs_prods_on_device; /** True if `inputs_prods` is on the device. Default: false. */ + bool is_inputs_inv_sums_on_device; /** True if `inputs_inv_sums` is on the device. Default: false. */ + bool is_coset_on_device; /** True if `phi_coset` and `m_coset` columns are on the device. Default: false. */ + bool is_l_on_device; /** True if `l0`, `l_last` and `l_active_row` columns are on the device. Default: false. */ + bool is_y_on_device; /** True if `y` array is on the device. Default: false. */ + bool is_previous_value_on_device; /** True if `previous_value` array is on the device. Default: false. */ + bool is_result_on_device; /** True to keep results on device. Default: false. */ + bool is_async; + }; + + struct HornerData { + const uint32_t* value_types; // Value types for Horner's method + const uint32_t* value_indices; // Source indices for Horner's method + const uint32_t* offsets; // Horner offsets + const uint32_t* sizes; // Horner sizes + uint32_t num_horner; + }; + + template + struct CalculationData { + const uint32_t* calc_types; // Array for calculation types (e.g., Add, Sub, Mul, etc.) + const uint32_t* targets; // Source value types (e.g., beta, advice, etc.) + const uint32_t* value_types; // Source value types (e.g., beta, advice, etc.) + const uint32_t* value_indices; // Source value indices + const T* constants; // Constants array + uint32_t num_constants; // Number of constants + const int32_t* rotations; // Rotations array + uint32_t num_rotations; // Number of rotations + const T* previous_value; + uint32_t num_calculations; // Number of calculations + uint32_t num_intermediates; // Number of intermediate values + uint32_t num_elements; + uint32_t rot_scale; // Rotation scale + uint32_t i_size; // Size of i + }; + + template + struct GateData { + const T* fixed; // Fixed columns array + uint32_t num_fixed_columns; // Number of fixed columns + uint32_t num_fixed_rows; // Number of fixed columns + const T* advice; // Advice columns array + uint32_t num_advice_columns; // Number of advice columns + uint32_t num_advice_rows; // Number of advice columns + const T* instance; // Instance columns array + uint32_t num_instance_columns; // Number of instance columns + uint32_t num_instance_rows; // Number of instance columns + const T* challenges; // Challenges array + uint32_t num_challenges; // Number of challenges + const T* beta; + const T* gamma; + const T* theta; + const T* y; + }; + + template + struct LookupData { + const T* table_values; + uint32_t num_table_values; + const T* inputs_prods; + uint32_t num_inputs_prods; + const T* inputs_inv_sums; + uint32_t num_inputs_inv_sums; + const T* phi_coset; + uint32_t num_phi_coset; + const T* m_coset; + uint32_t num_m_coset; + const T* l0; + uint32_t num_l0; + const T* l_last; + uint32_t num_l_last; + const T* l_active_row; + uint32_t num_l_active_row; + const T* y; + const T* previous_value; + uint32_t num_elements; + uint32_t rot_scale; + uint32_t i_size; + }; + + /** + * @brief Returns the default value of GateOpsConfig. + */ + static GateOpsConfig default_gate_ops_config() + { + return GateOpsConfig{ + nullptr, // stream + false, // is_constants_on_device + false, // is_fixed_on_device + false, // is_advice_on_device + false, // is_instance_on_device + false, // is_rotations_on_device + false, // is_challenges_on_device + false, // is_calculations_on_device + false, // is_horners_on_device + false, // is_result_on_device + false // is_async + }; + } + + /** + * @brief Evaluate the gates with full parameter set + */ + template + eIcicleError gate_evaluation( + const GateData& gate_data, + const CalculationData& calc_data, + const HornerData& horner_data, + const GateOpsConfig& config, + T* results + ); + + /** + * @brief Evaluate the lookups constraints with full parameter set + */ + template + eIcicleError lookups_constraint( + const LookupData& gate_data, + const LookupConfig& config, + T* results + ); + +} // namespace icicle \ No newline at end of file diff --git a/icicle/include/icicle/vec_ops.h b/icicle/include/icicle/vec_ops.h index f5f7895eff..007a76022f 100644 --- a/icicle/include/icicle/vec_ops.h +++ b/icicle/include/icicle/vec_ops.h @@ -135,6 +135,25 @@ namespace icicle { template eIcicleError vector_mul(const T* vec_a, const T* vec_b, uint64_t size, const VecOpsConfig& config, T* output); + /** + * @brief Mul Accumulates the elements of two vectors element-wise and stores the result in the first vector. + * + * @tparam T Type of the elements in the vectors. + * @param vec_a Pointer to the first Input/output vector(s). The result will be written back to this vector. + * - If `config.batch_size > 1`, this should be a concatenated array of vectors. + * - The layout depends on `config.columns_batch`: + * - If `false`, vectors are stored contiguously in memory. + * - If `true`, vectors are stored as columns in a 2D array. + * @param vec_b Pointer to the second input vector(s). + * - The storage layout should match that of `vec_a`. + * @param size Number of elements in each vector. + * @param config Configuration for the operation. + * @return eIcicleError Error code indicating success or failure. + */ + template + eIcicleError + vector_mul_accumulate(T* vec_a, const T* vec_b, uint64_t size, const VecOpsConfig& config); // use vector_mul (inplace) + /** * @brief Multiplies two vectors element-wise. * @@ -193,6 +212,23 @@ namespace icicle { template eIcicleError vector_inv(const T* vec_a, uint64_t size, const VecOpsConfig& config, T* output); + + /** + * @brief Invert vector `a` element-wise inplace. + * + * @tparam T Type of the elements in the vectors. + * @param vec_a Pointer to the first input vector(s). + * - If `config.batch_size > 1`, this should be a concatenated array of vectors. + * - The layout depends on `config.columns_batch`: + * - If `false`, vectors are stored contiguously in memory. + * - If `true`, vectors are stored as columns in a 2D array. + * @param size Number of elements in each vector. + * @param config Configuration for the operation. + * @return eIcicleError Error code indicating success or failure. + */ + template + eIcicleError vector_inplace_inv(T* vec_a, uint64_t size, const VecOpsConfig& config); + /** * @brief Converts elements to and from Montgomery form. * diff --git a/icicle/src/device_api.cpp b/icicle/src/device_api.cpp index 25ecc9c966..4050800efb 100644 --- a/icicle/src/device_api.cpp +++ b/icicle/src/device_api.cpp @@ -80,7 +80,7 @@ namespace icicle { bool is_device_registered(const char* device_type) { return apiMap.find(device_type) != apiMap.end(); } - Device m_default_device{"", -1}; + Device m_default_device{"CUDA", 0}; }; DeviceTracker DeviceAPI::sMemTracker; diff --git a/icicle/src/gate_ops.cpp b/icicle/src/gate_ops.cpp new file mode 100644 index 0000000000..b8088c3f3d --- /dev/null +++ b/icicle/src/gate_ops.cpp @@ -0,0 +1,66 @@ +#include "icicle/backend/gate_ops_backend.h" +#include "icicle/dispatcher.h" + +namespace icicle { + + /*********************************** EVALUATE ************************/ + ICICLE_DISPATCHER_INST(GateEvaluationDispatcher, gate_evaluation, gateEvaluationImpl); + ICICLE_DISPATCHER_INST(LookupsConstraintDispatcher, lookups_constraint, lookupsConstraintImpl); + + extern "C" eIcicleError CONCAT_EXPAND(FIELD, gate_evaluation)( + const GateData* gate_data, + const CalculationData* calc_data, + const HornerData* horner_data, + const GateOpsConfig* config, + scalar_t* results) + { + return GateEvaluationDispatcher::execute( + *gate_data, + *calc_data, + *horner_data, + *config, + results + ); + } + + extern "C" eIcicleError CONCAT_EXPAND(FIELD, lookups_constraint)( + const LookupData* lookup_data, + const LookupConfig* config, + scalar_t* results) + { + return LookupsConstraintDispatcher::execute( + *lookup_data, + *config, + results + ); + } + + eIcicleError gate_evaluation( + const GateData& gate_data, + const CalculationData& calc_data, + const HornerData& horner_data, + const GateOpsConfig& config, + scalar_t* results) + { + return CONCAT_EXPAND(FIELD, gate_evaluation)( + &gate_data, + &calc_data, + &horner_data, + &config, + results + ); + } + + eIcicleError lookups_constraint( + const LookupData& lookup_data, + const LookupConfig& config, + scalar_t* results) + { + return CONCAT_EXPAND(FIELD, lookups_constraint)( + &lookup_data, + &config, + results + ); + } + +} diff --git a/icicle/src/vec_ops.cpp b/icicle/src/vec_ops.cpp index 7799fd0cc4..489afa60db 100644 --- a/icicle/src/vec_ops.cpp +++ b/icicle/src/vec_ops.cpp @@ -179,6 +179,22 @@ namespace icicle { return CONCAT_EXPAND(FIELD, vector_mul)(vec_a, vec_b, size, &config, output); } + /*********************************** MUL ACCUMULATE ***********************************/ + ICICLE_DISPATCHER_INST(VectorMulAccumulateDispatcher, vector_mul_accumulate, vectorVectorOpImplInplaceA); + + extern "C" eIcicleError CONCAT_EXPAND(FIELD, vector_mul_accumulate)( + scalar_t* vec_a, const scalar_t* vec_b, uint64_t size, const VecOpsConfig* config) + { + return VectorMulAccumulateDispatcher::execute(vec_a, vec_b, size, *config); + } + + template <> + eIcicleError vector_mul_accumulate(scalar_t* vec_a, const scalar_t* vec_b, uint64_t size, const VecOpsConfig& config) + { + return CONCAT_EXPAND(FIELD, vector_mul_accumulate)(vec_a, vec_b, size, &config); + } + + #ifdef EXT_FIELD ICICLE_DISPATCHER_INST(VectorMulExtFieldDispatcher, extension_vector_mul, extFieldVectorOpImpl); @@ -275,6 +291,21 @@ namespace icicle { } #endif // EXT_FIELD + /*********************************** INPLACE INV ***********************************/ + ICICLE_DISPATCHER_INST(VectorInplaceInvDispatcher, vector_inplace_inv, VectorOpImplInplaceA); + + extern "C" eIcicleError + CONCAT_EXPAND(FIELD, vector_inplace_inv)(scalar_t* vec_a, uint64_t size, const VecOpsConfig* config) + { + return VectorInplaceInvDispatcher::execute(vec_a, size, *config); + } + + template <> + eIcicleError vector_inplace_inv(scalar_t* vec_a, uint64_t size, const VecOpsConfig& config) + { + return CONCAT_EXPAND(FIELD, vector_inplace_inv)(vec_a, size, &config); + } + /*********************************** (Scalar + Vector) ELEMENT WISE ***********************************/ ICICLE_DISPATCHER_INST(ScalarAddDispatcher, scalar_add_vec, scalarVectorOpImpl); diff --git a/icicle/tests/test_field_api.cpp b/icicle/tests/test_field_api.cpp index c0450bfe29..4fdc9331a3 100644 --- a/icicle/tests/test_field_api.cpp +++ b/icicle/tests/test_field_api.cpp @@ -52,6 +52,7 @@ TYPED_TEST_SUITE(FieldApiTest, FTImplementations); // Note: this is testing host arithmetic. Other tests against CPU backend should guarantee correct device arithmetic too TYPED_TEST(FieldApiTest, FieldSanityTest) { + icicle_set_device("CPU"); // Use CPU only for now. auto a = TypeParam::rand_host(); auto b = TypeParam::rand_host(); auto b_inv = TypeParam::inverse(b); @@ -65,6 +66,68 @@ TYPED_TEST(FieldApiTest, FieldSanityTest) ASSERT_EQ(a * scalar_t::from(2), a + a); } +#ifndef EXT_FIELD +TYPED_TEST(FieldApiTest, FieldStorageReduceSanityTest) +{ + /* + SR - storage reduce + check that: + 1. SR(x1) + SR(x1) = SR(x1+x2) + 2. SR(INV(SR(x))*x) = 1 + */ + START_TIMER(StorageSanity) + for (int i = 0; i < 1000; i++) { + if constexpr (TypeParam::TLC == 1) { + storage<18> a = // 18 because we support up to 576 bits + TypeParam::template rand_storage<18>(17); // 17 so we don't have carry after addition + storage<18> b = TypeParam::template rand_storage<18>(17); // 17 so we don't have carry after addition + storage<18> sum = {}; + const storage<3> c = + TypeParam::template rand_storage<3>(); // 3 because we don't support higher odd number of limbs yet + storage<4> product = {}; + base_math::template add_sub_limbs<18, false, false, true>(a, b, sum); + auto c_red = TypeParam::from(c); + auto c_inv = TypeParam::inverse(c_red); + base_math::multiply_raw<3, 1, true>( + c, c_inv.limbs_storage, product); // using 32-bit multiplication for small fields + ASSERT_EQ(TypeParam::from(a) + TypeParam::from(b), TypeParam::from(sum)); + ASSERT_EQ(TypeParam::from(product), TypeParam::one()); + std::byte* a_bytes = reinterpret_cast(a.limbs); + std::byte* b_bytes = reinterpret_cast(b.limbs); + std::byte* sum_bytes = reinterpret_cast(sum.limbs); + std::byte* product_bytes = reinterpret_cast(product.limbs); + ASSERT_EQ(TypeParam::from(a), TypeParam::from(a_bytes, 18 * 4)); + ASSERT_EQ( + TypeParam::from(a_bytes, 18 * 4) + TypeParam::from(b_bytes, 18 * 4), TypeParam::from(sum_bytes, 18 * 4)); + ASSERT_EQ(TypeParam::from(product_bytes, 4 * 4), TypeParam::one()); + } else { + storage<18> a = // 18 because we support up to 576 bits + TypeParam::template rand_storage<18>(17); // 17 so we don't have carry after addition + storage<18> b = TypeParam::template rand_storage<18>(17); // 17 so we don't have carry after addition + storage<18> sum = {}; + const storage<18 - TypeParam::TLC> c = + TypeParam::template rand_storage<18 - TypeParam::TLC>(); // -TLC so we don't overflow in multiplication + storage<18> product = {}; + base_math::template add_sub_limbs<18, false, false, true>(a, b, sum); + auto c_red = TypeParam::from(c); + auto c_inv = TypeParam::inverse(c_red); + base_math::multiply_raw(c, c_inv.limbs_storage, product); + ASSERT_EQ(TypeParam::from(a) + TypeParam::from(b), TypeParam::from(sum)); + ASSERT_EQ(TypeParam::from(product), TypeParam::one()); + std::byte* a_bytes = reinterpret_cast(a.limbs); + std::byte* b_bytes = reinterpret_cast(b.limbs); + std::byte* sum_bytes = reinterpret_cast(sum.limbs); + std::byte* product_bytes = reinterpret_cast(product.limbs); + ASSERT_EQ(TypeParam::from(a), TypeParam::from(a_bytes, 18 * 4)); + ASSERT_EQ( + TypeParam::from(a_bytes, 18 * 4) + TypeParam::from(b_bytes, 18 * 4), TypeParam::from(sum_bytes, 18 * 4)); + ASSERT_EQ(TypeParam::from(product_bytes, 18 * 4), TypeParam::one()); + } + } + END_TIMER(StorageSanity, "storage sanity", true); +} +#endif + TYPED_TEST(FieldApiTest, vectorVectorOps) { const uint64_t N = 1 << rand_uint_32b(3, 17); @@ -1192,6 +1255,7 @@ TEST_F(FieldApiTestBase, ProgramExecutorVecOpDataOnDevice) TEST_F(FieldApiTestBase, Sumcheck) { + icicle_set_device("CPU"); // Use CPU only for now. int log_mle_poly_size = 13; int mle_poly_size = 1 << log_mle_poly_size; int nof_mle_poly = 4; @@ -1242,4 +1306,4 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -} \ No newline at end of file +} diff --git a/icicle/tests/test_hash_api.cpp b/icicle/tests/test_hash_api.cpp index 860e42e358..52e920896d 100644 --- a/icicle/tests/test_hash_api.cpp +++ b/icicle/tests/test_hash_api.cpp @@ -8,6 +8,7 @@ #include "icicle/hash/keccak.h" #include "icicle/hash/blake2s.h" #include "icicle/hash/blake3.h" +#include "icicle/hash/poseidon2.h" #include "icicle/merkle/merkle_tree.h" #include "icicle/fields/field.h" @@ -1149,49 +1150,310 @@ TEST_F(HashApiTest, poseidon_tree) #endif // POSEIDON #ifdef POSEIDON2 -// p = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 - + // DEBUG. This test could run only with bn254 curve. Dont remove!!! + // bn254: p = 0x303b6f7c86d043bfcbcc80214f26a30277a15d3f74ca654992defe7ff8d03570 #include "icicle/fields/field_config.h" - using namespace field_config; +TEST_F(HashApiTest, poseidon2_3_single_hasher) +{ + const unsigned t = 3; + auto config = default_hash_config(); + config.batch = 1; - #include "icicle/hash/poseidon2.h" + auto input = std::make_unique(config.batch * t); + // for (int i = 0; i < config.batch * t; i++) { + // input[i] = scalar_t::from(i % t); + // } + scalar_t::rand_host_many(input.get(), t * config.batch); + // for (int i = 0; i < config.batch * t; i++) { + // std::cout << "poseidon2_3_single_hasher input " << input[i] << std::endl; + // } -// // DEBUG. This test could run only with bn254 curve. Dont remove!!! -// bn254: p = 0x303b6f7c86d043bfcbcc80214f26a30277a15d3f74ca654992defe7ff8d03570 -// TEST_F(HashApiTest, poseidon2_3_single_hash_cpu_only) -// { -// const unsigned t = 3; -// auto config = default_hash_config(); -// config.batch = 1 << 10; + auto run = [&](const std::string& dev_type, scalar_t* out, bool measure, const char* msg, int iters) { + Device dev = {dev_type, 0}; + icicle_set_device(dev); -// auto input = std::make_unique(t); -// scalar_t::rand_host_many(input.get(), t); + std::ostringstream oss; + oss << dev_type << " " << msg; -// auto run = [&](const std::string& dev_type, scalar_t* out, bool measure, const char* msg, int iters) { -// Device dev = {dev_type, 0}; -// icicle_set_device(dev); + auto poseidon2 = Poseidon2::create(t); -// std::ostringstream oss; -// oss << dev_type << " " << msg; + START_TIMER(POSEIDON2_sync) + for (int i = 0; i < iters; ++i) { + ICICLE_CHECK(poseidon2.hash(input.get(), t, config, out)); + } + END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); + }; -// auto poseidon2 = Poseidon2::create(t); + std::cout << "Run CPU only test " << std::endl; + auto output_cpu = std::make_unique(config.batch); + run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + // #if FIELD_ID == BN254 + // scalar_t expected_res = + // scalar_t::hex_str2scalar("0x303b6f7c86d043bfcbcc80214f26a30277a15d3f74ca654992defe7ff8d03570"); + // ASSERT_EQ(expected_res, *(output_cpu.get())); + // #endif + + if (IcicleTestBase::main_device() == "CUDA") { + std::cout << "Run CUDA test " << std::endl; + auto output_mainDev = std::make_unique(config.batch); + run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); + std::cout << "End CUDA test " << std::endl; + } +} // poseidon2_3_single_hasher -// START_TIMER(POSEIDON2_sync) -// for (int i = 0; i < iters; ++i) { -// ICICLE_CHECK(poseidon2.hash(input.get(), t, config, out)); -// } -// END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); -// }; +// Test used to generate expected result of any hasher ccording to the parameters inside. +TEST_F(HashApiTest, poseidon2_3_gen_hasher_expected_result_cpu_only) +{ + #if FIELD_ID == BN254 + const unsigned t = 3; + auto config = default_hash_config(); + config.batch = 1; -// auto output_cpu = std::make_unique(config.batch); + auto input = std::make_unique(t); + input[0] = scalar_t::hex_str2scalar("0x00e6997915531bf1cdb5d90acacc4a14d0960a3de8ac56b520de319b627db7bf"); + // input[1] = scalar_t::hex_str2scalar("0x17e49ca947671143af1f5038d0ed615d4db68cb2b475b00fb253a1f0886a80c0"); + // input[2] = scalar_t::hex_str2scalar("0x0001e7319635c0fdeabf4dbc8c539c296682a0c9260a8f457b3565e49299d308"); + // input[3] = scalar_t::hex_str2scalar("0x1aa6c65a496292747d2667b5e72a3521637b4d4d8dbc99d0b555696c1cdb9a34"); + // input[0] = scalar_t::from(4); + input[1] = scalar_t::from(7); + input[2] = scalar_t::from(8); + // input[3] = scalar_t::from(7); + // for (int i = 0; i < t; i++) { + // std::cout << "poseidon2_3_gen_hasher_expected_result_cpu_only input " << input[i] << std::endl; + // } -// run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); -// scalar_t expected_res = -// scalar_t::hex_str2scalar("0x303b6f7c86d043bfcbcc80214f26a30277a15d3f74ca654992defe7ff8d03570"); std::cout << "End -// of test\n" << std::endl; ASSERT_EQ(expected_res, *(output_cpu.get())); -// } -// // DEBUG + auto run = [&](const std::string& dev_type, scalar_t* out, bool measure, const char* msg, int iters) { + Device dev = {dev_type, 0}; + icicle_set_device(dev); + + std::ostringstream oss; + oss << dev_type << " " << msg; + + auto poseidon2 = Poseidon2::create(t); + + START_TIMER(POSEIDON2_sync) + for (int i = 0; i < iters; ++i) { + ICICLE_CHECK(poseidon2.hash(input.get(), t, config, out)); + } + END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); + }; + + auto output_cpu = std::make_unique(config.batch); + run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + #endif +} // poseidon2_3_gen_hasher_expected_result_cpu_only + +// Sponge, chain of 2 hashers, no padding, no domain tag. +TEST_F(HashApiTest, poseidon2_3_sponge_2_hashers_without_dt) +{ + const unsigned t = 3; + auto config = default_hash_config(); + int nof_hashers = 2; + int nof_inputs = 1 + nof_hashers * (t - 1); + + auto input = std::make_unique(nof_inputs); + // for (int i = 0; i < t; i++) { // First hasher has t inputs. + // input[i] = scalar_t::from(i); + // } + // for (int hasher_idx = 1; hasher_idx < nof_hashers; hasher_idx++) { + // for (int i = 1; i < t; i++) { // Non-first hashers have t-1 inputs. + // input[hasher_idx * (t - 1) + i] = scalar_t::from(i); + // } + // } + scalar_t::rand_host_many(input.get(), nof_inputs); + // for (int i = 0; i < t + (nof_hashers-1) * (t-1); i++) { + // std::cout << "poseidon2_3_sponge_2_hashers_without_dt input " << input[i] << std::endl; + // } + + auto run = [&](const std::string& dev_type, scalar_t* out, bool measure, const char* msg, int iters) { + Device dev = {dev_type, 0}; + icicle_set_device(dev); + + std::ostringstream oss; + oss << dev_type << " " << msg; + + auto poseidon2 = Poseidon2::create(t); + + START_TIMER(POSEIDON2_sync) + for (int i = 0; i < iters; ++i) { + ICICLE_CHECK(poseidon2.hash(input.get(), t + (nof_hashers - 1) * (t - 1), config, out)); + } + END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); + }; + + std::cout << "Run CPU test " << std::endl; + auto output_cpu = std::make_unique(config.batch); // config.batch = 1 here. + run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + // #if FIELD_ID == BN254 + // scalar_t expected_res = + // scalar_t::hex_str2scalar("0x0d54b4b71781dc4f30afe3a90f76559379f6f75aea6968d4c986512e2711ad20"); + // ASSERT_EQ(expected_res, *(output_cpu.get())); + // #endif + + std::string main_device = IcicleTestBase::main_device(); + if (IcicleTestBase::main_device() == "CUDA") { + std::cout << "Run CUDA test " << std::endl; + auto output_mainDev = std::make_unique(config.batch); + run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); + } +} // poseidon2_3_sponge_2_hashers_without_dt + +// Sponge, chain of 2 hashers, no padding, with domain tag. +TEST_F(HashApiTest, poseidon2_3_sponge_2_hashers_with_dt) +{ + const unsigned t = 3; + auto config = default_hash_config(); + const scalar_t domain_tag = scalar_t::from(4); + std::cout << "poseidon2_3_sponge_2_hashers_with_dt domain_tag " << domain_tag << std::endl; + int nof_hashers = 2; + int nof_valid_inputs = 4; + + // Input will be 4,5,6,8. + // With dt and padding it will be 4,5,6,7,8,1,0. + auto input = std::make_unique(nof_valid_inputs); + // for (int i = 0; i < nof_valid_inputs; i++) { // First hasher has t inputs. + // input[i] = scalar_t::from(5 + i); + // } + scalar_t::rand_host_many(input.get(), nof_valid_inputs); + // for (int i = 0; i < nof_valid_inputs; i++) { + // std::cout << "poseidon2_3_sponge_2_hashers_with_dt input " << input[i] << std::endl; + // } + + auto run = [&](const std::string& dev_type, scalar_t* out, bool measure, const char* msg, int iters) { + Device dev = {dev_type, 0}; + icicle_set_device(dev); + + std::ostringstream oss; + oss << dev_type << " " << msg; + + auto poseidon2 = Poseidon2::create(t, &domain_tag); + + START_TIMER(POSEIDON2_sync) + for (int i = 0; i < iters; ++i) { + ICICLE_CHECK(poseidon2.hash(input.get(), nof_valid_inputs, config, out)); + } + END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); + }; + + std::cout << "Run CPU test " << std::endl; + auto output_cpu = std::make_unique(config.batch); // config.batch = 1 here. + run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + // #if FIELD_ID == BN254 + // scalar_t expected_res = + // scalar_t::hex_str2scalar("0x286786cd695dbe838456c72a5edb4d2717a17a0971006671c26c0219c3de5abe"); + // ASSERT_EQ(expected_res, *(output_cpu.get())); + // #endif + + if (IcicleTestBase::main_device() == "CUDA") { + std::cout << "Run CUDA test " << std::endl; + auto output_mainDev = std::make_unique(config.batch); + run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); + } +} // poseidon2_3_sponge_2_hashers_with_dt + +// Sponge, chain of 1 hasher, with padding (2 scalars 1,0), no domain tag. +TEST_F(HashApiTest, poseidon2_3_sponge_1_hasher_without_dt_with_padding) +{ + const unsigned t = 4; + auto config = default_hash_config(); + int nof_hashers = 1; + int nof_valid_inputs = 2; + + auto input = std::make_unique(nof_valid_inputs); + // for (int i = 0; i < nof_valid_inputs; i++) { // First hasher has t inputs. + // input[i] = scalar_t::from(4 + i); // Valid inputs are 4,5 + // } + scalar_t::rand_host_many(input.get(), nof_valid_inputs); + // for (int i = 0; i < nof_valid_inputs; i++) { + // std::cout << "poseidon2_3_sponge_1_hasher_without_dt_with_padding input " << input[i] << std::endl; + // } + + auto run = [&](const std::string& dev_type, scalar_t* out, bool measure, const char* msg, int iters) { + Device dev = {dev_type, 0}; + icicle_set_device(dev); + + std::ostringstream oss; + oss << dev_type << " " << msg; + + auto poseidon2 = Poseidon2::create(t); + + START_TIMER(POSEIDON2_sync) + for (int i = 0; i < iters; ++i) { + ICICLE_CHECK(poseidon2.hash(input.get(), nof_valid_inputs, config, out)); + } + END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); + }; + + std::cout << "Run CPU test " << std::endl; + auto output_cpu = std::make_unique(config.batch); // config.batch = 1 here. + run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + // #if FIELD_ID == BN254 + // scalar_t expected_res = + // scalar_t::hex_str2scalar("0x2645a6e432f38bb4f197b1b4a69d6fac977cdb4927cfbb62f133a9e427dee146"); + // ASSERT_EQ(expected_res, *(output_cpu.get())); + // #endif + + if (IcicleTestBase::main_device() == "CUDA") { + std::cout << "Run CUDA test " << std::endl; + auto output_mainDev = std::make_unique(config.batch); + run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); + } +} // poseidon2_3_sponge_1_hasher_without_dt_with_padding + +// Sponge, chain of 2 hashers, with padding (2 scalars 1,0), no domain tag. +TEST_F(HashApiTest, poseidon2_4_sponge_2_hashers_without_dt_with_padding) +{ + const unsigned t = 4; + auto config = default_hash_config(); + int nof_hashers = 2; + int nof_valid_inputs = 5; + + auto input = std::make_unique(nof_valid_inputs); + // for (int i = 0; i < nof_valid_inputs; i++) { // First hasher has t inputs. + // input[i] = scalar_t::from(4 + i); // Valid inputs are 4,5 + // } + scalar_t::rand_host_many(input.get(), nof_valid_inputs); + // for (int i = 0; i < nof_valid_inputs; i++) { + // std::cout << "poseidon2_4_sponge_2_hashers_without_dt_with_padding input " << input[i] << std::endl; + // } + + auto run = [&](const std::string& dev_type, scalar_t* out, bool measure, const char* msg, int iters) { + Device dev = {dev_type, 0}; + icicle_set_device(dev); + + std::ostringstream oss; + oss << dev_type << " " << msg; + + auto poseidon2 = Poseidon2::create(t); + + START_TIMER(POSEIDON2_sync) + for (int i = 0; i < iters; ++i) { + ICICLE_CHECK(poseidon2.hash(input.get(), nof_valid_inputs, config, out)); + } + END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); + }; + + std::cout << "Run CPU test " << std::endl; + auto output_cpu = std::make_unique(config.batch); // config.batch = 1 here. + run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + // #if FIELD_ID == BN254 + // scalar_t expected_res = + // scalar_t::hex_str2scalar("0x0353fae9638ef80c9a80786ce24c42d6e087695a40cd5ca29207f20b72f25379"); + // ASSERT_EQ(expected_res, *(output_cpu.get())); + // #endif + + if (IcicleTestBase::main_device() == "CUDA") { + std::cout << "Run CUDA test " << std::endl; + auto output_mainDev = std::make_unique(config.batch); + run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); + } +} // poseidon2_4_sponge_2_hashers_without_dt_with_padding // Test check single hash without domain tag. TEST_F(HashApiTest, poseidon2_3_single_hash_without_dt) @@ -1202,6 +1464,17 @@ TEST_F(HashApiTest, poseidon2_3_single_hash_without_dt) auto input = std::make_unique(t * config.batch); scalar_t::rand_host_many(input.get(), t * config.batch); + // // DEBUG - sets known inputs. Do not remove!!! + // input[0] = scalar_t::hex_str2scalar("0x0bb61d24daca55eebcb1929a82650f328134334da98ea4f847f760054f4a3033"); + // input[1] = scalar_t::hex_str2scalar("0x303b6f7c86d043bfcbcc80214f26a30277a15d3f74ca654992defe7ff8d03571"); + // input[2] = scalar_t::hex_str2scalar("0x1ed25194542b12eef8617361c3ba7c52e660b145994427cc86296242cf766eca"); + // // for (int i=1; i(nof_valid_inputs); + scalar_t::rand_host_many(input.get(), nof_valid_inputs); + // // DEBUG - sets known inputs. Do not remove!!! + // for (int i=0; i(t); + + START_TIMER(POSEIDON2_sync) + for (int i = 0; i < iters; ++i) { + ICICLE_CHECK(poseidon2.hash(input.get(), 1 + nof_hashers * (t - 1), config, out)); + } + END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); + }; + + auto output_cpu = std::make_unique(1); + auto output_mainDev = std::make_unique(1); + + run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + + ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); + int a = 5; +} // poseidon2_3_sponge_hash_2_without_dt + +TEST_F(HashApiTest, poseidon2_3_sponge_hash_1K_without_dt) +{ + const unsigned t = 3; + auto config = default_hash_config(); + int nof_hashers = 1 << 10; + int nof_valid_inputs = 1 + nof_hashers * (t - 1); + + auto input = std::make_unique(nof_valid_inputs); + scalar_t::rand_host_many(input.get(), nof_valid_inputs); + // // DEBUG - sets known inputs. Do not remove!!! + // for (int i=0; i(t); + + ICICLE_CHECK(poseidon2.hash(input.get(), 1 + nof_hashers * (t - 1), config, out)); + START_TIMER(POSEIDON2_sync) + for (int i = 0; i < iters; ++i) { + ICICLE_CHECK(poseidon2.hash(input.get(), 1 + nof_hashers * (t - 1), config, out)); + } + END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); + }; + + auto output_cpu = std::make_unique(1); + auto output_mainDev = std::make_unique(1); + + run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); + + ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); + int a = 5; +} // poseidon2_3_sponge_hash_1K_without_dt TEST_F(HashApiTest, poseidon2_invalid_t) { @@ -1240,7 +1612,7 @@ TEST_F(HashApiTest, poseidon2_invalid_t) auto output = std::make_unique(config.batch); scalar_t::rand_host_many(input.get(), t * config.batch); - const bool large_field = sizeof(scalar_t) > 4; + const bool large_field = sizeof(scalar_t) > 8; for (const auto& device : s_registered_devices) { icicle_set_device(device); @@ -1297,8 +1669,6 @@ TEST_F(HashApiTest, poseidon2_3_batch_without_dt_debug) const unsigned t = 3; auto config = default_hash_config(); config.batch = 1 << 10; - std::cout << "poseidon2_3_batch_without_dt_debug: t = %d\n" << t << std::endl; - std::cout << "poseidon2_3_batch_without_dt_debug: config.batch = %d\n" << config.batch << std::endl; auto input = std::make_unique(t * config.batch); scalar_t::rand_host_many(input.get(), t * config.batch); @@ -1307,7 +1677,7 @@ TEST_F(HashApiTest, poseidon2_3_batch_without_dt_debug) // input[i] = scalar_t::from(i % t); // } // for (int i = 0; i < config.batch * t; i++) { - // std::cout << "poseidon2_3_batch_without_dt input " << input[i] << std::endl; + // std::cout << "poseidon2_3_batch_without_dt_debug input " << input[i] << std::endl; // } // // DEBUG @@ -1323,7 +1693,7 @@ TEST_F(HashApiTest, poseidon2_3_batch_without_dt_debug) START_TIMER(POSEIDON2_sync) for (int i = 0; i < iters; ++i) { - std::cout << "poseidon2_3_batch_without_dt: t = " << std::dec << t << std::endl; + std::cout << "poseidon2_3_batch_without_dt_debug: t = " << std::dec << t << std::endl; ICICLE_CHECK(poseidon2.hash(input.get(), t, config, out)); } END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); @@ -1335,10 +1705,6 @@ TEST_F(HashApiTest, poseidon2_3_batch_without_dt_debug) run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); - std::cout << "output_cpu[" << config.batch - 2 << "] = " << output_cpu.get()[config.batch - 2] << std::endl; - std::cout << "output_mainDev[" << config.batch - 2 << "] = " << output_mainDev.get()[config.batch - 2] << std::endl; - std::cout << "output_cpu[" << config.batch - 1 << "] = " << output_cpu.get()[config.batch - 1] << std::endl; - std::cout << "output_mainDev[" << config.batch - 1 << "] = " << output_mainDev.get()[config.batch - 1] << std::endl; ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); } @@ -1363,7 +1729,6 @@ TEST_F(HashApiTest, poseidon2_3_batch_without_dt) START_TIMER(POSEIDON2_sync) for (int i = 0; i < iters; ++i) { - std::cout << "poseidon2_3_batch_without_dt: t = " << std::dec << t << std::endl; ICICLE_CHECK(poseidon2.hash(input.get(), t, config, out)); } END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); @@ -1378,41 +1743,6 @@ TEST_F(HashApiTest, poseidon2_3_batch_without_dt) ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); } -// Danny TODO - to add tree test with diff T's for the levels. -// TEST_F(HashApiTest, poseidon2_3x2_to_2x1_two_level_tree_no_dt) -// { -// const unsigned t = 3; -// auto config = default_hash_config(); - -// config.batch = 1 << 10; -// auto input = std::make_unique(t * config.batch); -// scalar_t::rand_host_many(input.get(), t * config.batch); - -// auto run = [&](const std::string& dev_type, scalar_t* out, bool measure, const char* msg, int iters) { -// std::cout << "iters = " << iters << std::endl; -// Device dev = {dev_type, 0}; -// icicle_set_device(dev); - -// std::ostringstream oss; -// oss << dev_type << " " << msg; - -// auto poseidon2 = Poseidon2::create(t); - -// START_TIMER(POSEIDON2_sync) -// for (int i = 0; i < iters; ++i) { -// ICICLE_CHECK(poseidon2.hash(input.get(), t, config, out)); -// } -// END_TIMER(POSEIDON2_sync, oss.str().c_str(), measure); -// }; - -// auto output_cpu = std::make_unique(config.batch); -// auto output_mainDev = std::make_unique(config.batch); - -// run(IcicleTestBase::reference_device(), output_cpu.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); -// run(IcicleTestBase::main_device(), output_mainDev.get(), VERBOSE /*=measure*/, "poseidon2", ITERS); - -// ASSERT_EQ(0, memcmp(output_cpu.get(), output_mainDev.get(), config.batch * sizeof(scalar_t))); -// } #endif // POSEIDON2 #ifdef SUMCHECK @@ -1463,4 +1793,5 @@ TEST_F(SumcheckTest, InitializeWithByteVector) EXPECT_TRUE(config.is_little_endian()); EXPECT_EQ(config.get_seed_rng(), seed); } -#endif // SUMCHECK \ No newline at end of file +#endif // SUMCHECK + // \ No newline at end of file diff --git a/wrappers/rust/icicle-core/src/gate_ops/mod.rs b/wrappers/rust/icicle-core/src/gate_ops/mod.rs new file mode 100644 index 0000000000..0d9b82332d --- /dev/null +++ b/wrappers/rust/icicle-core/src/gate_ops/mod.rs @@ -0,0 +1,446 @@ +use crate::traits::FieldImpl; +use icicle_runtime::{ + errors::eIcicleError, memory::HostOrDeviceSlice, stream::IcicleStreamHandle, +}; + +pub mod tests; + +#[repr(C)] +#[derive(Debug, Clone)] +pub struct GateOpsConfig { + pub stream_handle: IcicleStreamHandle, + pub is_constants_on_device: bool, + pub is_fixed_on_device: bool, + pub is_advice_on_device: bool, + pub is_instance_on_device: bool, + pub is_rotations_on_device: bool, + pub is_challenges_on_device: bool, + pub is_calculations_on_device: bool, + pub is_previous_value_on_device: bool, + pub is_horners_on_device: bool, + pub is_result_on_device: bool, + pub is_async: bool, +} + +impl GateOpsConfig { + pub fn default() -> Self { + Self { + stream_handle: std::ptr::null_mut(), + is_constants_on_device: false, + is_fixed_on_device: false, + is_advice_on_device: false, + is_instance_on_device: false, + is_rotations_on_device: false, + is_challenges_on_device: false, + is_calculations_on_device: false, + is_previous_value_on_device: false, + is_horners_on_device: false, + is_result_on_device: false, + is_async: false, + } + } +} + +#[repr(C)] +#[derive(Debug, Clone)] +pub struct LookupConfig { + pub stream_handle: IcicleStreamHandle, + pub is_table_values_on_device: bool, + pub is_inputs_prods_on_device: bool, + pub is_inputs_inv_sums_on_device: bool, + pub is_coset_on_device: bool, + pub is_l_on_device: bool, + pub is_y_on_device: bool, + pub is_previous_value_on_device: bool, + pub is_result_on_device: bool, + pub is_async: bool, +} + +impl LookupConfig { + pub fn default() -> Self { + Self { + stream_handle: std::ptr::null_mut(), + is_table_values_on_device: false, + is_inputs_prods_on_device: false, + is_inputs_inv_sums_on_device: false, + is_coset_on_device: false, + is_l_on_device: false, + is_y_on_device: false, + is_previous_value_on_device: false, + is_result_on_device: false, + is_async: false, + } + } +} + +#[repr(C)] +#[derive(Debug, Clone)] +pub struct LookupData { + pub table_values: *const T, + pub num_table_values: u32, + pub inputs_prods: *const T, + pub num_inputs_prods: u32, + pub inputs_inv_sums: *const T, + pub num_inputs_inv_sums: u32, + pub phi_coset: *const T, + pub num_phi_coset: u32, + pub m_coset: *const T, + pub num_m_coset: u32, + pub l0: *const T, + pub num_l0: u32, + pub l_last: *const T, + pub num_l_last: u32, + pub l_active_row: *const T, + pub num_l_active_row: u32, + pub y: *const T, + pub previous_value: *const T, + pub num_elements: u32, + pub rot_scale: u32, + pub i_size: u32, +} + +impl LookupData { + pub fn new( + table_values: *const T, + num_table_values: u32, + inputs_prods: *const T, + num_inputs_prods: u32, + inputs_inv_sums: *const T, + num_inputs_inv_sums: u32, + phi_coset: *const T, + num_phi_coset: u32, + m_coset: *const T, + num_m_coset: u32, + l0: *const T, + num_l0: u32, + l_last: *const T, + num_l_last: u32, + l_active_row: *const T, + num_l_active_row: u32, + y: *const T, + previous_value: *const T, + num_elements: u32, + rot_scale: u32, + i_size: u32, + ) -> Self { + Self { + table_values, + num_table_values, + inputs_prods, + num_inputs_prods, + inputs_inv_sums, + num_inputs_inv_sums, + phi_coset, + num_phi_coset, + m_coset, + num_m_coset, + l0, + num_l0, + l_last, + num_l_last, + l_active_row, + num_l_active_row, + y, + previous_value, + num_elements, + rot_scale, + i_size, + } + } +} + +#[repr(C)] +#[derive(Debug, Clone)] +pub struct HornerData { + pub value_types: *const u32, + pub value_indices: *const u32, + pub offsets: *const u32, + pub sizes: *const u32, + pub num_horner: u32, +} + +impl HornerData { + pub fn new( + value_types: *const u32, + value_indices: *const u32, + offsets: *const u32, + sizes: *const u32, + num_horner: u32, + ) -> Self { + Self { + value_types, + value_indices, + offsets, + sizes, + num_horner + } + } +} + +#[repr(C)] +#[derive(Debug, Clone)] +pub struct CalculationData { + pub calc_types: *const u32, + pub targets: *const u32, + pub value_types: *const u32, + pub value_indices: *const u32, + pub constants: *const T, + pub num_constants: u32, + pub rotations: *const i32, + pub num_rotations: u32, + pub previous_value: *const T, + pub num_calculations: u32, + pub num_intermediates: u32, + pub num_elements: u32, + pub rot_scale: u32, + pub i_size: u32, +} + +impl CalculationData { + pub fn new( + calc_types: *const u32, + targets: *const u32, + value_types: *const u32, + value_indices: *const u32, + constants: *const T, + num_constants: u32, + rotations: *const i32, + num_rotations: u32, + previous_value: *const T, + num_calculations: u32, + num_intermediates: u32, + num_elements: u32, + rot_scale: u32, + i_size: u32, + ) -> Self { + Self { + calc_types, + targets, + value_types, + value_indices, + constants, + num_constants, + rotations, + num_rotations, + previous_value, + num_calculations, + num_intermediates, + num_elements, + rot_scale, + i_size, + } + } +} + +#[repr(C)] +#[derive(Debug, Clone)] +pub struct GateData { + pub fixed: *const T, + pub num_fixed_columns: u32, + pub num_fixed_rows: u32, + pub advice: *const T, + pub num_advice_columns: u32, + pub num_advice_rows: u32, + pub instance: *const T, + pub num_instance_columns: u32, + pub num_instance_rows: u32, + pub challenges: *const T, + pub num_challenges: u32, + pub beta: *const T, + pub gamma: *const T, + pub theta: *const T, + pub y: *const T, +} + +impl GateData { + pub fn new( + fixed: *const T, + num_fixed_columns: u32, + num_fixed_rows: u32, + advice: *const T, + num_advice_columns: u32, + num_advice_rows: u32, + instance: *const T, + num_instance_columns: u32, + num_instance_rows: u32, + challenges: *const T, + num_challenges: u32, + beta: *const T, + gamma: *const T, + theta: *const T, + y: *const T, + ) -> Self { + Self { + fixed, + num_fixed_columns, + num_fixed_rows, + advice, + num_advice_columns, + num_advice_rows, + instance, + num_instance_columns, + num_instance_rows, + challenges, + num_challenges, + beta, + gamma, + theta, + y, + } + } +} + +#[doc(hidden)] +pub trait GateOps { + fn gate_evaluation( + gate_data: &GateData, + calc_data: &CalculationData, + horner_data: &HornerData, + result: &mut (impl HostOrDeviceSlice + ?Sized), + cfg: &GateOpsConfig, + ) -> Result<(), eIcicleError>; + + fn lookups_constraint( + lookup_data: &LookupData, + result: &mut (impl HostOrDeviceSlice + ?Sized), + cfg: &LookupConfig, + ) -> Result<(), eIcicleError>; +} + +pub fn gate_evaluation( + gate_data: &GateData, + calc_data: &CalculationData, + horner_data: &HornerData, + result: &mut (impl HostOrDeviceSlice + ?Sized), + cfg: &GateOpsConfig, +) -> Result<(), eIcicleError> +where + F: FieldImpl, + ::Config: GateOps, +{ + <::Config as GateOps>::gate_evaluation( + gate_data, + calc_data, + horner_data, + result, + &cfg, + ) +} + +pub fn lookups_constraint( + lookup_data: &LookupData, + result: &mut (impl HostOrDeviceSlice + ?Sized), + cfg: &LookupConfig, +) -> Result<(), eIcicleError> +where + F: FieldImpl, + ::Config: GateOps, +{ + <::Config as GateOps>::lookups_constraint( + lookup_data, + result, + &cfg, + ) +} + +#[macro_export] +macro_rules! impl_gate_ops_field { + ( + $field_prefix:literal, + $field_prefix_ident:ident, + $field:ident, + $field_config:ident + ) => { + mod $field_prefix_ident { + + use crate::gate_ops::{$field, HostOrDeviceSlice}; + use icicle_core::gate_ops::{GateData, CalculationData, HornerData, LookupData, GateOpsConfig, LookupConfig}; + use icicle_runtime::errors::eIcicleError; + + extern "C" { + #[link_name = concat!($field_prefix, "_gate_evaluation")] + pub(crate) fn gate_evaluation_ffi( + gate_data: *const GateData<$field>, + calc_data: *const CalculationData<$field>, + horner_data: *const HornerData, + cfg: *const GateOpsConfig, + result: *mut $field, + ) -> eIcicleError; + + #[link_name = concat!($field_prefix, "_lookups_constraint")] + pub(crate) fn lookups_constraint_ffi( + lookup_data: *const LookupData<$field>, + cfg: *const LookupConfig, + result: *mut $field, + ) -> eIcicleError; + } + } + + impl GateOps<$field> for $field_config { + fn gate_evaluation( + gate_data: &GateData<$field>, + calc_data: &CalculationData<$field>, + horner_data: &HornerData, + result: &mut (impl HostOrDeviceSlice<$field> + ?Sized), + cfg: &GateOpsConfig, + ) -> Result<(), eIcicleError> { + unsafe { + $field_prefix_ident::gate_evaluation_ffi( + gate_data as *const GateData<$field>, + calc_data as *const CalculationData<$field>, + horner_data as *const HornerData, + cfg as *const GateOpsConfig, + result.as_mut_ptr(), + ) + .wrap() + } + } + + fn lookups_constraint( + lookup_data: &LookupData<$field>, + result: &mut (impl HostOrDeviceSlice<$field> + ?Sized), + cfg: &LookupConfig, + ) -> Result<(), eIcicleError> { + unsafe { + $field_prefix_ident::lookups_constraint_ffi( + lookup_data as *const LookupData<$field>, + cfg as *const LookupConfig, + result.as_mut_ptr(), + ) + .wrap() + } + } + } + }; +} + +#[macro_export] +macro_rules! impl_gate_ops_tests { + ( + $field:ident + ) => { + pub(crate) mod test_gateops { + use super::*; + use icicle_runtime::test_utilities; + use icicle_runtime::{device::Device, runtime}; + use std::sync::Once; + + fn initialize() { + test_utilities::test_load_and_init_devices(); + test_utilities::test_set_main_device(); + } + + #[test] + pub fn test_gate_ops_scalars() { + initialize(); + check_gate_ops_scalars::<$field>() + } + + #[test] + pub fn test_lookup_constraints_scalars() { + initialize(); + check_lookup_constraints_scalars::<$field>() + } + } + }; +} diff --git a/wrappers/rust/icicle-core/src/gate_ops/tests.rs b/wrappers/rust/icicle-core/src/gate_ops/tests.rs new file mode 100644 index 0000000000..13911bdbd1 --- /dev/null +++ b/wrappers/rust/icicle-core/src/gate_ops/tests.rs @@ -0,0 +1,474 @@ +#![allow(unused_imports)] +use crate::traits::GenerateRandom; +use crate::gate_ops::{gate_evaluation, lookups_constraint, GateOps, GateOpsConfig, GateData, CalculationData, HornerData, LookupConfig, LookupData, FieldImpl}; +use icicle_runtime::device::Device; +use icicle_runtime::memory::{DeviceVec, HostSlice, HostOrDeviceSlice}; +use icicle_runtime::{runtime, stream::IcicleStream, test_utilities}; +use rand::Rng; + +#[test] +fn test_gate_ops_config() { + let mut gate_ops_config = GateOpsConfig::default(); + gate_ops_config + .ext + .set_int("int_example", 5); + + assert_eq!( + gate_ops_config + .ext + .get_int("int_example"), + 5 + ); + + + let mut stream = IcicleStream::create().unwrap(); + gate_ops_config.stream_handle = *stream; + + stream + .synchronize() + .unwrap(); +} + +pub fn check_gate_ops_scalars() +where + ::Config: GateOps + GenerateRandom, +{ + check_horner_evaluation::(4096); + // check_ezkl_gate_ops::(2^25); +} + +pub fn check_lookup_constraints_scalars() +where + ::Config: GateOps + GenerateRandom, +{ + check_sample_lookup_constraints::(1); +} + +pub fn check_sample_lookup_constraints(_test_size: usize) +where + ::Config: GateOps + GenerateRandom, +{ + let table_values = vec![ + F::from_u32(2u32), + ]; + + let inputs_prods = vec![ + F::from_u32(2u32), + ]; + + let inputs_inv_sums = vec![ + F::from_u32(2u32), + ]; + + let phi_coset = vec![ + F::from_u32(2u32), + ]; + + let m_coset = vec![ + F::from_u32(2u32), + ]; + + let l0 = vec![ + F::from_u32(2u32), + ]; + + let l_last = vec![ + F::from_u32(2u32), + ]; + + let l_active_row = vec![ + F::from_u32(2u32), + ]; + + let previous_value = vec![ + F::from_u32(2u32), + ]; + + let y = vec![ + F::from_u32(2u32), + ]; + + let rot_scale = 1; + let i_size = 1; + + let lookup_data = LookupData::new( + table_values.as_ptr(), + table_values.len() as u32, + table_values.as_ptr(), + inputs_prods.len() as u32, + inputs_inv_sums.as_ptr(), + inputs_inv_sums.len() as u32, + phi_coset.as_ptr(), + phi_coset.len() as u32, + m_coset.as_ptr(), + m_coset.len() as u32, + l0.as_ptr(), + l0.len() as u32, + l_last.as_ptr(), + l_last.len() as u32, + l_active_row.as_ptr(), + l_active_row.len() as u32, + y.as_ptr(), + previous_value.as_ptr(), + previous_value.len() as u32, + rot_scale as u32, + i_size as u32, + ); + + let mut values = vec![ F::from_u32(0u32) ]; + let h_values = HostSlice::from_mut_slice(&mut values[..]); + let mut cfg = LookupConfig::default(); + cfg.is_result_on_device = false; + + lookups_constraint(&lookup_data, h_values, &cfg).unwrap(); + + println!("h_values: {:?}", h_values); +} + +pub fn check_horner_evaluation(test_size: usize) +where + ::Config: GateOps + GenerateRandom, +{ + let table_size = 8; + + let constants = vec![ + F::from_u32(5u32), + F::from_u32(7u32), + F::from_u32(100u32), + F::from_u32(200u32), + ]; + let fixed = vec![ + F::from_u32(11u32), + F::from_u32(11u32), + F::from_u32(11u32), + F::from_u32(11u32), + ]; + let advice = vec![ + F::from_u32(13u32), + F::from_u32(13u32), + F::from_u32(13u32), + F::from_u32(13u32), + ]; + + let instance = vec![ + F::from_u32(13u32), + F::from_u32(13u32), + F::from_u32(13u32), + F::from_u32(13u32), + ]; + let challenges = F::Config::generate_random(1); + + let beta = F::Config::generate_random(1); + let gamma = F::Config::generate_random(1); + let theta = F::Config::generate_random(1); + let y = F::Config::generate_random(1); + let previous_value = F::Config::generate_random(1); + + let rotations: Vec = vec![0]; + let calculations: Vec = vec![6, 7]; + let targets: Vec = vec![0, 1]; + let value_types: Vec = vec![0, 0, 1, 1]; + let value_indices: Vec = vec![0, 0, 1, 0, 0, 0, 0, 0]; + + // calc[0] = horner(constants[0], constants[1], [fixed[0][0], advice[0][0]]) -> target[0] + // calc[1] = store(intermediates[0]) -> target[1] + + let horner_offsets: Vec = vec![0, 0]; + let horner_sizes: Vec = vec![2, 0]; + let horner_value_types: Vec = vec![2, 3]; + let horner_value_indices: Vec = vec![0, 0, 0, 0]; + + let gate_data = GateData::new( + fixed.as_ptr(), + 1, + table_size as u32, + advice.as_ptr(), + 1, + table_size as u32, + instance.as_ptr(), + 1, + table_size as u32, + challenges.as_ptr(), + challenges.len() as u32, + beta.as_ptr(), + gamma.as_ptr(), + theta.as_ptr(), + y.as_ptr(), + ); + + let calc_data = CalculationData::new( + calculations.as_ptr(), + targets.as_ptr(), + value_types.as_ptr(), + value_indices.as_ptr(), + constants.as_ptr(), + constants.len() as u32, + rotations.as_ptr(), + rotations.len() as u32, + previous_value.as_ptr(), + calculations.len() as u32, + 2, + test_size as u32, + 1, + 2, + ); + + let horner_data = HornerData::new( + horner_value_types.as_ptr(), + horner_value_indices.as_ptr(), + horner_offsets.as_ptr(), + horner_sizes.as_ptr(), + horner_value_types.len() as u32, + ); + + let mut result = vec![F::zero(); test_size]; + let result_slice = HostSlice::from_mut_slice(&mut result); + + test_utilities::test_set_main_device(); + + let cfg = GateOpsConfig::default(); + + gate_evaluation( + &gate_data, + &calc_data, + &horner_data, + result_slice, + &cfg, + ) + .unwrap(); + + let expected = F::from_u32(335u32); + assert_eq!(result[0], expected, "Horner test did not match expected value"); + + println!("result: {:?}", result); +} + +pub fn check_complex_gate_ops(test_size: usize) +where + ::Config: GateOps + GenerateRandom, +{ + let table_size = 8; + + let constants = vec![ + F::from_u32(5), + F::from_u32(7), + F::from_u32(3), + F::from_u32(200), + ]; + + let fixed = vec![ + F::from_u32(11), + F::from_u32(111), + F::from_u32(111), + F::from_u32(111), + F::from_u32(111), + F::from_u32(111), + F::from_u32(111), + F::from_u32(111), + ]; + + let advice = vec![ + F::from_u32(13), + F::from_u32(113), + F::from_u32(113), + F::from_u32(113), + F::from_u32(113), + F::from_u32(113), + F::from_u32(113), + F::from_u32(113), + ]; + + let instance = vec![ + F::from_u32(17), + F::from_u32(117), + F::from_u32(117), + F::from_u32(117), + F::from_u32(117), + F::from_u32(117), + F::from_u32(117), + F::from_u32(117), + ]; + + let challenges = vec![F::from_u32(19)]; + + let beta = vec![F::from_u32(101)]; + let gamma = vec![F::from_u32(102)]; + let theta = vec![F::from_u32(103)]; + let y = vec![F::from_u32(104)]; + let previous_value = vec![F::from_u32(105)]; + + let rotations = vec![0]; + + let calculations = vec![0, 2, 3, 4, 7, 6]; + let targets = vec![0, 1, 2, 3, 4, 5]; + let value_types = vec![0, 0, 2, 3, 1, 1, 1, 1, 1, 1, 1, 0]; + let value_indices = vec![0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 2, 0, 4, 0, 2, 0]; + + let mut horner_offsets = vec![0; 6]; + let mut horner_sizes = vec![0; 6]; + horner_offsets[5] = 0; + horner_sizes[5] = 2; + let horner_value_types = vec![4, 5]; + let horner_value_indices = vec![0, 0, 0, 0]; + + // Build the GateData: + let gate_data = GateData::new( + fixed.as_ptr(), + 1, + table_size as u32, + advice.as_ptr(), + 1, + table_size as u32, + instance.as_ptr(), + 1, + table_size as u32, + challenges.as_ptr(), + challenges.len() as u32, + beta.as_ptr(), + gamma.as_ptr(), + theta.as_ptr(), + y.as_ptr(), + ); + + let calc_data = CalculationData::new( + calculations.as_ptr(), + targets.as_ptr(), + value_types.as_ptr(), + value_indices.as_ptr(), + constants.as_ptr(), + constants.len() as u32, + rotations.as_ptr(), + rotations.len() as u32, + previous_value.as_ptr(), + calculations.len() as u32, + 6, + test_size as u32, + 1, + 6, + ); + + let horner_data = HornerData::new( + horner_value_types.as_ptr(), + horner_value_indices.as_ptr(), + horner_offsets.as_ptr(), + horner_sizes.as_ptr(), + horner_value_types.len() as u32, + ); + + let mut result = vec![F::zero(); test_size]; + let result_slice = HostSlice::from_mut_slice(&mut result); + + test_utilities::test_set_main_device(); + let cfg = GateOpsConfig::default(); + + gate_evaluation(&gate_data, &calc_data, &horner_data, result_slice, &cfg) + .expect("Gate evaluation failed"); + + let expected = F::from_u32(1366); + assert_eq!(result_slice[0], expected, "Final result mismatch!"); +} + +pub fn check_ezkl_gate_ops(test_size: usize) +where + ::Config: GateOps + GenerateRandom, +{ + let constants = vec![ + F::from_u32(0), + F::from_u32(1), + F::from_u32(2), + F::from_u32(3), + ]; + + let fixed = vec![F::from_u32(1); 19 * 1048576]; + let advice = vec![F::from_u32(1); 6 * 1048576]; + let instance = vec![F::from_u32(1); 1 * 1048576]; + + let challenges = vec![]; + + let beta = vec![F::from_u32(1)]; + let gamma = vec![F::from_u32(1)]; + let theta = vec![F::from_u32(1)]; + let y = vec![F::from_u32(1)]; + let previous_value = vec![F::from_u32(0); test_size]; + + let rotations = vec![0, -1]; + + let calculations = vec![7, 1, 2, 1, 2, 7, 7, 7, 0, 1, 2, 7, 1, 2, 1, 2, 7, 7, 7, 0, 1, 2, 1, 2, 2, 2, 1, 2, 7, 1, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 1, 1, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 7, 1, 2, 7, 0, 0, 1, 2, 2, 1, 2, 7, 1, 2, 1, 2, 2, 1, 2, 1, 2, 2, 1, 2, 1, 2, 2, 0, 1, 2, 2, 0, 1, 2, 6]; + let targets = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]; + let value_types = vec![2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 0, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 9]; + let value_indices = vec![14, 0, 14, 0, 2, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 2, 0, 2, 0, 6, 0, 7, 0, 5, 0, 8, 0, 4, 0, 9, 0, 15, 0, 15, 0, 1, 0, 11, 0, 11, 0, 12, 0, 3, 0, 11, 0, 13, 0, 14, 0, 5, 0, 5, 0, 1, 0, 1, 0, 3, 0, 3, 0, 17, 0, 18, 0, 16, 0, 19, 0, 15, 0, 20, 0, 1, 0, 0, 0, 0, 0, 22, 0, 1, 0, 23, 0, 6, 0, 7, 0, 5, 0, 25, 0, 24, 0, 26, 0, 16, 0, 16, 0, 2, 0, 28, 0, 28, 0, 29, 0, 3, 0, 28, 0, 30, 0, 31, 0, 17, 0, 18, 0, 16, 0, 33, 0, 32, 0, 34, 0, 3, 0, 23, 0, 6, 0, 7, 0, 5, 0, 37, 0, 36, 0, 38, 0, 2, 0, 11, 0, 13, 0, 40, 0, 17, 0, 18, 0, 16, 0, 42, 0, 41, 0, 43, 0, 11, 0, 40, 0, 14, 0, 45, 0, 5, 0, 1, 0, 5, 0, 47, 0, 46, 0, 48, 0, 1, 0, 28, 0, 28, 0, 50, 0, 31, 0, 51, 0, 16, 0, 1, 0, 16, 0, 53, 0, 52, 0, 54, 0, 17, 0, 17, 0, 2, 0, 56, 0, 56, 0, 57, 0, 4, 1, 4, 1, 25, 0, 33, 0, 59, 0, 60, 0, 5, 0, 61, 0, 58, 0, 62, 0, 29, 0, 51, 0, 5, 0, 60, 0, 64, 0, 65, 0, 18, 0, 18, 0, 2, 0, 67, 0, 67, 0, 68, 0, 3, 0, 67, 0, 69, 0, 70, 0, 7, 0, 18, 0, 5, 0, 72, 0, 71, 0, 73, 0, 1, 0, 56, 0, 56, 0, 75, 0, 59, 0, 72, 0, 5, 0, 77, 0, 76, 0, 78, 0, 1, 0, 67, 0, 67, 0, 80, 0, 68, 0, 81, 0, 7, 0, 18, 0, 5, 0, 83, 0, 82, 0, 84, 0, 70, 0, 81, 0, 59, 0, 83, 0, 5, 0, 87, 0, 86, 0, 88, 0, 0, 0, 0, 0]; + + let horner_value_types = vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; + let horner_value_indices = vec![10, 0, 21, 0, 27, 0, 35, 0, 39, 0, 44, 0, 49, 0, 55, 0, 63, 0, 66, 0, 74, 0, 79, 0, 85, 0, 89, 0]; + let horner_offsets = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let horner_sizes = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14]; + + // println!("calculations: {:?}", calculations); + // println!("targets: {:?}", targets); + // println!("value_types: {:?}", value_types); + // println!("value_indices: {:?}", value_indices); + // println!("rotations: {:?}", rotations); + // println!("horner_value_types: {:?}", horner_value_types); + // println!("horner_value_indices: {:?}", horner_value_indices); + // println!("horner_offsets: {:?}", horner_offsets); + // println!("horner_sizes: {:?}", horner_sizes); + + // Build the GateData: + let gate_data = GateData::new( + fixed.as_ptr(), + 19, + 1048576, + advice.as_ptr(), + 6, + 1048576, + instance.as_ptr(), + 1, + 1048576, + challenges.as_ptr(), + 0, + beta.as_ptr(), + gamma.as_ptr(), + theta.as_ptr(), + y.as_ptr(), + ); + + let calc_data = CalculationData::new( + calculations.as_ptr(), + targets.as_ptr(), + value_types.as_ptr(), + value_indices.as_ptr(), + constants.as_ptr(), + constants.len() as u32, + rotations.as_ptr(), + rotations.len() as u32, + previous_value.as_ptr(), + calculations.len() as u32, + targets.len() as u32, + test_size as u32, + 4, + 1048576, + ); + + let horner_data = HornerData::new( + horner_value_types.as_ptr(), + horner_value_indices.as_ptr(), + horner_offsets.as_ptr(), + horner_sizes.as_ptr(), + horner_value_types.len() as u32, + ); + + println!("gate_data: {:?}", gate_data); + println!("calc_data: {:?}", calc_data); + println!("horner_data: {:?}", horner_data); + + let mut result = vec![F::zero(); test_size]; + let result_slice = HostSlice::from_mut_slice(&mut result); + + test_utilities::test_set_main_device(); + let cfg = GateOpsConfig::default(); + + gate_evaluation(&gate_data, &calc_data, &horner_data, result_slice, &cfg) + .expect("Gate evaluation failed"); + + println!("result_slice: {:?}", result_slice); +} \ No newline at end of file diff --git a/wrappers/rust/icicle-core/src/lib.rs b/wrappers/rust/icicle-core/src/lib.rs index fbf32a4ed7..b8fc400421 100644 --- a/wrappers/rust/icicle-core/src/lib.rs +++ b/wrappers/rust/icicle-core/src/lib.rs @@ -10,6 +10,7 @@ pub mod poseidon; pub mod poseidon2; pub mod sumcheck; pub mod vec_ops; +pub mod gate_ops; #[doc(hidden)] pub mod tests; diff --git a/wrappers/rust/icicle-core/src/vec_ops/mod.rs b/wrappers/rust/icicle-core/src/vec_ops/mod.rs index c0fa2b1e54..10ccb99ff1 100644 --- a/wrappers/rust/icicle-core/src/vec_ops/mod.rs +++ b/wrappers/rust/icicle-core/src/vec_ops/mod.rs @@ -62,6 +62,12 @@ pub trait VecOps { cfg: &VecOpsConfig, ) -> Result<(), eIcicleError>; + fn mul_accumulate( + a: &mut (impl HostOrDeviceSlice + ?Sized), + b: &(impl HostOrDeviceSlice + ?Sized), + cfg: &VecOpsConfig, + ) -> Result<(), eIcicleError>; + fn div( a: &(impl HostOrDeviceSlice + ?Sized), b: &(impl HostOrDeviceSlice + ?Sized), @@ -75,6 +81,11 @@ pub trait VecOps { cfg: &VecOpsConfig, ) -> Result<(), eIcicleError>; + fn inplace_inv( + a: &(impl HostOrDeviceSlice + ?Sized), + cfg: &VecOpsConfig, + ) -> Result<(), eIcicleError>; + fn sum( a: &(impl HostOrDeviceSlice + ?Sized), result: &mut (impl HostOrDeviceSlice + ?Sized), @@ -349,6 +360,19 @@ where <::Config as VecOps>::mul(a, b, result, &cfg) } +pub fn mul_accumulate( + a: &mut (impl HostOrDeviceSlice + ?Sized), + b: &(impl HostOrDeviceSlice + ?Sized), + cfg: &VecOpsConfig, +) -> Result<(), eIcicleError> +where + F: FieldImpl, + ::Config: VecOps, +{ + let cfg = check_vec_ops_args(a, b, a, cfg); + <::Config as VecOps>::mul_accumulate(a, b, &cfg) +} + pub fn mixed_mul_scalars( a: &(impl HostOrDeviceSlice + ?Sized), b: &(impl HostOrDeviceSlice + ?Sized), @@ -390,6 +414,18 @@ where <::Config as VecOps>::inv(a, result, &cfg) } +pub fn inplace_inv_scalars( + a: &(impl HostOrDeviceSlice + ?Sized), + cfg: &VecOpsConfig, +) -> Result<(), eIcicleError> +where + F: FieldImpl, + ::Config: VecOps, +{ + let cfg = check_vec_ops_args(a, a, a, cfg); + <::Config as VecOps>::inplace_inv(a, &cfg) +} + pub fn sum_scalars( a: &(impl HostOrDeviceSlice + ?Sized), result: &mut (impl HostOrDeviceSlice + ?Sized), @@ -565,6 +601,14 @@ macro_rules! impl_vec_ops_field { result: *mut $field, ) -> eIcicleError; + #[link_name = concat!($field_prefix, "_vector_mul_accumulate")] + pub(crate) fn vector_mul_accumulate_ffi( + a: *const $field, + b: *const $field, + size: u32, + cfg: *const VecOpsConfig, + ) -> eIcicleError; + #[link_name = concat!($field_prefix, "_vector_div")] pub(crate) fn vector_div_ffi( a: *const $field, @@ -582,6 +626,13 @@ macro_rules! impl_vec_ops_field { result: *mut $field, ) -> eIcicleError; + #[link_name = concat!($field_prefix, "_vector_inplace_inv")] + pub(crate) fn vector_inplace_inv_ffi( + a: *const $field, + size: u32, + cfg: *const VecOpsConfig, + ) -> eIcicleError; + #[link_name = concat!($field_prefix, "_vector_sum")] pub(crate) fn vector_sum_ffi( a: *const $field, @@ -726,6 +777,22 @@ macro_rules! impl_vec_ops_field { } } + fn mul_accumulate( + a: &mut (impl HostOrDeviceSlice<$field> + ?Sized), + b: &(impl HostOrDeviceSlice<$field> + ?Sized), + cfg: &VecOpsConfig, + ) -> Result<(), eIcicleError> { + unsafe { + $field_prefix_ident::vector_mul_accumulate_ffi( + a.as_ptr(), + b.as_ptr(), + a.len() as u32, + cfg as *const VecOpsConfig, + ) + .wrap() + } + } + fn div( a: &(impl HostOrDeviceSlice<$field> + ?Sized), b: &(impl HostOrDeviceSlice<$field> + ?Sized), @@ -760,6 +827,20 @@ macro_rules! impl_vec_ops_field { } } + fn inplace_inv( + a: &(impl HostOrDeviceSlice<$field> + ?Sized), + cfg: &VecOpsConfig, + ) -> Result<(), eIcicleError> { + unsafe { + $field_prefix_ident::vector_inplace_inv_ffi( + a.as_ptr(), + a.len() as u32, + cfg as *const VecOpsConfig, + ) + .wrap() + } + } + fn sum( a: &(impl HostOrDeviceSlice<$field> + ?Sized), result: &mut (impl HostOrDeviceSlice<$field> + ?Sized), diff --git a/wrappers/rust/icicle-core/src/vec_ops/tests.rs b/wrappers/rust/icicle-core/src/vec_ops/tests.rs index d6a44b5a91..8c07c941ce 100644 --- a/wrappers/rust/icicle-core/src/vec_ops/tests.rs +++ b/wrappers/rust/icicle-core/src/vec_ops/tests.rs @@ -1,7 +1,7 @@ #![allow(unused_imports)] use crate::traits::GenerateRandom; use crate::vec_ops::{ - accumulate_scalars, add_scalars, bit_reverse, bit_reverse_inplace, div_scalars, inv_scalars, mixed_mul_scalars, mul_scalars, + accumulate_scalars, add_scalars, bit_reverse, bit_reverse_inplace, div_scalars, inv_scalars, inplace_inv_scalars, mixed_mul_scalars, mul_scalars, product_scalars, scalar_add, scalar_mul, scalar_sub, slice, sub_scalars, sum_scalars, transpose_matrix, FieldImpl, MixedVecOps, VecOps, VecOpsConfig, }; diff --git a/wrappers/rust/icicle-curves/icicle-bls12-377/src/gate_ops/mod.rs b/wrappers/rust/icicle-curves/icicle-bls12-377/src/gate_ops/mod.rs new file mode 100644 index 0000000000..f0a0d753ef --- /dev/null +++ b/wrappers/rust/icicle-curves/icicle-bls12-377/src/gate_ops/mod.rs @@ -0,0 +1,16 @@ +use crate::curve::{ScalarCfg, ScalarField}; +use icicle_core::{ + impl_gate_ops_field, + gate_ops::{GateOps, GateOpsConfig}, +}; +use icicle_runtime::{errors::eIcicleError, memory::HostOrDeviceSlice}; + +impl_gate_ops_field!("bls12_377", bls12_377, ScalarField, ScalarCfg); +#[cfg(test)] +pub(crate) mod tests { + use crate::curve::ScalarField; + use icicle_core::impl_gate_ops_tests; + use icicle_core::gate_ops::tests::*; + + impl_gate_ops_tests!(ScalarField); +} diff --git a/wrappers/rust/icicle-curves/icicle-bls12-377/src/lib.rs b/wrappers/rust/icicle-curves/icicle-bls12-377/src/lib.rs index 194117cbce..5fa01aeb14 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-377/src/lib.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-377/src/lib.rs @@ -5,6 +5,7 @@ pub mod polynomials; pub mod poseidon; pub mod poseidon2; pub mod vec_ops; +pub mod gate_ops; #[cfg(not(feature = "no_ecntt"))] pub mod ecntt; diff --git a/wrappers/rust/icicle-curves/icicle-bls12-381/src/gate_ops/mod.rs b/wrappers/rust/icicle-curves/icicle-bls12-381/src/gate_ops/mod.rs new file mode 100644 index 0000000000..ef8754149b --- /dev/null +++ b/wrappers/rust/icicle-curves/icicle-bls12-381/src/gate_ops/mod.rs @@ -0,0 +1,16 @@ +use crate::curve::{ScalarCfg, ScalarField}; +use icicle_core::{ + impl_gate_ops_field, + gate_ops::{GateOps, GateOpsConfig, HornerData, CalculationData, GateData}, +}; +use icicle_runtime::{errors::eIcicleError, memory::HostOrDeviceSlice}; + +impl_gate_ops_field!("bls12_381", bls12_381, ScalarField, ScalarCfg); +#[cfg(test)] +pub(crate) mod tests { + use crate::curve::ScalarField; + use icicle_core::impl_gate_ops_tests; + use icicle_core::gate_ops::tests::*; + + impl_gate_ops_tests!(ScalarField); +} diff --git a/wrappers/rust/icicle-curves/icicle-bls12-381/src/lib.rs b/wrappers/rust/icicle-curves/icicle-bls12-381/src/lib.rs index 194117cbce..5fa01aeb14 100644 --- a/wrappers/rust/icicle-curves/icicle-bls12-381/src/lib.rs +++ b/wrappers/rust/icicle-curves/icicle-bls12-381/src/lib.rs @@ -5,6 +5,7 @@ pub mod polynomials; pub mod poseidon; pub mod poseidon2; pub mod vec_ops; +pub mod gate_ops; #[cfg(not(feature = "no_ecntt"))] pub mod ecntt; diff --git a/wrappers/rust/icicle-curves/icicle-bn254/src/gate_ops/mod.rs b/wrappers/rust/icicle-curves/icicle-bn254/src/gate_ops/mod.rs new file mode 100644 index 0000000000..5e47acaa01 --- /dev/null +++ b/wrappers/rust/icicle-curves/icicle-bn254/src/gate_ops/mod.rs @@ -0,0 +1,16 @@ +use crate::curve::{ScalarCfg, ScalarField}; +use icicle_core::{ + impl_gate_ops_field, + gate_ops::{GateData, CalculationData, HornerData, GateOps, GateOpsConfig, LookupData, LookupConfig}, +}; +use icicle_runtime::{errors::eIcicleError, memory::HostOrDeviceSlice}; + +impl_gate_ops_field!("bn254", bn254, ScalarField, ScalarCfg); +#[cfg(test)] +pub(crate) mod tests { + use crate::curve::ScalarField; + use icicle_core::impl_gate_ops_tests; + use icicle_core::gate_ops::tests::*; + + impl_gate_ops_tests!(ScalarField); +} diff --git a/wrappers/rust/icicle-curves/icicle-bn254/src/lib.rs b/wrappers/rust/icicle-curves/icicle-bn254/src/lib.rs index 0f906658f2..65cc96531f 100644 --- a/wrappers/rust/icicle-curves/icicle-bn254/src/lib.rs +++ b/wrappers/rust/icicle-curves/icicle-bn254/src/lib.rs @@ -6,6 +6,7 @@ pub mod poseidon; pub mod poseidon2; pub mod sumcheck; pub mod vec_ops; +pub mod gate_ops; #[cfg(not(feature = "no_ecntt"))] pub mod ecntt; diff --git a/wrappers/rust/icicle-curves/icicle-grumpkin/src/gate_ops/mod.rs b/wrappers/rust/icicle-curves/icicle-grumpkin/src/gate_ops/mod.rs new file mode 100644 index 0000000000..14c27cd9da --- /dev/null +++ b/wrappers/rust/icicle-curves/icicle-grumpkin/src/gate_ops/mod.rs @@ -0,0 +1,16 @@ +use crate::curve::{ScalarCfg, ScalarField}; +use icicle_core::{ + impl_gate_ops_field, + gate_ops::{GateOps, GateOpsConfig}, +}; +use icicle_runtime::{errors::eIcicleError, memory::HostOrDeviceSlice}; + +impl_gate_ops_field!("grumpkin", grumpkin, ScalarField, ScalarCfg); +#[cfg(test)] +pub(crate) mod tests { + use crate::curve::ScalarField; + use icicle_core::impl_gate_ops_tests; + use icicle_core::gate_ops::tests::*; + + impl_gate_ops_tests!(ScalarField); +} diff --git a/wrappers/rust/icicle-fields/icicle-babybear/src/gate_ops/mod.rs b/wrappers/rust/icicle-fields/icicle-babybear/src/gate_ops/mod.rs new file mode 100644 index 0000000000..9d994f3c9c --- /dev/null +++ b/wrappers/rust/icicle-fields/icicle-babybear/src/gate_ops/mod.rs @@ -0,0 +1,17 @@ +use crate::field::{ScalarCfg, ScalarField}; + +use icicle_core::gate_ops::{GateOps, GateOpsConfig, GateData, CalculationData, HornerData}; +use icicle_core::{impl_gate_ops_field}; +use icicle_runtime::errors::eIcicleError; +use icicle_runtime::memory::HostOrDeviceSlice; + +impl_gate_ops_field!("babybear", babybear, ScalarField, ScalarCfg); + +#[cfg(test)] +pub(crate) mod tests { + use crate::field::{ScalarField}; + use icicle_core::gate_ops::tests::*; + use icicle_core::impl_gate_ops_tests; + + impl_gate_ops_tests!(ScalarField); +} diff --git a/wrappers/rust/icicle-fields/icicle-babybear/src/lib.rs b/wrappers/rust/icicle-fields/icicle-babybear/src/lib.rs index ad7aa51895..62a05b9dbc 100644 --- a/wrappers/rust/icicle-fields/icicle-babybear/src/lib.rs +++ b/wrappers/rust/icicle-fields/icicle-babybear/src/lib.rs @@ -4,3 +4,4 @@ pub mod polynomials; pub mod poseidon; pub mod poseidon2; pub mod vec_ops; +pub mod gate_ops; diff --git a/wrappers/rust/icicle-fields/icicle-koalabear/src/gate_ops/mod.rs b/wrappers/rust/icicle-fields/icicle-koalabear/src/gate_ops/mod.rs new file mode 100644 index 0000000000..74d7612caf --- /dev/null +++ b/wrappers/rust/icicle-fields/icicle-koalabear/src/gate_ops/mod.rs @@ -0,0 +1,17 @@ +use crate::field::{ScalarCfg, ScalarField}; + +use icicle_core::gate_ops::{GateOps, GateOpsConfig}; +use icicle_core::{impl_gate_ops_field}; +use icicle_runtime::errors::eIcicleError; +use icicle_runtime::memory::HostOrDeviceSlice; + +impl_gate_ops_field!("koalabear", koalabear, ScalarField, ScalarCfg); + +#[cfg(test)] +pub(crate) mod tests { + use crate::field::{ExtensionField, ScalarField}; + use icicle_core::gate_ops::tests::*; + use icicle_core::impl_gate_ops_tests; + + impl_gate_ops_tests!(ScalarField); +} diff --git a/wrappers/rust/icicle-fields/icicle-koalabear/src/lib.rs b/wrappers/rust/icicle-fields/icicle-koalabear/src/lib.rs index ad7aa51895..d7bc031e3a 100644 --- a/wrappers/rust/icicle-fields/icicle-koalabear/src/lib.rs +++ b/wrappers/rust/icicle-fields/icicle-koalabear/src/lib.rs @@ -4,3 +4,4 @@ pub mod polynomials; pub mod poseidon; pub mod poseidon2; pub mod vec_ops; +pub mod gate_ops; \ No newline at end of file diff --git a/wrappers/rust/icicle-fields/icicle-m31/src/gate_ops/mod.rs b/wrappers/rust/icicle-fields/icicle-m31/src/gate_ops/mod.rs new file mode 100644 index 0000000000..106d7708fd --- /dev/null +++ b/wrappers/rust/icicle-fields/icicle-m31/src/gate_ops/mod.rs @@ -0,0 +1,17 @@ +use crate::field::{ScalarCfg, ScalarField}; + +use icicle_core::gate_ops::{GateOps, GateOpsConfig}; +use icicle_core::{impl_gate_ops_field}; +use icicle_runtime::errors::eIcicleError; +use icicle_runtime::memory::HostOrDeviceSlice; + +impl_gate_ops_field!("m31", m31, ScalarField, ScalarCfg); + +#[cfg(test)] +pub(crate) mod tests { + use crate::field::{ExtensionField, ScalarField}; + use icicle_core::gate_ops::tests::*; + use icicle_core::impl_gate_ops_tests; + + impl_gate_ops_tests!(ScalarField); +} diff --git a/wrappers/rust/icicle-fields/icicle-m31/src/lib.rs b/wrappers/rust/icicle-fields/icicle-m31/src/lib.rs index 81c3ab67f8..7d802fc022 100644 --- a/wrappers/rust/icicle-fields/icicle-m31/src/lib.rs +++ b/wrappers/rust/icicle-fields/icicle-m31/src/lib.rs @@ -2,3 +2,4 @@ pub mod field; pub mod poseidon; pub mod poseidon2; pub mod vec_ops; +pub mod gate_ops; diff --git a/wrappers/rust/icicle-fields/icicle-stark252/src/gate_ops/mod.rs b/wrappers/rust/icicle-fields/icicle-stark252/src/gate_ops/mod.rs new file mode 100644 index 0000000000..faf936599e --- /dev/null +++ b/wrappers/rust/icicle-fields/icicle-stark252/src/gate_ops/mod.rs @@ -0,0 +1,17 @@ +use crate::field::{ScalarCfg, ScalarField}; + +use icicle_core::gate_ops::{GateOps, GateOpsConfig}; +use icicle_core::{impl_gate_ops_field}; +use icicle_runtime::errors::eIcicleError; +use icicle_runtime::memory::HostOrDeviceSlice; + +impl_gate_ops_field!("stark252", stark252, ScalarField, ScalarCfg); + +#[cfg(test)] +pub(crate) mod tests { + use crate::field::{ExtensionField, ScalarField}; + use icicle_core::gate_ops::tests::*; + use icicle_core::impl_gate_ops_tests; + + impl_gate_ops_tests!(ScalarField); +} diff --git a/wrappers/rust/icicle-fields/icicle-stark252/src/lib.rs b/wrappers/rust/icicle-fields/icicle-stark252/src/lib.rs index ad7aa51895..d7bc031e3a 100644 --- a/wrappers/rust/icicle-fields/icicle-stark252/src/lib.rs +++ b/wrappers/rust/icicle-fields/icicle-stark252/src/lib.rs @@ -4,3 +4,4 @@ pub mod polynomials; pub mod poseidon; pub mod poseidon2; pub mod vec_ops; +pub mod gate_ops; \ No newline at end of file