diff --git a/.github/workflows/mldsa.yml b/.github/workflows/mldsa.yml new file mode 100644 index 000000000..03b6d91ad --- /dev/null +++ b/.github/workflows/mldsa.yml @@ -0,0 +1,97 @@ +name: ML-DSA + +on: + push: + branches: ["main", "dev"] + pull_request: + branches: ["main", "dev", "*"] + workflow_dispatch: + merge_group: + +env: + CARGO_TERM_COLOR: always + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + strategy: + fail-fast: false + matrix: + bits: [32, 64] + os: + - macos-13 # Intel mac + - macos-latest # macos-14 m1 + - ubuntu-latest + - windows-latest + exclude: + - bits: 32 + os: "macos-latest" + - bits: 32 + os: "macos-13" + + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + working-directory: libcrux-ml-dsa + + steps: + - uses: actions/checkout@v4 + + - run: echo "RUST_TARGET_FLAG=" > $GITHUB_ENV + if: ${{ matrix.bits == 64 }} + + - name: 🛠️ Setup Rust Nightly + run: rustup toolchain install nightly + + - name: 🛠️ Setup Ubuntu x86 + if: ${{ matrix.bits == 32 && matrix.os == 'ubuntu-latest' }} + run: | + rustup target add i686-unknown-linux-gnu + sudo apt-get update + sudo apt-get install -y gcc-multilib g++-multilib + + - name: 🛠️ Setup Ubuntu x64 + if: ${{ matrix.bits == 64 && matrix.os == 'ubuntu-latest' }} + run: | + rustup target add aarch64-unknown-linux-gnu + + # Set up 32 bit systems + + - name: 🛠️ Config Windows x86 + run: echo "RUST_TARGET_FLAG=--target=i686-pc-windows-msvc" > $GITHUB_ENV + if: ${{ matrix.bits == 32 && matrix.os == 'windows-latest' }} + + - name: 🛠️ Config Linux x86 + run: | + echo "RUST_TARGET_FLAG=--target=i686-unknown-linux-gnu" > $GITHUB_ENV + if: ${{ matrix.bits == 32 && matrix.os == 'ubuntu-latest' }} + + # Build ... + + - name: 🔨 Build + run: | + rustc --print=cfg + cargo build --verbose $RUST_TARGET_FLAG + + - name: 🔨 Build Release + run: cargo build --verbose --release $RUST_TARGET_FLAG + + - name: 🏃🏻 Asan MacOS + if: ${{ matrix.os == 'macos-latest' }} + run: RUSTDOCFLAGS=-Zsanitizer=address RUSTFLAGS=-Zsanitizer=address cargo +nightly test --release --target aarch64-apple-darwin + + # Test ML-DSA + + - name: 🏃🏻‍♀️ Test + run: | + cargo clean + cargo test --verbose $RUST_TARGET_FLAG + + - name: 🏃🏻‍♀️ Test Release + run: | + cargo clean + cargo test --verbose --release $RUST_TARGET_FLAG diff --git a/libcrux-ml-dsa/Cargo.toml b/libcrux-ml-dsa/Cargo.toml index 9e01338df..dcc3340ee 100644 --- a/libcrux-ml-dsa/Cargo.toml +++ b/libcrux-ml-dsa/Cargo.toml @@ -11,6 +11,7 @@ readme.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +libcrux-sha3 = { version = "0.0.2-pre.2", path = "../libcrux-sha3" } [dev-dependencies] hex = { version = "0.4.3", features = ["serde"] } diff --git a/libcrux-ml-dsa/src/arithmetic.rs b/libcrux-ml-dsa/src/arithmetic.rs new file mode 100644 index 000000000..2708a4055 --- /dev/null +++ b/libcrux-ml-dsa/src/arithmetic.rs @@ -0,0 +1,63 @@ +use crate::constants::{BITS_IN_LOWER_PART_OF_T, COEFFICIENTS_IN_RING_ELEMENT, FIELD_MODULUS}; + +/// Values having this type hold a representative 'x' of the ML-DSA field. +pub(crate) type FieldElement = i32; + +#[derive(Clone, Copy)] +pub struct PolynomialRingElement { + pub(crate) coefficients: [FieldElement; COEFFICIENTS_IN_RING_ELEMENT], +} + +impl PolynomialRingElement { + pub const ZERO: Self = Self { + // FIXME: hax issue, 256 is COEFFICIENTS_IN_RING_ELEMENT + coefficients: [0i32; 256], + }; +} + +// Splits 0 ≤ t < Q into t0 and t1 with a = t1*2ᴰ + t0 +// and -2ᴰ⁻¹ < t0 < 2ᴰ⁻¹. Returns t0 and t1 computed as. +// +// - t0 = t mod± 2ᵈ +// - t1 = (t - t0) / 2ᵈ. +// +// This approach has been taken from: +// https://github.com/cloudflare/circl/blob/main/sign/dilithium/internal/common/field.go#L35 +pub(crate) fn power2round(t: i32) -> (i32, i32) { + debug_assert!(t >= 0 && t < FIELD_MODULUS); + + // Compute t mod 2ᵈ + // t0 is now one of 0, 1, ..., 2ᵈ⁻¹-1, 2ᵈ⁻¹, 2ᵈ⁻¹+1, ..., 2ᵈ-1 + let mut t0 = t & ((1 << BITS_IN_LOWER_PART_OF_T) - 1); + + // now t0 is -2ᵈ⁻¹-1, -2ᵈ⁻¹, ..., -2, -1, 0, ..., 2ᵈ⁻¹-2 + t0 -= (1 << (BITS_IN_LOWER_PART_OF_T - 1)) + 1; + + // Next, we add 2ᴰ to those t0 that are negative + // now a0 is 2ᵈ⁻¹-1, 2ᵈ⁻¹, ..., 2ᵈ-2, 2ᵈ-1, 0, ..., 2ᵈ⁻¹-2 + t0 += (t0 >> 31) & (1 << BITS_IN_LOWER_PART_OF_T); + + // now t0 is 0, 1, 2, ..., 2ᵈ⁻¹-1, 2ᵈ⁻¹-1, -2ᵈ⁻¹-1, ... + // which is what we want. + t0 -= (1 << (BITS_IN_LOWER_PART_OF_T - 1)) - 1; + + let t1 = (t - t0) >> BITS_IN_LOWER_PART_OF_T; + + (t0, t1) +} + +pub(crate) fn t0_to_unsigned_representative(t0: i32) -> i32 { + (1 << (BITS_IN_LOWER_PART_OF_T - 1)) - t0 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_power2round() { + assert_eq!(power2round(2898283), (-1685, 354)); + assert_eq!(power2round(3821421), (3949, 466)); + assert_eq!(power2round(2577417), (-3063, 315)); + } +} diff --git a/libcrux-ml-dsa/src/constants.rs b/libcrux-ml-dsa/src/constants.rs index faecaa270..d47f9e616 100644 --- a/libcrux-ml-dsa/src/constants.rs +++ b/libcrux-ml-dsa/src/constants.rs @@ -1,3 +1,14 @@ +pub(crate) const FIELD_MODULUS: i32 = 8_380_417; + +pub(crate) const COEFFICIENTS_IN_RING_ELEMENT: usize = 256; + pub(crate) const FIELD_MODULUS_MINUS_ONE_BIT_LENGTH: usize = 23; -pub(crate) const DROPPED_BITS_FROM_T: usize = 13; +pub(crate) const BITS_IN_LOWER_PART_OF_T: usize = 13; + +pub(crate) const BITS_IN_UPPER_PART_OF_T: usize = + FIELD_MODULUS_MINUS_ONE_BIT_LENGTH - BITS_IN_LOWER_PART_OF_T; + +pub(crate) const SEED_FOR_A_SIZE: usize = 32; +pub(crate) const HASH_OF_PUBLIC_KEY_SIZE: usize = 64; +pub(crate) const SEED_FOR_SIGNING_SIZE: usize = 32; diff --git a/libcrux-ml-dsa/src/hash_functions.rs b/libcrux-ml-dsa/src/hash_functions.rs new file mode 100644 index 000000000..59add4178 --- /dev/null +++ b/libcrux-ml-dsa/src/hash_functions.rs @@ -0,0 +1,36 @@ +#![allow(non_snake_case)] +pub(crate) fn H(input: &[u8]) -> [u8; OUTPUT_LENGTH] { + let mut out = [0u8; OUTPUT_LENGTH]; + libcrux_sha3::portable::shake256(&mut out, input); + + out +} + +pub(crate) mod H_128 { + use libcrux_sha3::portable::{incremental, KeccakState1}; + + const BLOCK_SIZE: usize = 168; + const FIVE_BLOCKS_SIZE: usize = BLOCK_SIZE * 5; + + #[inline(always)] + pub(crate) fn new(seed: [u8; 34]) -> KeccakState1 { + let mut state = incremental::shake128_init(); + incremental::shake128_absorb_final(&mut state, &seed); + + state + } + + pub(crate) fn squeeze_first_five_blocks(state: &mut KeccakState1) -> [u8; FIVE_BLOCKS_SIZE] { + let mut out = [0u8; FIVE_BLOCKS_SIZE]; + incremental::shake128_squeeze_first_five_blocks(state, &mut out); + + out + } + + pub(crate) fn squeeze_next_block(state: &mut KeccakState1) -> [u8; BLOCK_SIZE] { + let mut out = [0u8; BLOCK_SIZE]; + incremental::shake128_squeeze_next_block(state, &mut out); + + out + } +} diff --git a/libcrux-ml-dsa/src/lib.rs b/libcrux-ml-dsa/src/lib.rs index fe886991a..3065cac92 100644 --- a/libcrux-ml-dsa/src/lib.rs +++ b/libcrux-ml-dsa/src/lib.rs @@ -1,4 +1,11 @@ +mod arithmetic; mod constants; +mod hash_functions; +mod matrix; +mod sample; +mod serialize; +mod utils; + mod ml_dsa_generic; pub mod ml_dsa_65; diff --git a/libcrux-ml-dsa/src/matrix.rs b/libcrux-ml-dsa/src/matrix.rs new file mode 100644 index 000000000..f7d5ede1e --- /dev/null +++ b/libcrux-ml-dsa/src/matrix.rs @@ -0,0 +1,27 @@ +use crate::{arithmetic::PolynomialRingElement, sample::sample_ring_element_uniform}; + +#[allow(non_snake_case)] +#[inline(always)] +pub(crate) fn expand_to_A( + mut seed: [u8; 34], + transposed: bool, +) -> [[PolynomialRingElement; COLUMNS_IN_A]; ROWS_IN_A] { + let mut A = [[PolynomialRingElement::ZERO; COLUMNS_IN_A]; ROWS_IN_A]; + + for i in 0..ROWS_IN_A { + for j in 0..COLUMNS_IN_A { + seed[32] = i as u8; + seed[33] = j as u8; + + let sampled = sample_ring_element_uniform(seed); + + if transposed { + A[j][i] = sampled; + } else { + A[i][j] = sampled; + } + } + } + + A +} diff --git a/libcrux-ml-dsa/src/ml_dsa_65.rs b/libcrux-ml-dsa/src/ml_dsa_65.rs index 97b5db7b5..8d517c1d3 100644 --- a/libcrux-ml-dsa/src/ml_dsa_65.rs +++ b/libcrux-ml-dsa/src/ml_dsa_65.rs @@ -5,23 +5,37 @@ use crate::constants::*; const ROWS_IN_A: usize = 6; const COLUMNS_IN_A: usize = 5; -const PUBLIC_KEY_SIZE: usize = - 32 + (32 * ROWS_IN_A * (FIELD_MODULUS_MINUS_ONE_BIT_LENGTH - DROPPED_BITS_FROM_T)); -const SECRET_KEY_SIZE: usize = - (32 + 32 + 64) + 32 * (((ROWS_IN_A + COLUMNS_IN_A) * 4) + (DROPPED_BITS_FROM_T * ROWS_IN_A)); +const ETA: usize = 4; +const TWO_TIMES_ETA_BIT_SIZE: usize = 4; // ⌊log_2(4)⌋ + 1 + +const VERIFICATION_KEY_SIZE: usize = SEED_FOR_A_SIZE + + (COEFFICIENTS_IN_RING_ELEMENT + * ROWS_IN_A + * (FIELD_MODULUS_MINUS_ONE_BIT_LENGTH - BITS_IN_LOWER_PART_OF_T)) + / 8; + +const SIGNING_KEY_SIZE: usize = (SEED_FOR_A_SIZE + SEED_FOR_SIGNING_SIZE + HASH_OF_PUBLIC_KEY_SIZE) + + (COEFFICIENTS_IN_RING_ELEMENT + * (((ROWS_IN_A + COLUMNS_IN_A) * TWO_TIMES_ETA_BIT_SIZE) + + (BITS_IN_LOWER_PART_OF_T * ROWS_IN_A))) + / 8; pub struct MLDSA65KeyPair { - pub secret_key: [u8; SECRET_KEY_SIZE], - pub public_key: [u8; PUBLIC_KEY_SIZE], + pub signing_key: [u8; SIGNING_KEY_SIZE], + pub verification_key: [u8; VERIFICATION_KEY_SIZE], } /// Generate an ML-DSA-65 Key Pair pub fn generate_key_pair(randomness: [u8; 32]) -> MLDSA65KeyPair { - let (secret_key, public_key) = - crate::ml_dsa_generic::generate_key_pair::(randomness); + let (signing_key, verification_key) = crate::ml_dsa_generic::generate_key_pair::< + ROWS_IN_A, + COLUMNS_IN_A, + SIGNING_KEY_SIZE, + VERIFICATION_KEY_SIZE, + >(randomness); MLDSA65KeyPair { - secret_key, - public_key, + signing_key, + verification_key, } } diff --git a/libcrux-ml-dsa/src/ml_dsa_generic.rs b/libcrux-ml-dsa/src/ml_dsa_generic.rs index 9a312fcb1..b1bb17f38 100644 --- a/libcrux-ml-dsa/src/ml_dsa_generic.rs +++ b/libcrux-ml-dsa/src/ml_dsa_generic.rs @@ -1,6 +1,19 @@ -pub(crate) fn generate_key_pair( +use crate::{hash_functions::H, matrix::expand_to_A, utils::into_padded_array}; + +#[allow(non_snake_case)] +pub(crate) fn generate_key_pair< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const SIGNING_KEY_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, +>( randomness: [u8; 32], -) -> ([u8; SECRET_KEY_SIZE], [u8; PUBLIC_KEY_SIZE]) { - let _ = randomness; +) -> ([u8; SIGNING_KEY_SIZE], [u8; VERIFICATION_KEY_SIZE]) { + let seed_expanded = H::<1024>(&randomness); + let (seed_for_A, seed_expanded) = seed_expanded.split_at(32); + let (_seed_for_short_vectors, _random_seed_for_signing) = seed_expanded.split_at(64); + + let _A_hat = expand_to_A::(into_padded_array(seed_for_A), false); + todo!(); } diff --git a/libcrux-ml-dsa/src/sample.rs b/libcrux-ml-dsa/src/sample.rs new file mode 100644 index 000000000..579b19e87 --- /dev/null +++ b/libcrux-ml-dsa/src/sample.rs @@ -0,0 +1,261 @@ +use crate::{ + arithmetic::PolynomialRingElement, + constants::{COEFFICIENTS_IN_RING_ELEMENT, FIELD_MODULUS}, + hash_functions::{H, H_128}, +}; + +fn rejection_sample_less_than_field_modulus( + randomness: &[u8], + sampled: &mut usize, + out: &mut PolynomialRingElement, +) -> bool { + let mut done = false; + + for bytes in randomness.chunks(3) { + if !done { + let b0 = bytes[0] as i32; + let b1 = bytes[1] as i32; + let b2 = bytes[2] as i32; + + let potential_coefficient = ((b2 << 16) | (b1 << 8) | b0) & 0x00_7F_FF_FF; + + if potential_coefficient < FIELD_MODULUS && *sampled < COEFFICIENTS_IN_RING_ELEMENT { + out.coefficients[*sampled] = potential_coefficient; + *sampled += 1; + } + + if *sampled == COEFFICIENTS_IN_RING_ELEMENT { + done = true; + } + } + } + + done +} +pub(crate) fn sample_ring_element_uniform(seed: [u8; 34]) -> PolynomialRingElement { + let mut state = H_128::new(seed); + let randomness = H_128::squeeze_first_five_blocks(&mut state); + + let mut out = PolynomialRingElement::ZERO; + + let mut sampled = 0; + let mut done = rejection_sample_less_than_field_modulus(&randomness, &mut sampled, &mut out); + + while !done { + let randomness = H_128::squeeze_next_block(&mut state); + done = rejection_sample_less_than_field_modulus(&randomness, &mut sampled, &mut out); + } + + out +} + +fn rejection_sample_less_than_eta_equals_2( + randomness: &[u8], + sampled: &mut usize, + out: &mut PolynomialRingElement, +) -> bool { + let mut done = false; + + for byte in randomness { + if !done { + let try_0 = byte & 0xF; + let try_1 = byte >> 4; + + if try_0 < 15 && *sampled < COEFFICIENTS_IN_RING_ELEMENT { + let try_0 = try_0 as i32; + + // (try_0 * 26) >> 7 computes ⌊try_0 / 5⌋ + let try_0_mod_5 = try_0 - ((try_0 * 26) >> 7) * 5; + + out.coefficients[*sampled] = 2 - try_0_mod_5; + + *sampled += 1; + } + + if try_1 < 15 && *sampled < COEFFICIENTS_IN_RING_ELEMENT { + let try_1 = try_1 as i32; + let try_1_mod_5 = try_1 - ((try_1 * 26) >> 7) * 5; + + out.coefficients[*sampled] = 2 - try_1_mod_5; + + *sampled += 1; + } + + if *sampled == COEFFICIENTS_IN_RING_ELEMENT { + done = true; + } + } + } + + done +} +fn rejection_sample_less_than_eta_equals_4( + randomness: &[u8], + sampled: &mut usize, + out: &mut PolynomialRingElement, +) -> bool { + let mut done = false; + + for byte in randomness { + if !done { + let try_0 = byte & 0xF; + let try_1 = byte >> 4; + + if try_0 < 9 && *sampled < COEFFICIENTS_IN_RING_ELEMENT { + out.coefficients[*sampled] = 4 - (try_0 as i32); + *sampled += 1; + } + + if try_1 < 9 && *sampled < COEFFICIENTS_IN_RING_ELEMENT { + out.coefficients[*sampled] = 4 - (try_1 as i32); + *sampled += 1; + } + + if *sampled == COEFFICIENTS_IN_RING_ELEMENT { + done = true; + } + } + } + + done +} + +pub(crate) fn rejection_sample_less_than_eta( + randomness: &[u8], + sampled: &mut usize, + out: &mut PolynomialRingElement, +) -> bool { + match ETA { + 2 => rejection_sample_less_than_eta_equals_2(randomness, sampled, out), + 4 => rejection_sample_less_than_eta_equals_4(randomness, sampled, out), + _ => unreachable!(), + } +} + +#[allow(non_snake_case)] +pub(crate) fn sample_error_ring_element_uniform( + seed: [u8; 66], +) -> PolynomialRingElement { + // TODO: Use incremental API to squeeze one block at a time. + let randomness = H::<272>(&seed); + + let mut out = PolynomialRingElement::ZERO; + + let mut sampled = 0; + let done = rejection_sample_less_than_eta::(&randomness, &mut sampled, &mut out); + + // TODO: Remove this panic using the incremental API. + if !done { + panic!("Not enough randomness for sampling short vector."); + } + + out +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::arithmetic::FieldElement; + + #[test] + fn test_sample_ring_element_uniform() { + let seed: [u8; 34] = [ + 33, 192, 250, 216, 117, 61, 16, 12, 248, 51, 213, 110, 64, 57, 119, 80, 164, 83, 73, + 91, 80, 128, 195, 219, 203, 149, 170, 233, 16, 232, 209, 105, 4, 5, + ]; + + let expected_coefficients: [FieldElement; COEFFICIENTS_IN_RING_ELEMENT] = [ + 886541, 1468422, 793958, 7610434, 3986512, 913782, 2546456, 5820798, 1940159, 10062, + 3303190, 3831326, 4834267, 3500674, 16909, 8314529, 7469249, 5611755, 6181076, 269257, + 3566448, 2968856, 7556314, 6685884, 129963, 8017973, 1087829, 5842199, 6867133, 442098, + 3473053, 3812349, 556165, 55620, 4367526, 798402, 5317265, 2828265, 3808240, 3065841, + 6340895, 2710831, 715345, 5806109, 3689225, 4088547, 4258029, 2877620, 6867225, + 3275166, 4626484, 6596723, 5180488, 3836050, 1115576, 2086584, 749098, 4980044, + 7626966, 961947, 4695118, 6488634, 7898263, 841160, 1186851, 6958928, 4995591, 6829719, + 5910175, 2590788, 987365, 5983050, 7039561, 1406907, 4054912, 3093314, 237981, 6184639, + 515190, 5209488, 6460375, 4417602, 7890594, 6584284, 1729237, 5851336, 8226663, + 1843549, 5872244, 1375077, 6275711, 997136, 2593411, 5739784, 6621377, 7180456, + 1437441, 2607410, 197226, 4753353, 5086363, 6096080, 3057564, 5040851, 886178, 699532, + 3772666, 7983776, 1235995, 1960665, 1233119, 317423, 442071, 4649134, 5043634, 4164756, + 3166873, 2343835, 6256400, 6132302, 4124098, 6087733, 5371278, 3484545, 1020458, + 3688444, 7263864, 2413270, 4449757, 5561507, 7464292, 1176556, 8294481, 2892372, + 5509298, 194732, 7976046, 5907126, 4792878, 5059916, 3122481, 7009119, 5476286, + 4905623, 7374799, 7284599, 4929839, 538055, 5611660, 233595, 6125390, 7441322, 3752658, + 6655759, 4907614, 2281767, 1659504, 5490352, 4235568, 7143494, 6217399, 1581266, + 2455222, 1015526, 8366150, 2002613, 185543, 7904386, 8206829, 5380721, 2226008, + 7713547, 6961768, 7911095, 5604679, 6839785, 7573702, 1113136, 5563352, 7446030, + 6694003, 1725163, 4749689, 6474727, 7125683, 1830230, 5300491, 7927815, 5808662, + 2345184, 5462894, 5760340, 1949317, 1853703, 5060631, 5935138, 4873466, 3302619, + 5351360, 5707708, 2715882, 2050173, 52173, 5463772, 2851164, 1702574, 7167630, 1132010, + 1418205, 4182063, 4919187, 2707143, 6241533, 3241235, 2286591, 268487, 3799838, 558302, + 5882605, 6165192, 6702794, 5578115, 1893372, 7246495, 4974148, 2633723, 1522313, + 7636103, 6639058, 6765356, 3588710, 7011438, 4798122, 2329503, 4671411, 6787853, + 1838957, 306944, 5112958, 853077, 7844176, 384195, 839634, 1860349, 7289878, 4054796, + 703698, 5147821, 7632328, 5993194, 6329638, 5959986, 3073141, 675737, 7364844, 4124952, + ]; + + assert_eq!( + sample_ring_element_uniform(seed).coefficients, + expected_coefficients + ); + } + + #[test] + fn test_sample_error_ring_element_when_eta_is_2() { + let seed: [u8; 66] = [ + 51, 203, 133, 235, 126, 210, 169, 81, 4, 134, 147, 168, 252, 67, 176, 99, 130, 186, + 254, 103, 241, 199, 173, 78, 121, 232, 12, 244, 4, 143, 8, 174, 122, 170, 124, 35, 53, + 49, 202, 94, 27, 249, 200, 186, 175, 198, 169, 116, 244, 227, 133, 111, 205, 140, 233, + 110, 227, 67, 35, 226, 194, 75, 130, 105, 5, 0, + ]; + + let expected_coefficients: [i32; COEFFICIENTS_IN_RING_ELEMENT] = [ + 1, 0, -1, 0, 1, -2, -1, 0, -2, 2, -1, -2, 1, -2, 1, -2, 1, 2, -2, 2, -2, -1, 0, -2, -1, + -2, -2, 1, 1, -1, 1, 1, 2, -2, 2, -1, 1, 2, 0, 2, -1, 0, 2, -2, -2, 2, 0, 2, 1, 1, 2, + 1, 1, -2, 1, -1, 2, -2, -2, 2, -2, -2, 0, 0, -1, 0, 2, 0, 1, 2, 0, 2, -1, 2, 0, 2, 1, + -2, -2, 0, -1, -2, 2, -2, -1, 2, 1, -1, 2, 1, -2, -1, 1, -1, -1, -1, 2, -1, -2, -2, 2, + 2, 0, -1, -1, -2, 0, -1, 0, 1, 2, -2, 0, 2, 2, 1, 0, -1, -1, 0, -2, 2, 2, -2, 2, 1, -1, + -2, -1, -2, -1, 1, 2, 2, -1, 0, 1, 2, -1, 0, 0, 0, 1, 1, -1, -1, -1, -2, 2, 0, -2, 0, + 2, -1, 1, 1, 2, -2, 2, -2, 1, 0, -2, 1, 0, 0, -2, -2, 2, 2, -2, -1, 2, -2, 1, 0, 0, -1, + 0, -2, 2, -1, -2, 2, -1, 1, -2, -1, 0, -2, 2, 1, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, -1, + -2, 1, 1, 0, -2, 1, 0, 0, -2, 1, -2, -1, 2, 0, 0, 2, 0, -2, -1, -1, 2, 2, -1, -1, -1, + -2, -2, -1, -2, 2, -2, 0, 1, 0, -2, -2, 2, 0, 1, 0, 0, -2, -1, 1, -1, 1, -1, -1, -1, 2, + 2, 0, + ]; + + assert_eq!( + sample_error_ring_element_uniform::<2>(seed).coefficients, + expected_coefficients + ); + } + + #[test] + fn test_sample_error_ring_element_when_eta_is_4() { + let seed: [u8; 66] = [ + 236, 4, 148, 239, 41, 178, 188, 226, 130, 212, 6, 144, 208, 180, 180, 105, 47, 148, 75, + 195, 181, 177, 5, 140, 204, 68, 24, 132, 169, 19, 68, 118, 67, 203, 13, 152, 29, 194, + 235, 123, 101, 109, 162, 137, 198, 164, 97, 247, 11, 44, 34, 49, 235, 251, 243, 177, + 213, 141, 65, 232, 136, 163, 85, 54, 10, 0, + ]; + + let expected_coefficients: [i32; COEFFICIENTS_IN_RING_ELEMENT] = [ + 2, -4, 2, -2, 1, 2, 4, 2, 4, -1, -4, 3, 2, 4, -1, 2, -3, 3, 1, -2, 0, 3, -2, 3, 4, 1, + -3, -2, 0, -4, -1, -4, 3, -4, 0, -3, -2, -3, 2, -3, -3, 3, -4, -3, -4, 1, -2, 4, -3, 4, + 4, 1, -3, -3, 4, 0, -2, 2, 4, -4, 4, -4, -1, -3, 4, 3, 2, -1, 3, -2, -2, -4, -1, -1, 4, + 1, 4, 0, 3, 4, -1, -3, 4, -4, 4, 1, -3, 0, -4, 2, 1, 4, -1, 0, -2, -2, -3, 3, -3, 4, 3, + 2, -2, -2, -1, 2, -1, -4, 3, 0, -2, 4, -1, 0, 4, -2, 4, -3, 2, -4, 2, 3, 3, 2, -4, 2, + 0, -2, 1, -4, 0, -4, -3, 2, 0, -2, -4, 1, 2, 3, 4, -4, 2, 2, 1, -4, 0, -4, -3, -2, -2, + -2, -1, 1, 4, 1, 0, -2, 2, 1, 4, -4, -1, 0, -1, -3, 2, 1, 3, 3, 4, -2, -2, 3, 1, 3, 3, + -4, -2, -1, -4, -3, 4, 1, 2, -3, -1, 3, 4, -3, 0, -1, -1, -4, -2, 1, -2, 3, -1, -2, 2, + -1, -2, 0, -2, 2, 3, 3, 2, 3, 4, 3, -3, -4, 1, 4, -3, 2, 0, -4, 4, -4, 2, 4, -2, -3, + -4, 3, 0, 1, -2, 2, -1, 4, 4, 0, -1, 1, 4, -2, -3, 2, -2, 4, 2, 1, 1, 1, -3, -2, -2, 2, + 2, -4, -1, 1, + ]; + + assert_eq!( + sample_error_ring_element_uniform::<4>(seed).coefficients, + expected_coefficients + ); + } +} diff --git a/libcrux-ml-dsa/src/serialize.rs b/libcrux-ml-dsa/src/serialize.rs new file mode 100644 index 000000000..7fb537312 --- /dev/null +++ b/libcrux-ml-dsa/src/serialize.rs @@ -0,0 +1,179 @@ +use crate::arithmetic::{t0_to_unsigned_representative, PolynomialRingElement}; + +#[inline(always)] +fn serialize_ring_element_of_t0s(re: PolynomialRingElement) -> [u8; 416] { + let mut serialized = [0u8; 416]; + + for (i, coefficients) in re.coefficients.chunks_exact(8).enumerate() { + let coefficient0 = t0_to_unsigned_representative(coefficients[0]); + let coefficient1 = t0_to_unsigned_representative(coefficients[1]); + let coefficient2 = t0_to_unsigned_representative(coefficients[2]); + let coefficient3 = t0_to_unsigned_representative(coefficients[3]); + let coefficient4 = t0_to_unsigned_representative(coefficients[4]); + let coefficient5 = t0_to_unsigned_representative(coefficients[5]); + let coefficient6 = t0_to_unsigned_representative(coefficients[6]); + let coefficient7 = t0_to_unsigned_representative(coefficients[7]); + + serialized[13 * i + 0] = coefficient0 as u8; + + serialized[13 * i + 1] = (coefficient0 >> 8) as u8; + serialized[13 * i + 1] |= (coefficient1 << 5) as u8; + + serialized[13 * i + 2] = (coefficient1 >> 3) as u8; + + serialized[13 * i + 3] = (coefficient1 >> 11) as u8; + serialized[13 * i + 3] |= (coefficient2 << 2) as u8; + + serialized[13 * i + 4] = (coefficient2 >> 6) as u8; + serialized[13 * i + 4] |= (coefficient3 << 7) as u8; + + serialized[13 * i + 5] = (coefficient3 >> 1) as u8; + + serialized[13 * i + 6] = (coefficient3 >> 9) as u8; + serialized[13 * i + 6] |= (coefficient4 << 4) as u8; + + serialized[13 * i + 7] = (coefficient4 >> 4) as u8; + + serialized[13 * i + 8] = (coefficient4 >> 12) as u8; + serialized[13 * i + 8] |= (coefficient5 << 1) as u8; + + serialized[13 * i + 9] = (coefficient5 >> 7) as u8; + serialized[13 * i + 9] |= (coefficient6 << 6) as u8; + + serialized[13 * i + 10] = (coefficient6 >> 2) as u8; + + serialized[13 * i + 11] = (coefficient6 >> 10) as u8; + serialized[13 * i + 11] |= (coefficient7 << 3) as u8; + + serialized[13 * i + 12] = (coefficient7 >> 5) as u8; + } + + serialized +} + +#[inline(always)] +fn serialize_ring_element_of_t1s(re: PolynomialRingElement) -> [u8; 320] { + let mut serialized = [0u8; 320]; + + for (i, coefficients) in re.coefficients.chunks_exact(4).enumerate() { + serialized[5 * i] = (coefficients[0] & 0xFF) as u8; + serialized[5 * i + 1] = + ((coefficients[1] & 0x3F) as u8) << 2 | ((coefficients[0] >> 8) & 0x03) as u8; + serialized[5 * i + 2] = + ((coefficients[2] & 0x0F) as u8) << 4 | ((coefficients[1] >> 6) & 0x0F) as u8; + serialized[5 * i + 3] = + ((coefficients[3] & 0x03) as u8) << 6 | ((coefficients[2] >> 4) & 0x3F) as u8; + serialized[5 * i + 4] = ((coefficients[3] >> 2) & 0xFF) as u8; + } + + serialized +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::arithmetic::PolynomialRingElement; + + #[test] + fn test_serialize_ring_element_of_t1s() { + let re = PolynomialRingElement { + coefficients: [ + 127, 627, 86, 834, 463, 169, 792, 8, 595, 212, 1015, 213, 321, 501, 471, 633, 686, + 333, 973, 464, 737, 30, 761, 358, 659, 607, 177, 826, 147, 995, 89, 365, 302, 585, + 406, 76, 535, 406, 952, 664, 102, 270, 879, 877, 127, 437, 1010, 418, 695, 596, + 847, 131, 1004, 228, 882, 433, 39, 569, 284, 225, 676, 740, 712, 165, 912, 71, 491, + 887, 668, 607, 919, 607, 891, 647, 904, 957, 846, 256, 353, 57, 712, 98, 200, 722, + 734, 596, 187, 470, 501, 524, 1000, 435, 195, 594, 834, 848, 438, 548, 819, 533, + 898, 777, 676, 284, 215, 95, 811, 134, 338, 915, 12, 951, 124, 246, 365, 532, 359, + 561, 280, 923, 236, 299, 916, 394, 266, 946, 645, 872, 898, 228, 737, 229, 452, + 562, 355, 403, 321, 161, 202, 983, 306, 898, 172, 304, 921, 796, 232, 1011, 293, + 183, 130, 376, 874, 1018, 501, 154, 747, 62, 262, 185, 397, 208, 75, 933, 459, 687, + 574, 803, 570, 635, 57, 548, 253, 970, 583, 425, 626, 562, 96, 52, 715, 240, 58, + 451, 888, 932, 179, 632, 605, 394, 941, 646, 286, 217, 477, 443, 80, 639, 64, 139, + 394, 227, 2, 927, 455, 719, 377, 533, 438, 120, 788, 811, 650, 402, 240, 516, 354, + 950, 372, 105, 247, 762, 445, 108, 1009, 862, 885, 870, 53, 346, 392, 710, 434, 72, + 899, 610, 543, 937, 501, 41, 615, 97, 557, 168, 105, 665, 179, 708, 137, 849, 508, + 742, 512, 879, 534, 490, + ], + }; + + let expected_re_serialized = [ + 127, 204, 105, 133, 208, 207, 165, 130, 49, 2, 83, 82, 115, 127, 53, 65, 213, 119, 93, + 158, 174, 54, 213, 60, 116, 225, 122, 144, 175, 89, 147, 126, 25, 139, 206, 147, 140, + 159, 69, 91, 46, 37, 105, 25, 19, 23, 90, 134, 59, 166, 102, 56, 244, 118, 219, 127, + 212, 38, 191, 104, 183, 82, 249, 244, 32, 236, 147, 35, 119, 108, 39, 228, 200, 81, 56, + 164, 146, 139, 108, 41, 144, 31, 177, 222, 221, 156, 126, 121, 249, 151, 123, 31, 138, + 120, 239, 78, 3, 20, 86, 14, 200, 138, 129, 140, 180, 222, 82, 185, 139, 117, 245, 49, + 136, 254, 108, 195, 72, 41, 52, 212, 182, 145, 56, 115, 133, 130, 39, 76, 42, 71, 215, + 124, 177, 178, 33, 82, 77, 206, 192, 237, 124, 216, 211, 22, 133, 103, 197, 136, 209, + 230, 236, 172, 68, 185, 98, 10, 201, 94, 40, 218, 130, 147, 19, 110, 57, 196, 201, 56, + 214, 100, 65, 133, 162, 204, 245, 50, 9, 206, 10, 76, 153, 115, 140, 206, 252, 37, 221, + 34, 8, 94, 106, 235, 95, 159, 38, 235, 250, 96, 80, 46, 141, 65, 179, 68, 233, 203, + 189, 234, 227, 200, 58, 238, 153, 3, 137, 253, 40, 127, 100, 106, 114, 202, 8, 6, 13, + 203, 194, 163, 195, 112, 120, 147, 62, 11, 158, 93, 42, 214, 186, 161, 30, 101, 211, + 221, 110, 80, 252, 9, 196, 34, 138, 141, 35, 192, 231, 199, 61, 155, 87, 133, 182, 225, + 65, 241, 202, 138, 74, 6, 15, 129, 98, 217, 78, 87, 26, 247, 232, 219, 27, 27, 241, + 123, 93, 183, 217, 53, 104, 133, 152, 177, 178, 33, 49, 184, 152, 31, 166, 94, 95, 10, + 103, 134, 209, 34, 42, 105, 100, 58, 11, 177, 137, 68, 205, 159, 185, 0, 190, 109, 161, + 122, + ]; + + assert_eq!(serialize_ring_element_of_t1s(re), expected_re_serialized); + } + + #[test] + fn test_serialize_ring_element_of_t0s() { + let re = PolynomialRingElement { + coefficients: [ + -1072, -3712, -3423, -27, 1995, 3750, -922, 3806, 2356, 3801, -1709, -2709, 1191, + 108, -593, -3081, -949, -926, 3107, -3820, 379, 3747, -2910, -2370, 939, 3218, + -3190, 1311, 1110, -2717, -1191, -1019, -2478, -1860, -4018, 2615, -3208, 337, + -3406, -1225, -261, -329, -3624, -726, -3159, 3407, 4042, 2124, 2921, 1507, 279, + -2830, -2850, -4011, 402, 1510, -2648, -168, 18, 652, 3443, 1723, 3112, -1605, + -3885, 3174, 832, -3424, 2886, 3815, 2064, 1757, 3298, 3365, -1489, -1021, 1594, + 3630, -3352, 1055, -2914, -816, 864, -1251, 2628, -3199, 549, -1966, 419, 685, + -3414, -3673, -3939, -1422, -3994, 4073, 86, -1703, 1179, 758, -3588, 3427, -1798, + -2139, -456, -547, -3741, 3191, -2432, 1213, -3415, -3825, -1993, -763, -1757, 887, + 1587, -1995, -887, -873, 1152, -1897, 2738, 2867, 1952, 3834, 3562, 3118, -768, + 1400, 3883, 2636, 456, -3884, -1726, -3232, 2373, -1039, 591, 1975, 1634, 459, + -595, 2864, 3619, 3288, -2180, 4048, -2469, 1826, 1764, -1345, 3761, 2320, 3935, + -1219, -1397, 214, -1008, 299, -3270, -2628, 1070, 2904, 1597, 3471, 2383, -417, + -3456, 327, 3997, 1662, -3363, 2033, 1180, 1625, 923, -1911, -3511, -41, 1525, + -3882, -3104, 3023, 3794, -1028, 3818, -3216, -2875, -1755, -354, -3137, -1546, + -3535, -1156, 1802, -1081, 3726, 3067, 773, 2408, 72, 810, 3607, -1524, 3478, 3409, + 3377, 3159, 159, -706, -60, 1462, 2224, 2279, 2373, -3027, -78, 405, -4078, 2697, + 3474, -3611, 3632, 1229, 2396, -3729, -1110, 290, -2861, 3018, 122, 1177, -3123, + -3583, 2683, 2743, 2888, -2104, 874, -1150, -2453, -125, -2561, -2011, -2384, 2259, + -10, 836, -2773, 2487, -2292, -201, -3235, 1232, -3197, + ], + }; + + let expected_re_serialized = [ + 48, 20, 208, 127, 245, 13, 88, 131, 180, 130, 230, 20, 9, 204, 230, 36, 180, 218, 74, + 157, 181, 40, 95, 148, 76, 224, 181, 211, 115, 118, 15, 118, 95, 232, 186, 130, 215, + 22, 202, 85, 204, 109, 216, 241, 112, 165, 186, 58, 245, 41, 221, 159, 174, 153, 232, + 202, 254, 228, 130, 200, 95, 157, 83, 79, 166, 5, 49, 41, 162, 120, 107, 121, 197, 99, + 133, 13, 160, 61, 151, 164, 67, 165, 59, 135, 45, 178, 87, 191, 155, 211, 80, 88, 26, + 21, 186, 63, 186, 214, 40, 138, 18, 246, 40, 178, 45, 95, 115, 0, 51, 176, 174, 75, 50, + 2, 252, 25, 73, 30, 99, 91, 68, 215, 254, 105, 156, 164, 3, 70, 15, 95, 98, 27, 102, + 130, 178, 113, 202, 91, 254, 248, 118, 115, 189, 93, 110, 170, 89, 245, 44, 63, 246, + 29, 171, 230, 191, 0, 170, 239, 212, 150, 45, 133, 70, 224, 59, 133, 193, 221, 194, + 200, 113, 68, 118, 250, 196, 1, 152, 135, 214, 85, 143, 247, 201, 119, 95, 118, 219, + 68, 214, 156, 150, 239, 221, 76, 155, 128, 43, 237, 58, 149, 102, 2, 134, 12, 130, 133, + 144, 30, 0, 19, 81, 85, 3, 218, 130, 227, 88, 190, 175, 5, 229, 187, 230, 129, 198, + 182, 36, 228, 153, 106, 220, 148, 132, 38, 221, 1, 101, 16, 98, 24, 80, 154, 189, 17, + 71, 10, 170, 79, 1, 222, 132, 130, 97, 90, 87, 85, 30, 252, 172, 118, 198, 156, 72, 75, + 47, 84, 50, 156, 226, 68, 172, 9, 141, 128, 61, 215, 141, 1, 193, 52, 210, 31, 16, 217, + 58, 77, 101, 236, 238, 222, 246, 20, 184, 160, 84, 62, 8, 143, 33, 46, 129, 128, 90, 4, + 72, 190, 179, 183, 173, 88, 12, 226, 10, 246, 185, 19, 82, 123, 148, 67, 229, 66, 1, + 217, 103, 152, 6, 247, 89, 179, 244, 64, 95, 213, 196, 171, 120, 22, 169, 35, 236, 9, + 75, 30, 168, 164, 160, 78, 198, 217, 53, 211, 219, 9, 174, 57, 247, 127, 87, 220, 196, + 134, 135, 14, 51, 139, 212, 68, 122, 43, 234, 237, 90, 182, 13, 49, 124, 103, 107, 134, + 255, 247, 194, 146, 84, 112, 9, 14, 182, 100, 126, 180, 50, 247, 193, 0, 189, 125, 161, + 114, 203, 81, 128, 188, 172, 90, 39, 25, 122, 156, 12, 71, 57, 204, 234, 227, + ]; + + assert_eq!(serialize_ring_element_of_t0s(re), expected_re_serialized); + } +} diff --git a/libcrux-ml-dsa/src/utils.rs b/libcrux-ml-dsa/src/utils.rs new file mode 100644 index 000000000..8d4754d19 --- /dev/null +++ b/libcrux-ml-dsa/src/utils.rs @@ -0,0 +1,8 @@ +/// Pad the `slice` with `0`s at the end. +#[inline(always)] +pub(crate) fn into_padded_array(slice: &[u8]) -> [u8; LEN] { + debug_assert!(slice.len() <= LEN); + let mut out = [0u8; LEN]; + out[0..slice.len()].copy_from_slice(slice); + out +} diff --git a/libcrux-ml-dsa/tests/kats/dilithium.py b/libcrux-ml-dsa/tests/kats/dilithium.py index da3cee2c7..ad1eb4054 100644 --- a/libcrux-ml-dsa/tests/kats/dilithium.py +++ b/libcrux-ml-dsa/tests/kats/dilithium.py @@ -288,6 +288,7 @@ def rejection_sample(xof): seed = rho + bytes([j, i]) Shake128.absorb(seed) coeffs = [rejection_sample(Shake128) for _ in range(self.n)] + return self.R(coeffs, is_ntt=is_ntt) def _sample_mask_polynomial(self, rho_prime, i, kappa, is_ntt=False): diff --git a/libcrux-ml-dsa/tests/kats/generate_kats.py b/libcrux-ml-dsa/tests/kats/generate_kats.py index 1342361eb..8c9eac38a 100755 --- a/libcrux-ml-dsa/tests/kats/generate_kats.py +++ b/libcrux-ml-dsa/tests/kats/generate_kats.py @@ -6,7 +6,8 @@ import json import hashlib -for algorithm in [Dilithium2, Dilithium3, Dilithium5]: + +def generate_nistkats(algorithm): kats_formatted = [] entropy_input = bytes([i for i in range(48)]) @@ -43,3 +44,8 @@ with open("nistkats-{}{}.json".format(algorithm.k, algorithm.l), "w") as f: json.dump(kats_formatted, f, ensure_ascii=False, indent=4) + + +generate_nistkats(Dilithium2) +generate_nistkats(Dilithium3) +generate_nistkats(Dilithium5) diff --git a/libcrux-ml-dsa/tests/nistkats.rs b/libcrux-ml-dsa/tests/nistkats.rs index 02c54dd05..d2cc52a17 100644 --- a/libcrux-ml-dsa/tests/nistkats.rs +++ b/libcrux-ml-dsa/tests/nistkats.rs @@ -24,6 +24,7 @@ struct MlDsaNISTKAT { sha3_256_hash_of_signature: [u8; 32], } +#[ignore] #[test] fn ml_dsa_65_nist_known_answer_tests() { let katfile_path = Path::new("tests") diff --git a/libcrux-sha3/src/traits.rs b/libcrux-sha3/src/traits.rs index a499305e3..f8dc30c79 100644 --- a/libcrux-sha3/src/traits.rs +++ b/libcrux-sha3/src/traits.rs @@ -1,5 +1,5 @@ /// A trait for multiplexing implementations. -pub(crate) trait KeccakItem: Clone + Copy { +pub trait KeccakItem: Clone + Copy { fn zero() -> Self; fn xor5(a: Self, b: Self, c: Self, d: Self, e: Self) -> Self; fn rotate_left1_and_xor(a: Self, b: Self) -> Self; diff --git a/polynomials-aarch64/src/neon.rs b/polynomials-aarch64/src/neon.rs new file mode 100644 index 000000000..88157fdf3 --- /dev/null +++ b/polynomials-aarch64/src/neon.rs @@ -0,0 +1,282 @@ +#![allow(non_camel_case_types)] +pub(crate) use core::arch::aarch64::*; + +#[inline(always)] +pub(crate) fn _vdupq_n_s16(i: i16) -> int16x8_t { + unsafe { vdupq_n_s16(i) } +} + +#[inline(always)] +pub(crate) fn _vst1q_s16(out: &mut [i16], v: int16x8_t) { + unsafe { vst1q_s16(out.as_mut_ptr(), v) } +} + +#[inline(always)] +pub(crate) fn _vld1q_s16(array: &[i16]) -> int16x8_t { + unsafe { vld1q_s16(array.as_ptr()) } +} + +#[inline(always)] +pub(crate) fn _vaddq_s16(lhs: int16x8_t, rhs: int16x8_t) -> int16x8_t { + unsafe { vaddq_s16(lhs, rhs) } +} + +#[inline(always)] +pub(crate) fn _vsubq_s16(lhs: int16x8_t, rhs: int16x8_t) -> int16x8_t { + unsafe { vsubq_s16(lhs, rhs) } +} + +#[inline(always)] +pub(crate) fn _vmulq_n_s16(v: int16x8_t, c: i16) -> int16x8_t { + unsafe { vmulq_n_s16(v, c) } +} + +#[inline(always)] +pub(crate) fn _vmulq_n_u16(v: uint16x8_t, c: u16) -> uint16x8_t { + unsafe { vmulq_n_u16(v, c) } +} + +#[inline(always)] +pub(crate) fn _vshrq_n_s16(v: int16x8_t) -> int16x8_t { + unsafe { vshrq_n_s16::(v) } +} + +#[inline(always)] +pub(crate) fn _vshrq_n_u16(v: uint16x8_t) -> uint16x8_t { + unsafe { vshrq_n_u16::(v) } +} + +#[inline(always)] +pub(crate) fn _vshlq_n_s16(v: int16x8_t) -> int16x8_t { + unsafe { vshlq_n_s16::(v) } +} + +#[inline(always)] +pub(crate) fn _vshlq_n_u32(v: uint32x4_t) -> uint32x4_t { + unsafe { vshlq_n_u32::(v) } +} +#[inline(always)] +pub(crate) fn _vqdmulhq_n_s16(k: int16x8_t, b: i16) -> int16x8_t { + unsafe { vqdmulhq_n_s16(k, b) } +} +#[inline(always)] +pub(crate) fn _vqdmulhq_s16(v: int16x8_t, c: int16x8_t) -> int16x8_t { + unsafe { vqdmulhq_s16(v, c) } +} +#[inline(always)] +pub(crate) fn _vcgeq_s16(v: int16x8_t, c: int16x8_t) -> uint16x8_t { + unsafe { vcgeq_s16(v, c) } +} +#[inline(always)] +pub(crate) fn _vandq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unsafe { vandq_s16(a, b) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_s16_u16(m0: uint16x8_t) -> int16x8_t { + unsafe { vreinterpretq_s16_u16(m0) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_u16_s16(m0: int16x8_t) -> uint16x8_t { + unsafe { vreinterpretq_u16_s16(m0) } +} +#[inline(always)] +pub(crate) fn _vmulq_s16(v: int16x8_t, c: int16x8_t) -> int16x8_t { + unsafe { vmulq_s16(v, c) } +} +#[inline(always)] +pub(crate) fn _veorq_s16(mask: int16x8_t, shifted: int16x8_t) -> int16x8_t { + unsafe { veorq_s16(mask, shifted) } +} +#[inline(always)] +pub(crate) fn _vdupq_n_u32(value: u32) -> uint32x4_t { + unsafe { vdupq_n_u32(value) } +} +#[inline(always)] +pub(crate) fn _vaddq_u32(compressed: uint32x4_t, half: uint32x4_t) -> uint32x4_t { + unsafe { vaddq_u32(compressed, half) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_s32_u32(compressed: uint32x4_t) -> int32x4_t { + unsafe { vreinterpretq_s32_u32(compressed) } +} +#[inline(always)] +pub(crate) fn _vqdmulhq_n_s32(a: int32x4_t, b: i32) -> int32x4_t { + unsafe { vqdmulhq_n_s32(a, b) } +} + +#[inline(always)] +pub(super) fn _vreinterpretq_u32_s32(a: int32x4_t) -> uint32x4_t { + unsafe { vreinterpretq_u32_s32(a) } +} + +#[inline(always)] +pub(super) fn _vshrq_n_u32(a: uint32x4_t) -> uint32x4_t { + unsafe { vshrq_n_u32::(a) } +} +#[inline(always)] +pub(crate) fn _vandq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t { + unsafe { vandq_u32(a, b) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_u32_s16(a: int16x8_t) -> uint32x4_t { + unsafe { vreinterpretq_u32_s16(a) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_s16_u32(a: uint32x4_t) -> int16x8_t { + unsafe { vreinterpretq_s16_u32(a) } +} +#[inline(always)] +pub(crate) fn _vtrn1q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unsafe { vtrn1q_s16(a, b) } +} +#[inline(always)] +pub(crate) fn _vtrn2q_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unsafe { vtrn2q_s16(a, b) } +} +#[inline(always)] +pub(crate) fn _vmulq_n_u32(a: uint32x4_t, b: u32) -> uint32x4_t { + unsafe { vmulq_n_u32(a, b) } +} + +#[inline(always)] +pub(super) fn _vtrn1q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { + unsafe { vtrn1q_s32(a, b) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_s16_s32(a: int32x4_t) -> int16x8_t { + unsafe { vreinterpretq_s16_s32(a) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_s32_s16(a: int16x8_t) -> int32x4_t { + unsafe { vreinterpretq_s32_s16(a) } +} + +#[inline(always)] +pub(super) fn _vtrn2q_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { + unsafe { vtrn2q_s32(a, b) } +} +#[inline(always)] +pub(crate) fn _vtrn1q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { + unsafe { vtrn1q_s64(a, b) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_s16_s64(a: int64x2_t) -> int16x8_t { + unsafe { vreinterpretq_s16_s64(a) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_s64_s16(a: int16x8_t) -> int64x2_t { + unsafe { vreinterpretq_s64_s16(a) } +} +#[inline(always)] +pub(crate) fn _vtrn2q_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { + unsafe { vtrn2q_s64(a, b) } +} +#[inline(always)] +pub(crate) fn _vmull_s16(a: int16x4_t, b: int16x4_t) -> int32x4_t { + unsafe { vmull_s16(a, b) } +} +#[inline(always)] +pub(crate) fn _vget_low_s16(a: int16x8_t) -> int16x4_t { + unsafe { vget_low_s16(a) } +} +#[inline(always)] +pub(crate) fn _vmull_high_s16(a: int16x8_t, b: int16x8_t) -> int32x4_t { + unsafe { vmull_high_s16(a, b) } +} +#[inline(always)] +pub(crate) fn _vmlal_s16(a: int32x4_t, b: int16x4_t, c: int16x4_t) -> int32x4_t { + unsafe { vmlal_s16(a, b, c) } +} +#[inline(always)] +pub(crate) fn _vmlal_high_s16(a: int32x4_t, b: int16x8_t, c: int16x8_t) -> int32x4_t { + unsafe { vmlal_high_s16(a, b, c) } +} +#[inline(always)] +pub(crate) fn _vld1q_u8(ptr: &[u8]) -> uint8x16_t { + unsafe { vld1q_u8(ptr.as_ptr()) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_u8_s16(a: int16x8_t) -> uint8x16_t { + unsafe { vreinterpretq_u8_s16(a) } +} +#[inline(always)] +pub(crate) fn _vqtbl1q_u8(t: uint8x16_t, idx: uint8x16_t) -> uint8x16_t { + unsafe { vqtbl1q_u8(t, idx) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_s16_u8(a: uint8x16_t) -> int16x8_t { + unsafe { vreinterpretq_s16_u8(a) } +} +#[inline(always)] +pub(crate) fn _vshlq_s16(a: int16x8_t, b: int16x8_t) -> int16x8_t { + unsafe { vshlq_s16(a, b) } +} +#[inline(always)] +pub(crate) fn _vshlq_u16(a: uint16x8_t, b: int16x8_t) -> uint16x8_t { + unsafe { vshlq_u16(a, b) } +} +#[inline(always)] +pub(crate) fn _vaddv_u16(a: uint16x4_t) -> u16 { + unsafe { vaddv_u16(a) } +} +#[inline(always)] +pub(crate) fn _vget_low_u16(a: uint16x8_t) -> uint16x4_t { + unsafe { vget_low_u16(a) } +} +#[inline(always)] +pub(crate) fn _vget_high_u16(a: uint16x8_t) -> uint16x4_t { + unsafe { vget_high_u16(a) } +} +#[inline(always)] +pub(crate) fn _vaddvq_s16(a: int16x8_t) -> i16 { + unsafe { vaddvq_s16(a) } +} + +#[inline(always)] +pub(super) fn _vsliq_n_s32(a: int32x4_t, b: int32x4_t) -> int32x4_t { + unsafe { vsliq_n_s32::(a, b) } +} + +#[inline(always)] +pub(super) fn _vreinterpretq_s64_s32(a: int32x4_t) -> int64x2_t { + unsafe { vreinterpretq_s64_s32(a) } +} + +#[inline(always)] +pub(super) fn _vsliq_n_s64(a: int64x2_t, b: int64x2_t) -> int64x2_t { + unsafe { vsliq_n_s64::(a, b) } +} + +#[inline(always)] +pub(super) fn _vreinterpretq_u8_s64(a: int64x2_t) -> uint8x16_t { + unsafe { vreinterpretq_u8_s64(a) } +} + +#[inline(always)] +pub(super) fn _vst1q_u8(out: &mut [u8], v: uint8x16_t) { + unsafe { vst1q_u8(out.as_mut_ptr(), v) } +} +#[inline(always)] +pub(crate) fn _vdupq_n_u16(value: u16) -> uint16x8_t { + unsafe { vdupq_n_u16(value) } +} +#[inline(always)] +pub(crate) fn _vandq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t { + unsafe { vandq_u16(a, b) } +} +#[inline(always)] +pub(crate) fn _vreinterpretq_u16_u8(a: uint8x16_t) -> uint16x8_t { + unsafe { vreinterpretq_u16_u8(a) } +} +#[inline(always)] +pub(crate) fn _vld1q_u16(ptr: &[u16]) -> uint16x8_t { + unsafe { vld1q_u16(ptr.as_ptr()) } +} +#[inline(always)] +pub(crate) fn _vcleq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t { + unsafe { vcleq_s16(a, b) } +} +#[inline(always)] +pub(crate) fn _vaddvq_u16(a: uint16x8_t) -> u16 { + unsafe { vaddvq_u16(a) } +} diff --git a/polynomials-aarch64/src/rejsample.rs b/polynomials-aarch64/src/rejsample.rs new file mode 100644 index 000000000..64e64a0dc --- /dev/null +++ b/polynomials-aarch64/src/rejsample.rs @@ -0,0 +1,797 @@ +#![forbid(unsafe_code)] + +use crate::neon::*; + +/// This table is taken from PQClean. It is used in rej_sample +// It implements the following logic: +// let mut index : [u8;16] = [0u8; 16]; +// let mut idx = 0; +// for i in 0..8 { +// if used > 0 { +// let next = used.trailing_zeros(); +// idx = idx + next; +// index[i*2] = (idx*2) as u8; +// index[i*2+1] = (idx*2 + 1) as u8; +// idx = idx + 1; +// used = used >> (next+1); +// } +// } +// let index_vec = unsafe { vld1q_u8(index.as_ptr() as *const u8) }; +// End of index table lookup calculation + +const IDX_TABLE: [[u8; 16]; 256] = [ + [ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, + ], // 0 + [ + 0, 1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 1 + [ + 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 2 + [ + 0, 1, 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 3 + [ + 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 4 + [ + 0, 1, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 5 + [ + 2, 3, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 6 + [ + 0, 1, 2, 3, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 7 + [ + 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 8 + [ + 0, 1, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 9 + [ + 2, 3, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 10 + [ + 0, 1, 2, 3, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 11 + [ + 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 12 + [ + 0, 1, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 13 + [ + 2, 3, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 14 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 15 + [ + 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 16 + [ + 0, 1, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 17 + [ + 2, 3, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 18 + [ + 0, 1, 2, 3, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 19 + [ + 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 20 + [ + 0, 1, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 21 + [ + 2, 3, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 22 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 23 + [ + 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 24 + [ + 0, 1, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 25 + [ + 2, 3, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 26 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 27 + [ + 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 28 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 29 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 30 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 31 + [ + 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 32 + [ + 0, 1, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 33 + [ + 2, 3, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 34 + [ + 0, 1, 2, 3, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 35 + [ + 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 36 + [ + 0, 1, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 37 + [ + 2, 3, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 38 + [ + 0, 1, 2, 3, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 39 + [ + 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 40 + [ + 0, 1, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 41 + [ + 2, 3, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 42 + [ + 0, 1, 2, 3, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 43 + [ + 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 44 + [ + 0, 1, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 45 + [ + 2, 3, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 46 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 47 + [ + 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 48 + [ + 0, 1, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 49 + [ + 2, 3, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 50 + [ + 0, 1, 2, 3, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 51 + [ + 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 52 + [ + 0, 1, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 53 + [ + 2, 3, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 54 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 55 + [ + 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 56 + [ + 0, 1, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 57 + [ + 2, 3, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 58 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 59 + [ + 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 60 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 61 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 62 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff], // 63 + [ + 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 64 + [ + 0, 1, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 65 + [ + 2, 3, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 66 + [ + 0, 1, 2, 3, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 67 + [ + 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 68 + [ + 0, 1, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 69 + [ + 2, 3, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 70 + [ + 0, 1, 2, 3, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 71 + [ + 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 72 + [ + 0, 1, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 73 + [ + 2, 3, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 74 + [ + 0, 1, 2, 3, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 75 + [ + 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 76 + [ + 0, 1, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 77 + [ + 2, 3, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 78 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 79 + [ + 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 80 + [ + 0, 1, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 81 + [ + 2, 3, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 82 + [ + 0, 1, 2, 3, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 83 + [ + 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 84 + [ + 0, 1, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 85 + [ + 2, 3, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 86 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 87 + [ + 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 88 + [ + 0, 1, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 89 + [ + 2, 3, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 90 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 91 + [ + 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 92 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 93 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 94 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff], // 95 + [ + 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 96 + [ + 0, 1, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 97 + [ + 2, 3, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 98 + [ + 0, 1, 2, 3, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 99 + [ + 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 100 + [ + 0, 1, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 101 + [ + 2, 3, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 102 + [ + 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 103 + [ + 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 104 + [ + 0, 1, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 105 + [ + 2, 3, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 106 + [ + 0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 107 + [ + 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 108 + [ + 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 109 + [ + 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 110 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 111 + [ + 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 112 + [ + 0, 1, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 113 + [ + 2, 3, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 114 + [ + 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 115 + [ + 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 116 + [ + 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 117 + [ + 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 118 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 119 + [ + 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 120 + [ + 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 121 + [ + 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 122 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 123 + [ + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 124 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 125 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 126 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff], // 127 + [ + 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 128 + [ + 0, 1, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 129 + [ + 2, 3, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 130 + [ + 0, 1, 2, 3, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 131 + [ + 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 132 + [ + 0, 1, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 133 + [ + 2, 3, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 134 + [ + 0, 1, 2, 3, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 135 + [ + 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 136 + [ + 0, 1, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 137 + [ + 2, 3, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 138 + [ + 0, 1, 2, 3, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 139 + [ + 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 140 + [ + 0, 1, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 141 + [ + 2, 3, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 142 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 143 + [ + 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 144 + [ + 0, 1, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 145 + [ + 2, 3, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 146 + [ + 0, 1, 2, 3, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 147 + [ + 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 148 + [ + 0, 1, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 149 + [ + 2, 3, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 150 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 151 + [ + 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 152 + [ + 0, 1, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 153 + [ + 2, 3, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 154 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 155 + [ + 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 156 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 157 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 158 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff], // 159 + [ + 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 160 + [ + 0, 1, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 161 + [ + 2, 3, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 162 + [ + 0, 1, 2, 3, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 163 + [ + 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 164 + [ + 0, 1, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 165 + [ + 2, 3, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 166 + [ + 0, 1, 2, 3, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 167 + [ + 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 168 + [ + 0, 1, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 169 + [ + 2, 3, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 170 + [ + 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 171 + [ + 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 172 + [ + 0, 1, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 173 + [ + 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 174 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 175 + [ + 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 176 + [ + 0, 1, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 177 + [ + 2, 3, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 178 + [ + 0, 1, 2, 3, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 179 + [ + 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 180 + [ + 0, 1, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 181 + [ + 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 182 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 183 + [ + 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 184 + [ + 0, 1, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 185 + [ + 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 186 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 187 + [ + 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 188 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 189 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 190 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff], // 191 + [ + 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 192 + [ + 0, 1, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 193 + [ + 2, 3, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 194 + [ + 0, 1, 2, 3, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 195 + [ + 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 196 + [ + 0, 1, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 197 + [ + 2, 3, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 198 + [ + 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 199 + [ + 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 200 + [ + 0, 1, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 201 + [ + 2, 3, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 202 + [ + 0, 1, 2, 3, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 203 + [ + 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 204 + [ + 0, 1, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 205 + [ + 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 206 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 207 + [ + 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 208 + [ + 0, 1, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 209 + [ + 2, 3, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 210 + [ + 0, 1, 2, 3, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 211 + [ + 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 212 + [ + 0, 1, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 213 + [ + 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 214 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 215 + [ + 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 216 + [ + 0, 1, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 217 + [ + 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 218 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 219 + [ + 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 220 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 221 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 222 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff], // 223 + [ + 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 224 + [ + 0, 1, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 225 + [ + 2, 3, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 226 + [ + 0, 1, 2, 3, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 227 + [ + 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 228 + [ + 0, 1, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 229 + [ + 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 230 + [ + 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 231 + [ + 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 232 + [ + 0, 1, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 233 + [ + 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 234 + [ + 0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 235 + [ + 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 236 + [ + 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 237 + [ + 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 238 + [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 239 + [ + 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 240 + [ + 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 241 + [ + 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 242 + [ + 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 243 + [ + 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 244 + [ + 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 245 + [ + 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 246 + [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 247 + [ + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 248 + [ + 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 249 + [ + 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 250 + [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 251 + [ + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 252 + [0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 253 + [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 254 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // 255 +]; + +#[inline(always)] +pub(crate) fn rej_sample(a: &[u8], out: &mut [i16]) -> usize { + let neon_bits: [u16; 8] = [0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80]; + let bits = _vld1q_u16(&neon_bits); + let fm = _vdupq_n_s16(3328); + + let input = super::simd128ops::deserialize_12(a); + let mask0 = _vcleq_s16(input.low, fm); + let mask1 = _vcleq_s16(input.high, fm); + let masked = _vandq_u16(mask0, bits); + let used0 = _vaddvq_u16(masked); + let masked = _vandq_u16(mask1, bits); + let used1 = _vaddvq_u16(masked); + let pick0 = used0.count_ones(); + let pick1 = used1.count_ones(); + + // XXX: the indices used0 and used1 must be < 256. + let index_vec0 = _vld1q_u8(&IDX_TABLE[(used0 as u8) as usize]); + let shifted0 = _vreinterpretq_s16_u8(_vqtbl1q_u8(_vreinterpretq_u8_s16(input.low), index_vec0)); + let index_vec1 = _vld1q_u8(&IDX_TABLE[(used1 as u8) as usize]); + let shifted1 = + _vreinterpretq_s16_u8(_vqtbl1q_u8(_vreinterpretq_u8_s16(input.high), index_vec1)); + + let idx0 = usize::try_from(pick0).unwrap(); + _vst1q_s16(&mut out[0..8], shifted0); + _vst1q_s16(&mut out[idx0..idx0 + 8], shifted1); + (pick0 + pick1) as usize +} diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Arithmetic.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Arithmetic.fst new file mode 100644 index 000000000..cd19825be --- /dev/null +++ b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Arithmetic.fst @@ -0,0 +1,159 @@ +module Libcrux_polynomials_avx2.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let v_BARRETT_MULTIPLIER: i16 = 20159s + +let add (lhs rhs: u8) : u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs + +let bitwise_and_with_constant (vector: u8) (constant: i16) : u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_and_si256 vector + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 constant <: u8) + +let multiply_by_constant (vector: u8) (constant: i16) : u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 vector + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 constant <: u8) + +let shift_left (v_SHIFT_BY: i32) (vector: u8) : u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_slli_epi16 v_SHIFT_BY vector + +let shift_right (v_SHIFT_BY: i32) (vector: u8) : u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srai_epi16 v_SHIFT_BY vector + +/// See Section 3.2 of the implementation notes document for an explanation +/// of this code. +let barrett_reduce (vector: u8) : u8 = + let t:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 vector + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 v_BARRETT_MULTIPLIER <: u8) + in + let t:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 t + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 512s <: u8) + in + let quotient:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srai_epi16 10l t in + let quotient_times_field_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 quotient + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS + + <: + u8) + in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 vector quotient_times_field_modulus + +let cond_subtract_3329_ (vector: u8) : u8 = + let field_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS + in + let vv_minus_field_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 vector field_modulus + in + let sign_mask:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srai_epi16 15l vv_minus_field_modulus + in + let conditional_add_field_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_and_si256 sign_mask field_modulus + in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 vv_minus_field_modulus + conditional_add_field_modulus + +let montgomery_multiply_by_constant (vector: u8) (constant: i16) : u8 = + let constant:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 constant in + let value_low:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 vector constant + in + let k:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 value_low + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 (cast (Libcrux_traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u32) + <: + i16) + <: + u8) + in + let k_times_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 k + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS + + <: + u8) + in + let value_high:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 vector constant + in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 value_high k_times_modulus + +let montgomery_multiply_by_constants (v c: u8) : u8 = + let value_low:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 v c in + let k:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 value_low + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 (cast (Libcrux_traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u32) + <: + i16) + <: + u8) + in + let k_times_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 k + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS + + <: + u8) + in + let value_high:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 v c in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 value_high k_times_modulus + +let montgomery_reduce_i32s (v: u8) : u8 = + let k:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 v + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi32 (cast (Libcrux_traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u32) + <: + i32) + <: + u8) + in + let k_times_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mulhi_epi16 k + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi32 (cast (Libcrux_traits.v_FIELD_MODULUS + <: + i16) + <: + i32) + <: + u8) + in + let value_high:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srli_epi32 16l v in + let result:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 value_high k_times_modulus + in + let result:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_slli_epi32 16l result in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_srai_epi32 16l result + +let sub (lhs rhs: u8) : u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_sub_epi16 lhs rhs + +let montgomery_multiply_m128i_by_constants (v c: u8) : u8 = + let value_low:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_mullo_epi16 v c in + let k:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm_mullo_epi16 value_low + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_set1_epi16 (cast (Libcrux_traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u32) + <: + i16) + <: + u8) + in + let k_times_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm_mulhi_epi16 k + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_set1_epi16 Libcrux_traits.v_FIELD_MODULUS + <: + u8) + in + let value_high:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_mulhi_epi16 v c in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm_sub_epi16 value_high k_times_modulus diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Compress.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Compress.fst new file mode 100644 index 000000000..252e284a9 --- /dev/null +++ b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Compress.fst @@ -0,0 +1,192 @@ +module Libcrux_polynomials_avx2.Compress +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let decompress_ciphertext_coefficient (v_COEFFICIENT_BITS: i32) (vector: u8) : u8 = + let field_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi32 (cast (Libcrux_traits.v_FIELD_MODULUS + <: + i16) + <: + i32) + in + let two_pow_coefficient_bits:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi32 (1l <=. 0l <: bool) && (v_CONTROL <. 256l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL >= 0 && CONTROL < 256" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_castsi128_si256 (vector: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_castsi256_si128 (vector: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_cmpgt_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_cvtepi16_epi32 (vector: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_extracti128_si256 (v_CONTROL: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_CONTROL =. 0l <: bool) || (v_CONTROL =. 1l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL == 0 || CONTROL == 1" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_inserti128_si256 (v_CONTROL: i32) (vector vector_i128: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_CONTROL =. 0l <: bool) || (v_CONTROL =. 1l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL == 0 || CONTROL == 1" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_loadu_si256 (input: t_Slice i16) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + match Core.Slice.impl__len input, sz 16 <: (usize & usize) with + | left_val, right_val -> + if ~.(left_val =. right_val <: bool) + then + let kind:Core.Panicking.t_AssertKind = + Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind + in + Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind + left_val + right_val + (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_madd_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_mul_epu32 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_mulhi_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_mullo_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_mullo_epi32 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_packs_epi32 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_permute4x64_epi64 (v_CONTROL: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_CONTROL >=. 0l <: bool) && (v_CONTROL <. 256l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL >= 0 && CONTROL < 256" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_permutevar8x32_epi32 (vector control: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_set1_epi16 (constant: i16) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_set1_epi32 (constant: i32) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_set_epi16 + (input15 input14 input13 input12 input11 input10 input9 input8 input7 input6 input5 input4 input3 input2 input1 input0: + i16) + : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_set_epi32 (input7 input6 input5 input4 input3 input2 input1 input0: i32) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_set_epi8 + (byte31 byte30 byte29 byte28 byte27 byte26 byte25 byte24 byte23 byte22 byte21 byte20 byte19 byte18 byte17 byte16 byte15 byte14 byte13 byte12 byte11 byte10 byte9 byte8 byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0: + i8) + : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_setzero_si256 (_: Prims.unit) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_shuffle_epi32 (v_CONTROL: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_CONTROL >=. 0l <: bool) && (v_CONTROL <. 256l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: CONTROL >= 0 && CONTROL < 256" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_shuffle_epi8 (vector control: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_slli_epi16 (v_SHIFT_BY: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 16l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 16" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_slli_epi32 (v_SHIFT_BY: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 32l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 32" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_sllv_epi32 (vector counts: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_srai_epi16 (v_SHIFT_BY: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 16l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 16" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_srai_epi32 (v_SHIFT_BY: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 32l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 32" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_srli_epi16 (v_SHIFT_BY: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 16l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 16" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_srli_epi32 (v_SHIFT_BY: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 32l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 32" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_srli_epi64 (v_SHIFT_BY: i32) (vector: u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + if ~.((v_SHIFT_BY >=. 0l <: bool) && (v_SHIFT_BY <. 64l <: bool)) + then + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: SHIFT_BY >= 0 && SHIFT_BY < 64" + + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_storeu_si256 (output: t_Slice i16) (vector: u8) : t_Slice i16 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + match Core.Slice.impl__len output, sz 16 <: (usize & usize) with + | left_val, right_val -> + if ~.(left_val =. right_val <: bool) + then + let kind:Core.Panicking.t_AssertKind = + Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind + in + Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind + left_val + right_val + (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in + () + in + let hax_temp_output:Prims.unit = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + in + output + +let mm256_sub_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_unpackhi_epi32 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_unpackhi_epi64 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_unpacklo_epi32 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm256_xor_si256 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_add_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_loadu_si128 (input: t_Slice u8) : u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + match Core.Slice.impl__len input, sz 16 <: (usize & usize) with + | left_val, right_val -> + if ~.(left_val =. right_val <: bool) + then + let kind:Core.Panicking.t_AssertKind = + Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind + in + Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind + left_val + right_val + (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in + () + in + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_movemask_epi8 (vector: u8) : i32 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_mulhi_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_mullo_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_packs_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_set1_epi16 (constant: i16) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_set_epi8 + (byte15 byte14 byte13 byte12 byte11 byte10 byte9 byte8 byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0: + u8) + : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_shuffle_epi8 (vector control: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + +let mm_storeu_bytes_si128 (output: t_Slice u8) (vector: u8) : t_Slice u8 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + match Core.Slice.impl__len output, sz 16 <: (usize & usize) with + | left_val, right_val -> + if ~.(left_val =. right_val <: bool) + then + let kind:Core.Panicking.t_AssertKind = + Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind + in + Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind + left_val + right_val + (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in + () + in + let hax_temp_output:Prims.unit = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + in + output + +let mm_storeu_si128 (output: t_Slice i16) (vector: u8) : t_Slice i16 = + let _:Prims.unit = + if true + then + let _:Prims.unit = + match Core.Slice.impl__len output, sz 8 <: (usize & usize) with + | left_val, right_val -> + if ~.(left_val =. right_val <: bool) + then + let kind:Core.Panicking.t_AssertKind = + Core.Panicking.AssertKind_Eq <: Core.Panicking.t_AssertKind + in + Rust_primitives.Hax.never_to_any (Core.Panicking.assert_failed kind + left_val + right_val + (Core.Option.Option_None <: Core.Option.t_Option Core.Fmt.t_Arguments) + <: + Rust_primitives.Hax.t_Never) + in + () + in + let hax_temp_output:Prims.unit = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) + in + output + +let mm_sub_epi16 (lhs rhs: u8) : u8 = + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not implemented" + <: + Rust_primitives.Hax.t_Never) diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Ntt.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Ntt.fst new file mode 100644 index 000000000..5b788b5ad --- /dev/null +++ b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Ntt.fst @@ -0,0 +1,192 @@ +module Libcrux_polynomials_avx2.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let ntt_multiply__PERMUTE_WITH: i32 = 216l + +let inv_ntt_layer_1_step (vector: u8) (zeta0 zeta1 zeta2 zeta3: i16) : u8 = + let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 245l vector in + let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 160l vector in + let rhs:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 rhs + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (-1s) (-1s) 1s 1s (-1s) (-1s) + 1s 1s (-1s) (-1s) 1s 1s (-1s) (-1s) 1s 1s + <: + u8) + in + let sum:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs in + let sum_times_zetas:u8 = + Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constants sum + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 zeta3 zeta3 0s 0s zeta2 zeta2 + 0s 0s zeta1 zeta1 0s 0s zeta0 zeta0 0s 0s + <: + u8) + in + let sum:u8 = Libcrux_polynomials_avx2.Arithmetic.barrett_reduce sum in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_blend_epi16 204l sum sum_times_zetas + +let inv_ntt_layer_2_step (vector: u8) (zeta0 zeta1: i16) : u8 = + let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_permute4x64_epi64 245l vector in + let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_permute4x64_epi64 160l vector in + let rhs:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi16 rhs + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (-1s) (-1s) (-1s) (-1s) 1s 1s + 1s 1s (-1s) (-1s) (-1s) (-1s) 1s 1s 1s 1s + <: + u8) + in + let sum:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs in + let sum_times_zetas:u8 = + Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constants sum + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 zeta1 zeta1 zeta1 zeta1 0s 0s + 0s 0s zeta0 zeta0 zeta0 zeta0 0s 0s 0s 0s + <: + u8) + in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_blend_epi16 240l sum sum_times_zetas + +let inv_ntt_layer_3_step (vector: u8) (zeta: i16) : u8 = + let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l vector in + let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 vector in + let lower_coefficients:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_add_epi16 lhs rhs in + let upper_coefficients:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_sub_epi16 lhs rhs in + let upper_coefficients:u8 = + Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_m128i_by_constants upper_coefficients + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_set1_epi16 zeta <: u8) + in + let combined:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi128_si256 lower_coefficients + in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_inserti128_si256 1l + combined + upper_coefficients + +let ntt_layer_1_step (vector: u8) (zeta0 zeta1 zeta2 zeta3: i16) : u8 = + let zetas:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (Core.Ops.Arith.Neg.neg zeta3 + <: + i16) (Core.Ops.Arith.Neg.neg zeta3 <: i16) zeta3 zeta3 (Core.Ops.Arith.Neg.neg zeta2 <: i16) + (Core.Ops.Arith.Neg.neg zeta2 <: i16) zeta2 zeta2 (Core.Ops.Arith.Neg.neg zeta1 <: i16) + (Core.Ops.Arith.Neg.neg zeta1 <: i16) zeta1 zeta1 (Core.Ops.Arith.Neg.neg zeta0 <: i16) + (Core.Ops.Arith.Neg.neg zeta0 <: i16) zeta0 zeta0 + in + let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 245l vector in + let rhs:u8 = Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constants rhs zetas in + let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 160l vector in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs + +let ntt_layer_2_step (vector: u8) (zeta0 zeta1: i16) : u8 = + let zetas:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (Core.Ops.Arith.Neg.neg zeta1 + <: + i16) (Core.Ops.Arith.Neg.neg zeta1 <: i16) (Core.Ops.Arith.Neg.neg zeta1 <: i16) + (Core.Ops.Arith.Neg.neg zeta1 <: i16) zeta1 zeta1 zeta1 zeta1 + (Core.Ops.Arith.Neg.neg zeta0 <: i16) (Core.Ops.Arith.Neg.neg zeta0 <: i16) + (Core.Ops.Arith.Neg.neg zeta0 <: i16) (Core.Ops.Arith.Neg.neg zeta0 <: i16) zeta0 zeta0 zeta0 + zeta0 + in + let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 238l vector in + let rhs:u8 = Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constants rhs zetas in + let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi32 68l vector in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi16 lhs rhs + +let ntt_layer_3_step (vector: u8) (zeta: i16) : u8 = + let rhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l vector in + let rhs:u8 = + Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_m128i_by_constants rhs + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_set1_epi16 zeta <: u8) + in + let lhs:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 vector in + let lower_coefficients:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_add_epi16 lhs rhs in + let upper_coefficients:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm_sub_epi16 lhs rhs in + let combined:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi128_si256 lower_coefficients + in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_inserti128_si256 1l + combined + upper_coefficients + +let ntt_multiply (lhs rhs: u8) (zeta0 zeta1 zeta2 zeta3: i16) : u8 = + let shuffle_with:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi8 15y 14y 11y 10y 7y 6y 3y 2y 13y + 12y 9y 8y 5y 4y 1y 0y 15y 14y 11y 10y 7y 6y 3y 2y 13y 12y 9y 8y 5y 4y 1y 0y + in + let lhs_shuffled:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi8 lhs shuffle_with + in + let lhs_shuffled:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_permute4x64_epi64 216l lhs_shuffled + in + let lhs_evens:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 lhs_shuffled + in + let lhs_evens:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cvtepi16_epi32 lhs_evens + in + let lhs_odds:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l lhs_shuffled + in + let lhs_odds:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cvtepi16_epi32 lhs_odds in + let rhs_shuffled:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi8 rhs shuffle_with + in + let rhs_shuffled:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_permute4x64_epi64 216l rhs_shuffled + in + let rhs_evens:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 rhs_shuffled + in + let rhs_evens:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cvtepi16_epi32 rhs_evens + in + let rhs_odds:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l rhs_shuffled + in + let rhs_odds:u8 = Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cvtepi16_epi32 rhs_odds in + let left:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi32 lhs_evens rhs_evens + in + let right:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi32 lhs_odds rhs_odds + in + let right:u8 = Libcrux_polynomials_avx2.Arithmetic.montgomery_reduce_i32s right in + let right:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_mullo_epi32 right + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi32 (Core.Ops.Arith.Neg.neg (cast ( + zeta3 <: i16) + <: + i32) + <: + i32) + (cast (zeta3 <: i16) <: i32) + (Core.Ops.Arith.Neg.neg (cast (zeta2 <: i16) <: i32) <: i32) + (cast (zeta2 <: i16) <: i32) + (Core.Ops.Arith.Neg.neg (cast (zeta1 <: i16) <: i32) <: i32) + (cast (zeta1 <: i16) <: i32) + (Core.Ops.Arith.Neg.neg (cast (zeta0 <: i16) <: i32) <: i32) + (cast (zeta0 <: i16) <: i32) + <: + u8) + in + let products_left:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_add_epi32 left right + in + let products_left:u8 = Libcrux_polynomials_avx2.Arithmetic.montgomery_reduce_i32s products_left in + let rhs_adjacent_swapped:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_shuffle_epi8 rhs + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi8 13y 12y 15y 14y 9y 8y 11y 10y + 5y 4y 7y 6y 1y 0y 3y 2y 13y 12y 15y 14y 9y 8y 11y 10y 5y 4y 7y 6y 1y 0y 3y 2y + <: + u8) + in + let products_right:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_madd_epi16 lhs rhs_adjacent_swapped + in + let products_right:u8 = + Libcrux_polynomials_avx2.Arithmetic.montgomery_reduce_i32s products_right + in + let products_right:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_slli_epi32 16l products_right + in + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_blend_epi16 170l products_left products_right diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Portable.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Portable.fst new file mode 100644 index 000000000..541e25541 --- /dev/null +++ b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Portable.fst @@ -0,0 +1,429 @@ +module Libcrux_polynomials_avx2.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +unfold +let t_FieldElement = i16 + +type t_PortableVector = { f_elements:t_Array i16 (sz 16) } + +let from_i16_array (array: t_Array i16 (sz 16)) : t_PortableVector = + { f_elements = array } <: t_PortableVector + +let serialize_11_ (v: t_PortableVector) : t_Array u8 (sz 22) = + let result:t_Array u8 (sz 22) = Rust_primitives.Hax.repeat 0uy (sz 22) in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 0) + (cast (v.f_elements.[ sz 0 ] <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 1) + (((cast ((v.f_elements.[ sz 1 ] <: i16) &. 31s <: i16) <: u8) <>! 8l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 2) + (((cast ((v.f_elements.[ sz 2 ] <: i16) &. 3s <: i16) <: u8) <>! 5l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 3) + (cast (((v.f_elements.[ sz 2 ] <: i16) >>! 2l <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 4) + (((cast ((v.f_elements.[ sz 3 ] <: i16) &. 127s <: i16) <: u8) <>! 10l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 5) + (((cast ((v.f_elements.[ sz 4 ] <: i16) &. 15s <: i16) <: u8) <>! 7l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 6) + (((cast ((v.f_elements.[ sz 5 ] <: i16) &. 1s <: i16) <: u8) <>! 4l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 7) + (cast (((v.f_elements.[ sz 5 ] <: i16) >>! 1l <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 8) + (((cast ((v.f_elements.[ sz 6 ] <: i16) &. 63s <: i16) <: u8) <>! 9l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 9) + (((cast ((v.f_elements.[ sz 7 ] <: i16) &. 7s <: i16) <: u8) <>! 6l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 10) + (cast ((v.f_elements.[ sz 7 ] <: i16) >>! 3l <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 11) + (cast (v.f_elements.[ sz 8 +! sz 0 <: usize ] <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 12) + (((cast ((v.f_elements.[ sz 8 +! sz 1 <: usize ] <: i16) &. 31s <: i16) <: u8) <>! 8l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 13) + (((cast ((v.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) &. 3s <: i16) <: u8) <>! 5l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 14) + (cast (((v.f_elements.[ sz 8 +! sz 2 <: usize ] <: i16) >>! 2l <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 15) + (((cast ((v.f_elements.[ sz 8 +! sz 3 <: usize ] <: i16) &. 127s <: i16) <: u8) <>! 10l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 16) + (((cast ((v.f_elements.[ sz 8 +! sz 4 <: usize ] <: i16) &. 15s <: i16) <: u8) <>! 7l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 17) + (((cast ((v.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) &. 1s <: i16) <: u8) <>! 4l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 18) + (cast (((v.f_elements.[ sz 8 +! sz 5 <: usize ] <: i16) >>! 1l <: i16) &. 255s <: i16) <: u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 19) + (((cast ((v.f_elements.[ sz 8 +! sz 6 <: usize ] <: i16) &. 63s <: i16) <: u8) <>! 9l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 20) + (((cast ((v.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) &. 7s <: i16) <: u8) <>! 6l <: i16) <: u8) + <: + u8) + in + let result:t_Array u8 (sz 22) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + (sz 21) + (cast ((v.f_elements.[ sz 8 +! sz 7 <: usize ] <: i16) >>! 3l <: i16) <: u8) + in + result + +let to_i16_array (v: t_PortableVector) : t_Array i16 (sz 16) = v.f_elements + +let zero (_: Prims.unit) : t_PortableVector = + { f_elements = Rust_primitives.Hax.repeat 0s (sz 16) } <: t_PortableVector + +let deserialize_11_ (bytes: t_Slice u8) : t_PortableVector = + let result:t_PortableVector = zero () in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 0) + ((((cast (bytes.[ sz 1 ] <: u8) <: i16) &. 7s <: i16) <>! 3l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 2) + (((((cast (bytes.[ sz 4 ] <: u8) <: i16) &. 1s <: i16) <>! 6l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 3) + ((((cast (bytes.[ sz 5 ] <: u8) <: i16) &. 15s <: i16) <>! 1l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 4) + ((((cast (bytes.[ sz 6 ] <: u8) <: i16) &. 127s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 5) + (((((cast (bytes.[ sz 8 ] <: u8) <: i16) &. 3s <: i16) <>! 7l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 6) + ((((cast (bytes.[ sz 9 ] <: u8) <: i16) &. 31s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 7) + (((cast (bytes.[ sz 10 ] <: u8) <: i16) <>! 5l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 8) + ((((cast (bytes.[ sz 11 +! sz 1 <: usize ] <: u8) <: i16) &. 7s <: i16) <>! 3l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 10) + (((((cast (bytes.[ sz 11 +! sz 4 <: usize ] <: u8) <: i16) &. 1s <: i16) <>! 6l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 11) + ((((cast (bytes.[ sz 11 +! sz 5 <: usize ] <: u8) <: i16) &. 15s <: i16) <>! 1l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 12) + ((((cast (bytes.[ sz 11 +! sz 6 <: usize ] <: u8) <: i16) &. 127s <: i16) <>! 4l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 13) + (((((cast (bytes.[ sz 11 +! sz 8 <: usize ] <: u8) <: i16) &. 3s <: i16) <>! 7l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 14) + ((((cast (bytes.[ sz 11 +! sz 9 <: usize ] <: u8) <: i16) &. 31s <: i16) <>! 2l <: i16) + <: + i16) + } + <: + t_PortableVector + in + let result:t_PortableVector = + { + result with + f_elements + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_elements + (sz 15) + (((cast (bytes.[ sz 11 +! sz 10 <: usize ] <: u8) <: i16) <>! 5l <: i16) + <: + i16) + } + <: + t_PortableVector + in + result diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Sampling.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Sampling.fst new file mode 100644 index 000000000..65ce23750 --- /dev/null +++ b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Sampling.fst @@ -0,0 +1,2111 @@ +module Libcrux_polynomials_avx2.Sampling +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let v_REJECTION_SAMPLE_SHUFFLE_TABLE: t_Array (t_Array u8 (sz 16)) (sz 256) = + let list = + [ + (let list = + [ + 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 255uy; 255uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 14uy; 15uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 2uy; 3uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; 255uy; + 255uy; 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 0uy; 1uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 2uy; 3uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [ + 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy; 255uy; + 255uy + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [0uy; 1uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + (let list = + [2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy; 255uy; 255uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list); + let list = + [0uy; 1uy; 2uy; 3uy; 4uy; 5uy; 6uy; 7uy; 8uy; 9uy; 10uy; 11uy; 12uy; 13uy; 14uy; 15uy] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 16); + Rust_primitives.Hax.array_of_list 16 list + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 256); + Rust_primitives.Hax.array_of_list 256 list + +let rejection_sample (input: t_Slice u8) (output: t_Slice i16) : (t_Slice i16 & usize) = + let field_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set1_epi16 Libcrux_traits.v_FIELD_MODULUS + in + let potential_coefficients:u8 = Libcrux_polynomials_avx2.Serialize.deserialize_12_ input in + let compare_with_field_modulus:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_cmpgt_epi16 field_modulus + potential_coefficients + in + let good:t_Array u8 (sz 2) = + Libcrux_polynomials_avx2.Serialize.serialize_1_ compare_with_field_modulus + in + let lower_shuffles:t_Array u8 (sz 16) = + v_REJECTION_SAMPLE_SHUFFLE_TABLE.[ cast (good.[ sz 0 ] <: u8) <: usize ] + in + let lower_shuffles:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm_loadu_si128 (Rust_primitives.unsize lower_shuffles + + <: + t_Slice u8) + in + let lower_coefficients:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_castsi256_si128 potential_coefficients + in + let lower_coefficients:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm_shuffle_epi8 lower_coefficients lower_shuffles + in + let output:t_Slice i16 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range output + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 8 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_storeu_si128 (output.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 8 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i16) + lower_coefficients + <: + t_Slice i16) + in + let sampled_count:usize = + cast (Core.Num.impl__u8__count_ones (good.[ sz 0 ] <: u8) <: u32) <: usize + in + let upper_shuffles:t_Array u8 (sz 16) = + v_REJECTION_SAMPLE_SHUFFLE_TABLE.[ cast (good.[ sz 1 ] <: u8) <: usize ] + in + let upper_shuffles:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm_loadu_si128 (Rust_primitives.unsize upper_shuffles + + <: + t_Slice u8) + in + let upper_coefficients:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_extracti128_si256 1l potential_coefficients + in + let upper_coefficients:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm_shuffle_epi8 upper_coefficients upper_shuffles + in + let output:t_Slice i16 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range output + ({ + Core.Ops.Range.f_start = sampled_count; + Core.Ops.Range.f_end = sampled_count +! sz 8 <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm_storeu_si128 (output.[ { + Core.Ops.Range.f_start = sampled_count; + Core.Ops.Range.f_end = sampled_count +! sz 8 <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i16) + upper_coefficients + <: + t_Slice i16) + in + let hax_temp_output:usize = + sampled_count +! (cast (Core.Num.impl__u8__count_ones (good.[ sz 1 ] <: u8) <: u32) <: usize) + in + output, hax_temp_output <: (t_Slice i16 & usize) diff --git a/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Serialize.fst b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Serialize.fst new file mode 100644 index 000000000..f951730a4 --- /dev/null +++ b/polynomials-avx2/proofs/fstar/extraction/Libcrux_polynomials_avx2.Serialize.fst @@ -0,0 +1,557 @@ +module Libcrux_polynomials_avx2.Serialize +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" +open Core +open FStar.Mul + +let deserialize_1_ (bytes: t_Slice u8) : u8 = + let coefficients:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (cast (bytes.[ sz 1 ] <: u8) + <: + i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) + (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) + (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 1 ] <: u8) <: i16) + (cast (bytes.[ sz 1 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) + (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) + (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) + (cast (bytes.[ sz 0 ] <: u8) <: i16) (cast (bytes.[ sz 0 ] <: u8) <: i16) + (cast (bytes.[ sz 0 ] <: u8) <: i16) + in + let shift_lsb_to_msb:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (1s <>! 8l <: i32) <: u8) + in + serialized + +let serialize_10_ (vector: u8) : t_Array u8 (sz 20) = + let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let adjacent_2_combined:u8 = + Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_madd_epi16 vector + (Libcrux_polynomials_avx2.Intrinsics_extraction.mm256_set_epi16 (1s < true); + f_ZERO_post = (fun (_: Prims.unit) (out: t_SIMD256Vector) -> true); + f_ZERO = (fun (_: Prims.unit) -> zero ()); + f_to_i16_array_pre = (fun (v: t_SIMD256Vector) -> true); + f_to_i16_array_post = (fun (v: t_SIMD256Vector) (out: t_Array i16 (sz 16)) -> true); + f_to_i16_array = (fun (v: t_SIMD256Vector) -> to_i16_array v); + f_from_i16_array_pre = (fun (array: t_Slice i16) -> true); + f_from_i16_array_post = (fun (array: t_Slice i16) (out: t_SIMD256Vector) -> true); + f_from_i16_array = (fun (array: t_Slice i16) -> from_i16_array array); + f_add_pre = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> true); + f_add_post = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_add + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> + { f_elements = Libcrux_polynomials_avx2.Arithmetic.add lhs.f_elements rhs.f_elements } + <: + t_SIMD256Vector); + f_sub_pre = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> true); + f_sub_post = (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_sub + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> + { f_elements = Libcrux_polynomials_avx2.Arithmetic.sub lhs.f_elements rhs.f_elements } + <: + t_SIMD256Vector); + f_multiply_by_constant_pre = (fun (v: t_SIMD256Vector) (c: i16) -> true); + f_multiply_by_constant_post = (fun (v: t_SIMD256Vector) (c: i16) (out: t_SIMD256Vector) -> true); + f_multiply_by_constant + = + (fun (v: t_SIMD256Vector) (c: i16) -> + { f_elements = Libcrux_polynomials_avx2.Arithmetic.multiply_by_constant v.f_elements c } + <: + t_SIMD256Vector); + f_bitwise_and_with_constant_pre = (fun (vector: t_SIMD256Vector) (constant: i16) -> true); + f_bitwise_and_with_constant_post + = + (fun (vector: t_SIMD256Vector) (constant: i16) (out: t_SIMD256Vector) -> true); + f_bitwise_and_with_constant + = + (fun (vector: t_SIMD256Vector) (constant: i16) -> + { + f_elements + = + Libcrux_polynomials_avx2.Arithmetic.bitwise_and_with_constant vector.f_elements constant + } + <: + t_SIMD256Vector); + f_shift_right_pre = (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> true); + f_shift_right_post + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_shift_right + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> + { + f_elements = Libcrux_polynomials_avx2.Arithmetic.shift_right v_SHIFT_BY vector.f_elements + } + <: + t_SIMD256Vector); + f_shift_left_pre = (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> true); + f_shift_left_post + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_shift_left + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> + { f_elements = Libcrux_polynomials_avx2.Arithmetic.shift_left v_SHIFT_BY vector.f_elements } + <: + t_SIMD256Vector); + f_cond_subtract_3329_pre = (fun (vector: t_SIMD256Vector) -> true); + f_cond_subtract_3329_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_cond_subtract_3329_ + = + (fun (vector: t_SIMD256Vector) -> + { f_elements = Libcrux_polynomials_avx2.Arithmetic.cond_subtract_3329_ vector.f_elements } + <: + t_SIMD256Vector); + f_barrett_reduce_pre = (fun (vector: t_SIMD256Vector) -> true); + f_barrett_reduce_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_barrett_reduce + = + (fun (vector: t_SIMD256Vector) -> + { f_elements = Libcrux_polynomials_avx2.Arithmetic.barrett_reduce vector.f_elements } + <: + t_SIMD256Vector); + f_montgomery_multiply_by_constant_pre = (fun (vector: t_SIMD256Vector) (constant: i16) -> true); + f_montgomery_multiply_by_constant_post + = + (fun (vector: t_SIMD256Vector) (constant: i16) (out: t_SIMD256Vector) -> true); + f_montgomery_multiply_by_constant + = + (fun (vector: t_SIMD256Vector) (constant: i16) -> + { + f_elements + = + Libcrux_polynomials_avx2.Arithmetic.montgomery_multiply_by_constant vector.f_elements + constant + } + <: + t_SIMD256Vector); + f_compress_1_pre = (fun (vector: t_SIMD256Vector) -> true); + f_compress_1_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_compress_1_ + = + (fun (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_polynomials_avx2.Compress.compress_message_coefficient vector.f_elements + } + <: + t_SIMD256Vector); + f_compress_pre = (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> true); + f_compress_post + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_compress + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_polynomials_avx2.Compress.compress_ciphertext_coefficient v_COEFFICIENT_BITS + vector.f_elements + } + <: + t_SIMD256Vector); + f_decompress_ciphertext_coefficient_pre + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> true); + f_decompress_ciphertext_coefficient_post + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_decompress_ciphertext_coefficient + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_polynomials_avx2.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS + vector.f_elements + } + <: + t_SIMD256Vector); + f_ntt_layer_1_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> true); + f_ntt_layer_1_step_post + = + (fun + (vector: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + true); + f_ntt_layer_1_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> + { + f_elements + = + Libcrux_polynomials_avx2.Ntt.ntt_layer_1_step vector.f_elements zeta0 zeta1 zeta2 zeta3 + } + <: + t_SIMD256Vector); + f_ntt_layer_2_step_pre = (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> true); + f_ntt_layer_2_step_post + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> true); + f_ntt_layer_2_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> + { f_elements = Libcrux_polynomials_avx2.Ntt.ntt_layer_2_step vector.f_elements zeta0 zeta1 } + <: + t_SIMD256Vector); + f_ntt_layer_3_step_pre = (fun (vector: t_SIMD256Vector) (zeta: i16) -> true); + f_ntt_layer_3_step_post + = + (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> true); + f_ntt_layer_3_step + = + (fun (vector: t_SIMD256Vector) (zeta: i16) -> + { f_elements = Libcrux_polynomials_avx2.Ntt.ntt_layer_3_step vector.f_elements zeta } + <: + t_SIMD256Vector); + f_inv_ntt_layer_1_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> true); + f_inv_ntt_layer_1_step_post + = + (fun + (vector: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + true); + f_inv_ntt_layer_1_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> + { + f_elements + = + Libcrux_polynomials_avx2.Ntt.inv_ntt_layer_1_step vector.f_elements + zeta0 + zeta1 + zeta2 + zeta3 + } + <: + t_SIMD256Vector); + f_inv_ntt_layer_2_step_pre = (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> true); + f_inv_ntt_layer_2_step_post + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> true); + f_inv_ntt_layer_2_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> + { + f_elements + = + Libcrux_polynomials_avx2.Ntt.inv_ntt_layer_2_step vector.f_elements zeta0 zeta1 + } + <: + t_SIMD256Vector); + f_inv_ntt_layer_3_step_pre = (fun (vector: t_SIMD256Vector) (zeta: i16) -> true); + f_inv_ntt_layer_3_step_post + = + (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> true); + f_inv_ntt_layer_3_step + = + (fun (vector: t_SIMD256Vector) (zeta: i16) -> + { f_elements = Libcrux_polynomials_avx2.Ntt.inv_ntt_layer_3_step vector.f_elements zeta } + <: + t_SIMD256Vector); + f_ntt_multiply_pre + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + true); + f_ntt_multiply_post + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + true); + f_ntt_multiply + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + { + f_elements + = + Libcrux_polynomials_avx2.Ntt.ntt_multiply lhs.f_elements + rhs.f_elements + zeta0 + zeta1 + zeta2 + zeta3 + } + <: + t_SIMD256Vector); + f_serialize_1_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_1_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 2)) -> true); + f_serialize_1_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_polynomials_avx2.Serialize.serialize_1_ vector.f_elements); + f_deserialize_1_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_1_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_1_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_1_ bytes } <: t_SIMD256Vector); + f_serialize_4_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_4_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 8)) -> true); + f_serialize_4_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_polynomials_avx2.Serialize.serialize_4_ vector.f_elements); + f_deserialize_4_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_4_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_4_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_4_ bytes } <: t_SIMD256Vector); + f_serialize_5_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_5_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 10)) -> true); + f_serialize_5_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_polynomials_avx2.Serialize.serialize_5_ vector.f_elements); + f_deserialize_5_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_5_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_5_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_5_ bytes } <: t_SIMD256Vector); + f_serialize_10_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_10_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 20)) -> true); + f_serialize_10_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_polynomials_avx2.Serialize.serialize_10_ vector.f_elements); + f_deserialize_10_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_10_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_10_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_10_ bytes } <: t_SIMD256Vector + ); + f_serialize_11_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_11_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 22)) -> true); + f_serialize_11_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_polynomials_avx2.Serialize.serialize_11_ vector.f_elements); + f_deserialize_11_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_11_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_11_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_11_ bytes } <: t_SIMD256Vector + ); + f_serialize_12_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_12_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 24)) -> true); + f_serialize_12_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_polynomials_avx2.Serialize.serialize_12_ vector.f_elements); + f_deserialize_12_pre = (fun (bytes: t_Slice u8) -> true); + f_deserialize_12_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_12_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_polynomials_avx2.Serialize.deserialize_12_ bytes } <: t_SIMD256Vector + ); + f_rej_sample_pre = (fun (input: t_Slice u8) (output: t_Slice i16) -> true); + f_rej_sample_post + = + (fun (input: t_Slice u8) (output: t_Slice i16) (out1: (t_Slice i16 & usize)) -> true); + f_rej_sample + = + fun (input: t_Slice u8) (output: t_Slice i16) -> + let tmp0, out:(t_Slice i16 & usize) = + Libcrux_polynomials_avx2.Sampling.rejection_sample input output + in + let output:t_Slice i16 = tmp0 in + let hax_temp_output:usize = out in + output, hax_temp_output <: (t_Slice i16 & usize) + } diff --git a/polynomials-avx2/src/sampling.rs b/polynomials-avx2/src/sampling.rs new file mode 100644 index 000000000..b4de11b48 --- /dev/null +++ b/polynomials-avx2/src/sampling.rs @@ -0,0 +1,814 @@ +use crate::{ + serialize::{deserialize_12, serialize_1}, + *, +}; + +use libcrux_traits::FIELD_MODULUS; + +const REJECTION_SAMPLE_SHUFFLE_TABLE: [[u8; 16]; 256] = [ + [ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, + ], // 0 + [ + 0, 1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 1 + [ + 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 2 + [ + 0, 1, 2, 3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 3 + [ + 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 4 + [ + 0, 1, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 5 + [ + 2, 3, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 6 + [ + 0, 1, 2, 3, 4, 5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 7 + [ + 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 8 + [ + 0, 1, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 9 + [ + 2, 3, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 10 + [ + 0, 1, 2, 3, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 11 + [ + 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 12 + [ + 0, 1, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 13 + [ + 2, 3, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 14 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 15 + [ + 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 16 + [ + 0, 1, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 17 + [ + 2, 3, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 18 + [ + 0, 1, 2, 3, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 19 + [ + 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 20 + [ + 0, 1, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 21 + [ + 2, 3, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 22 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 23 + [ + 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 24 + [ + 0, 1, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 25 + [ + 2, 3, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 26 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 27 + [ + 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 28 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 29 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 30 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 31 + [ + 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 32 + [ + 0, 1, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 33 + [ + 2, 3, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 34 + [ + 0, 1, 2, 3, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 35 + [ + 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 36 + [ + 0, 1, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 37 + [ + 2, 3, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 38 + [ + 0, 1, 2, 3, 4, 5, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 39 + [ + 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 40 + [ + 0, 1, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 41 + [ + 2, 3, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 42 + [ + 0, 1, 2, 3, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 43 + [ + 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 44 + [ + 0, 1, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 45 + [ + 2, 3, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 46 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 47 + [ + 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 48 + [ + 0, 1, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 49 + [ + 2, 3, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 50 + [ + 0, 1, 2, 3, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 51 + [ + 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 52 + [ + 0, 1, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 53 + [ + 2, 3, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 54 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 55 + [ + 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 56 + [ + 0, 1, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 57 + [ + 2, 3, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 58 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 59 + [ + 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 60 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 61 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 62 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0xff, 0xff, 0xff, 0xff], // 63 + [ + 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 64 + [ + 0, 1, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 65 + [ + 2, 3, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 66 + [ + 0, 1, 2, 3, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 67 + [ + 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 68 + [ + 0, 1, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 69 + [ + 2, 3, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 70 + [ + 0, 1, 2, 3, 4, 5, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 71 + [ + 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 72 + [ + 0, 1, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 73 + [ + 2, 3, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 74 + [ + 0, 1, 2, 3, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 75 + [ + 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 76 + [ + 0, 1, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 77 + [ + 2, 3, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 78 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 79 + [ + 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 80 + [ + 0, 1, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 81 + [ + 2, 3, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 82 + [ + 0, 1, 2, 3, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 83 + [ + 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 84 + [ + 0, 1, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 85 + [ + 2, 3, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 86 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 87 + [ + 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 88 + [ + 0, 1, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 89 + [ + 2, 3, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 90 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 91 + [ + 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 92 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 93 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 94 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 0xff, 0xff, 0xff, 0xff], // 95 + [ + 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 96 + [ + 0, 1, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 97 + [ + 2, 3, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 98 + [ + 0, 1, 2, 3, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 99 + [ + 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 100 + [ + 0, 1, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 101 + [ + 2, 3, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 102 + [ + 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 103 + [ + 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 104 + [ + 0, 1, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 105 + [ + 2, 3, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 106 + [ + 0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 107 + [ + 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 108 + [ + 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 109 + [ + 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 110 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 111 + [ + 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 112 + [ + 0, 1, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 113 + [ + 2, 3, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 114 + [ + 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 115 + [ + 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 116 + [ + 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 117 + [ + 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 118 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 119 + [ + 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 120 + [ + 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 121 + [ + 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 122 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 123 + [ + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 124 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 125 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff, 0xff, 0xff, + ], // 126 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xff, 0xff], // 127 + [ + 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 128 + [ + 0, 1, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 129 + [ + 2, 3, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 130 + [ + 0, 1, 2, 3, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 131 + [ + 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 132 + [ + 0, 1, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 133 + [ + 2, 3, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 134 + [ + 0, 1, 2, 3, 4, 5, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 135 + [ + 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 136 + [ + 0, 1, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 137 + [ + 2, 3, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 138 + [ + 0, 1, 2, 3, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 139 + [ + 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 140 + [ + 0, 1, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 141 + [ + 2, 3, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 142 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 143 + [ + 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 144 + [ + 0, 1, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 145 + [ + 2, 3, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 146 + [ + 0, 1, 2, 3, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 147 + [ + 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 148 + [ + 0, 1, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 149 + [ + 2, 3, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 150 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 151 + [ + 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 152 + [ + 0, 1, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 153 + [ + 2, 3, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 154 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 155 + [ + 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 156 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 157 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 158 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15, 0xff, 0xff, 0xff, 0xff], // 159 + [ + 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 160 + [ + 0, 1, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 161 + [ + 2, 3, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 162 + [ + 0, 1, 2, 3, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 163 + [ + 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 164 + [ + 0, 1, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 165 + [ + 2, 3, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 166 + [ + 0, 1, 2, 3, 4, 5, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 167 + [ + 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 168 + [ + 0, 1, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 169 + [ + 2, 3, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 170 + [ + 0, 1, 2, 3, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 171 + [ + 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 172 + [ + 0, 1, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 173 + [ + 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 174 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 175 + [ + 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 176 + [ + 0, 1, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 177 + [ + 2, 3, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 178 + [ + 0, 1, 2, 3, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 179 + [ + 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 180 + [ + 0, 1, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 181 + [ + 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 182 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 183 + [ + 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 184 + [ + 0, 1, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 185 + [ + 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 186 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 187 + [ + 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 188 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 189 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 190 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15, 0xff, 0xff], // 191 + [ + 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 192 + [ + 0, 1, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 193 + [ + 2, 3, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 194 + [ + 0, 1, 2, 3, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 195 + [ + 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 196 + [ + 0, 1, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 197 + [ + 2, 3, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 198 + [ + 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 199 + [ + 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 200 + [ + 0, 1, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 201 + [ + 2, 3, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 202 + [ + 0, 1, 2, 3, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 203 + [ + 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 204 + [ + 0, 1, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 205 + [ + 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 206 + [ + 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 207 + [ + 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 208 + [ + 0, 1, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 209 + [ + 2, 3, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 210 + [ + 0, 1, 2, 3, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 211 + [ + 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 212 + [ + 0, 1, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 213 + [ + 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 214 + [ + 0, 1, 2, 3, 4, 5, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 215 + [ + 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 216 + [ + 0, 1, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 217 + [ + 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 218 + [ + 0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 219 + [ + 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 220 + [ + 0, 1, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 221 + [ + 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 222 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0xff, 0xff], // 223 + [ + 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 224 + [ + 0, 1, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 225 + [ + 2, 3, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 226 + [ + 0, 1, 2, 3, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 227 + [ + 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 228 + [ + 0, 1, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 229 + [ + 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 230 + [ + 0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 231 + [ + 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 232 + [ + 0, 1, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 233 + [ + 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 234 + [ + 0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 235 + [ + 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 236 + [ + 0, 1, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 237 + [ + 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 238 + [0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 239 + [ + 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 240 + [ + 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 241 + [ + 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 242 + [ + 0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 243 + [ + 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 244 + [ + 0, 1, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 245 + [ + 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 246 + [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 247 + [ + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + ], // 248 + [ + 0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 249 + [ + 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 250 + [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 251 + [ + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff, 0xff, 0xff, + ], // 252 + [0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 253 + [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0xff, 0xff], // 254 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], // 255 +]; + +#[inline(always)] +pub(crate) fn rejection_sample(input: &[u8], output: &mut [i16]) -> usize { + let field_modulus = mm256_set1_epi16(FIELD_MODULUS); + + // The input bytes can be interpreted as a sequence of serialized + // 12-bit (i.e. uncompressed) coefficients. Not all coefficients may be + // less than FIELD_MODULUS though. + let potential_coefficients = deserialize_12(input); + + // Suppose we view |potential_coefficients| as follows (grouping 64-bit elements): + // + // A B C D | E F G H | .... + // + // and A < 3329, D < 3329 and H < 3329, |compare_with_field_modulus| will look like: + // + // 0xFF 0 0 0xFF | 0 0 0 0xFF | ... + let compare_with_field_modulus = mm256_cmpgt_epi16(field_modulus, potential_coefficients); + + // Since every bit in each lane is either 0 or 1, we only need one bit from + // each lane in the register to tell us what coefficients to keep and what + // to throw-away. Combine all the bits (there are 16) into two bytes. + let good = serialize_1(compare_with_field_modulus); + + // Each bit (and its corresponding position) represents an element we + // want to sample. We'd like all such elements to be next to each other starting + // at index 0, so that they can be read from the vector easily. + // |REJECTION_SAMPLE_SHUFFLE_TABLE| encodes the byte-level shuffling indices + // needed to make this happen. + // + // For e.g. if good[0] = 0b0_0_0_0_0_0_1_0, we need to move the element in + // the 2-nd 16-bit lane to the first. To do this, we need the byte-level + // shuffle indices to be 2 3 X X X X ... + let lower_shuffles = REJECTION_SAMPLE_SHUFFLE_TABLE[good[0] as usize]; + + // Shuffle the lower 8 16-bits accordingly ... + let lower_shuffles = mm_loadu_si128(&lower_shuffles); + let lower_coefficients = mm256_castsi256_si128(potential_coefficients); + let lower_coefficients = mm_shuffle_epi8(lower_coefficients, lower_shuffles); + + // ... then write them out ... + mm_storeu_si128(&mut output[0..8], lower_coefficients); + + // ... and finally count the number of bits of |good[0]| so we know how many + // were actually sampled + let sampled_count = good[0].count_ones() as usize; + + // Do the same for |goood[1]| + let upper_shuffles = REJECTION_SAMPLE_SHUFFLE_TABLE[good[1] as usize]; + let upper_shuffles = mm_loadu_si128(&upper_shuffles); + let upper_coefficients = mm256_extracti128_si256::<1>(potential_coefficients); + let upper_coefficients = mm_shuffle_epi8(upper_coefficients, upper_shuffles); + + mm_storeu_si128( + &mut output[sampled_count..sampled_count + 8], + upper_coefficients, + ); + + sampled_count + (good[1].count_ones() as usize) +}