diff --git a/.docker/c/ext-tools.sh b/.docker/c/ext-tools.sh index 2f6c8b85d..0a7283577 100644 --- a/.docker/c/ext-tools.sh +++ b/.docker/c/ext-tools.sh @@ -16,11 +16,11 @@ unzip karamel.zip rm -rf karamel.zip mv karamel-8c3612018c25889288da6857771be3ad03b75bcd/ karamel -curl -L https://github.com/AeneasVerif/eurydice/archive/1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c.zip \ +curl -L https://github.com/AeneasVerif/eurydice/archive/e2db6e88adc9995ca9d3dedf7fa9bc4095e9ca20.zip \ --output eurydice.zip unzip eurydice.zip rm -rf eurydice.zip -mv eurydice-1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c/ eurydice +mv eurydice-e2db6e88adc9995ca9d3dedf7fa9bc4095e9ca20/ eurydice echo "export KRML_HOME=$HOME/karamel" >>$HOME/.profile echo "export EURYDICE_HOME=$HOME/eurydice" >>$HOME/.profile diff --git a/.github/workflows/c.yml b/.github/workflows/c.yml index c3535185b..5345cad14 100644 --- a/.github/workflows/c.yml +++ b/.github/workflows/c.yml @@ -118,7 +118,7 @@ jobs: - name: 🔨 Build run: | - cmake -B build + LIBCRUX_BENCHMARKS=1 cmake -B build cmake --build build - name: 🏃🏻‍♀️ Test @@ -132,7 +132,7 @@ jobs: - name: 🔨 Build Release run: | rm -rf build - cmake -B build -DCMAKE_BUILD_TYPE=Release + LIBCRUX_BENCHMARKS=1 cmake -B build -DCMAKE_BUILD_TYPE=Release cmake --build build --config Release if: ${{ matrix.os != 'windows-latest' }} @@ -159,13 +159,6 @@ jobs: cmake -B build cmake --build build # FIXME: Benchmark build for cg on Windows CI is not working right now. - if: ${{ matrix.os != 'windows-latest' }} - - # FIXME: Benchmark build for cg on Windows CI are not working right now. - # - name: 🏃🏻‍♀️ Test (cg) - # working-directory: libcrux-ml-kem/cg - # run: ./build/Debug/ml_kem_test - # if: ${{ matrix.os == 'windows-latest' }} - name: 🏃🏻‍♀️ Test run: ./build/ml_kem_test diff --git a/.github/workflows/hax.yml b/.github/workflows/hax.yml index 39c5c4267..e385b948e 100644 --- a/.github/workflows/hax.yml +++ b/.github/workflows/hax.yml @@ -68,4 +68,13 @@ jobs: - name: 🏃 Extract ML-DSA crate working-directory: libcrux-ml-dsa - run: cargo hax into fstar + run: ./hax.py extract + + - name: 🏃 Lax ML-DSA crate + working-directory: libcrux-ml-dsa + run: | + env FSTAR_HOME=${{ github.workspace }}/fstar \ + HACL_HOME=${{ github.workspace }}/hacl-star \ + HAX_HOME=${{ github.workspace }}/hax \ + PATH="${PATH}:${{ github.workspace }}/fstar/bin" \ + ./hax.py prove --admit diff --git a/.github/workflows/mlkem.yml b/.github/workflows/mlkem.yml index 575339c5d..039a850f4 100644 --- a/.github/workflows/mlkem.yml +++ b/.github/workflows/mlkem.yml @@ -87,11 +87,6 @@ jobs: rustc --print=cfg cargo build --verbose $RUST_TARGET_FLAG --features pre-verification - - name: 🔨 Build unpacked - run: | - rustc --print=cfg - cargo build --verbose $RUST_TARGET_FLAG --features pre-verification,unpacked - - name: 🔨 Build Release run: cargo build --verbose --release $RUST_TARGET_FLAG --features pre-verification @@ -173,3 +168,37 @@ jobs: run: | cargo clean cargo hack test --each-feature $EXCLUDE_FEATURES --verbose $RUST_TARGET_FLAG + + fuzz: + strategy: + fail-fast: false + matrix: + os: + - macos-latest # macos-14 m1 + - ubuntu-latest + + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + working-directory: libcrux-ml-kem + + steps: + - uses: actions/checkout@v4 + + - name: 🛠️ Setup Rust Nightly + run: | + rustup toolchain install nightly + cargo install cargo-fuzz + + - name: 🛠️ Update dependencies + run: cargo update + + - name: 🏃🏻‍♀️ Decaps + run: CARGO_PROFILE_RELEASE_LTO=false cargo +nightly fuzz run decaps -- -runs=100000 + + - name: 🏃🏻‍♀️ Encaps + run: CARGO_PROFILE_RELEASE_LTO=false cargo +nightly fuzz run encaps -- -runs=100000 + + - name: 🏃🏻‍♀️ KeyGen + run: CARGO_PROFILE_RELEASE_LTO=false cargo +nightly fuzz run keygen -- -runs=1000000 diff --git a/.github/workflows/s390x.yml b/.github/workflows/s390x.yml new file mode 100644 index 000000000..e76c37b62 --- /dev/null +++ b/.github/workflows/s390x.yml @@ -0,0 +1,44 @@ +name: s390x - Build & Test + +on: + push: + 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: + s390x: + runs-on: ubuntu-latest + name: Build on ubuntu-22.04 s390x + steps: + - uses: actions/checkout@v4 + - uses: uraimo/run-on-arch-action@v2 + name: Run + id: runcmd + with: + arch: s390x + distro: ubuntu22.04 + + # Speed up builds by storing container images in + # a GitHub package registry. + githubToken: ${{ github.token }} + + run: | + apt-get -y update + apt-get install -y curl gcc g++ make cmake ninja-build git + cd libcrux-ml-kem/c + cmake -B build -G"Ninja Multi-Config" + cmake --build build + ./build/Debug/ml_kem_test + cd ../cg + cmake -B build -G"Ninja Multi-Config" + cmake --build build + ./build/Debug/ml_kem_test diff --git a/.gitignore b/.gitignore index e1ba64f55..3eb7f0598 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,6 @@ kyber-crate/ # F* .fstar-cache .depend -**/proofs/fstar/*/#*# -**/proofs/fstar/*/.#* +/proofs/fstar/*/#*# +/proofs/fstar/*/.#* hax.fst.config.json diff --git a/Cargo.lock b/Cargo.lock index 4b69f652c..753c14de6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,9 +29,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -44,9 +44,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" [[package]] name = "autocfg" @@ -143,7 +143,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.86", + "syn 2.0.87", "which", ] @@ -191,9 +191,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.31" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" dependencies = [ "jobserver", "libc", @@ -319,7 +319,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", ] [[package]] @@ -363,9 +363,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -483,7 +483,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", ] [[package]] @@ -499,6 +499,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + [[package]] name = "der" version = "0.7.9" @@ -702,7 +708,7 @@ dependencies = [ [[package]] name = "hax-lib" version = "0.1.0-alpha.1" -source = "git+https://github.com/hacspec/hax/?branch=main#291e34e51a0182c0f1b29f27cbafe3d40490e39a" +source = "git+https://github.com/hacspec/hax/#2b5ec0a0570e10861388481894911da7f152d1c6" dependencies = [ "hax-lib-macros", "num-bigint", @@ -712,20 +718,20 @@ dependencies = [ [[package]] name = "hax-lib-macros" version = "0.1.0-alpha.1" -source = "git+https://github.com/hacspec/hax/?branch=main#291e34e51a0182c0f1b29f27cbafe3d40490e39a" +source = "git+https://github.com/hacspec/hax/#2b5ec0a0570e10861388481894911da7f152d1c6" dependencies = [ "hax-lib-macros-types", "paste", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", ] [[package]] name = "hax-lib-macros-types" version = "0.1.0-alpha.1" -source = "git+https://github.com/hacspec/hax/?branch=main#291e34e51a0182c0f1b29f27cbafe3d40490e39a" +source = "git+https://github.com/hacspec/hax/#2b5ec0a0570e10861388481894911da7f152d1c6" dependencies = [ "proc-macro2", "quote", @@ -889,9 +895,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libcrux" @@ -899,15 +905,20 @@ version = "0.0.2-beta.2" dependencies = [ "clap", "getrandom", + "hax-lib", "hex", "libcrux", "libcrux-ecdh", + "libcrux-ed25519", "libcrux-hacl", + "libcrux-hacl-rs", "libcrux-hkdf", "libcrux-hmac", "libcrux-kem", "libcrux-ml-kem", "libcrux-platform", + "libcrux-sha2", + "libcrux-traits", "log", "pretty_env_logger", "quickcheck", @@ -918,6 +929,16 @@ dependencies = [ "serde_json", "wasm-bindgen", "wasm-bindgen-test", + "wycheproof", +] + +[[package]] +name = "libcrux-curve25519" +version = "0.0.2-beta.2" +dependencies = [ + "libcrux-hacl-rs", + "libcrux-macros", + "libcrux-sha2", ] [[package]] @@ -925,6 +946,7 @@ name = "libcrux-ecdh" version = "0.0.2-beta.2" dependencies = [ "hex", + "libcrux-curve25519", "libcrux-hacl", "pretty_env_logger", "rand", @@ -933,6 +955,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "libcrux-ed25519" +version = "0.0.2-beta.2" +dependencies = [ + "libcrux-hacl-rs", + "libcrux-macros", + "libcrux-sha2", +] + [[package]] name = "libcrux-fuzz" version = "0.0.0" @@ -953,19 +984,28 @@ dependencies = [ "wasm-bindgen-test", ] +[[package]] +name = "libcrux-hacl-rs" +version = "0.0.2-beta.2" +dependencies = [ + "libcrux-macros", +] + [[package]] name = "libcrux-hkdf" version = "0.0.2-beta.2" dependencies = [ - "libcrux-hacl", + "libcrux-hacl-rs", + "libcrux-hmac", ] [[package]] name = "libcrux-hmac" version = "0.0.2-beta.2" dependencies = [ - "libcrux-hacl", - "libcrux-hkdf", + "libcrux-hacl-rs", + "libcrux-macros", + "libcrux-sha2", ] [[package]] @@ -987,11 +1027,16 @@ dependencies = [ "rand", ] +[[package]] +name = "libcrux-macros" +version = "0.0.2-beta.2" + [[package]] name = "libcrux-ml-dsa" version = "0.0.2-beta.2" dependencies = [ "criterion", + "hax-lib", "hex", "libcrux-intrinsics", "libcrux-platform", @@ -1017,6 +1062,14 @@ dependencies = [ "serde_json", ] +[[package]] +name = "libcrux-ml-kem-fuzz" +version = "0.0.0" +dependencies = [ + "libcrux-ml-kem", + "libfuzzer-sys", +] + [[package]] name = "libcrux-platform" version = "0.0.2-beta.2" @@ -1047,6 +1100,15 @@ dependencies = [ "rand", ] +[[package]] +name = "libcrux-sha2" +version = "0.0.2-beta.2" +dependencies = [ + "libcrux-hacl-rs", + "libcrux-macros", + "libcrux-traits", +] + [[package]] name = "libcrux-sha3" version = "0.0.2-beta.2" @@ -1061,15 +1123,18 @@ dependencies = [ "rand", ] +[[package]] +name = "libcrux-traits" +version = "0.0.2-beta.2" + [[package]] name = "libfuzzer-sys" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" dependencies = [ "arbitrary", "cc", - "once_cell", ] [[package]] @@ -1112,9 +1177,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minicov" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def6d99771d7c499c26ad4d40eb6645eafd3a1553b35fc26ea5a489a45e82d9a" +checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b" dependencies = [ "cc", "walkdir", @@ -1205,7 +1270,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", ] [[package]] @@ -1372,7 +1437,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.86", + "syn 2.0.87", ] [[package]] @@ -1512,9 +1577,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1569,9 +1634,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags", "errno", @@ -1623,22 +1688,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", ] [[package]] @@ -1737,9 +1802,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.86" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -1858,7 +1923,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -1892,7 +1957,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1926,7 +1991,7 @@ checksum = "c97b2ef2c8d627381e51c071c2ab328eac606d3f69dd82bcbca20a9e389d95f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", ] [[package]] @@ -2042,6 +2107,17 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wycheproof" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb3be19abfb206c6adcbdf2007b09b0e8ca1f6530db40c03b42ce8ed4719894" +dependencies = [ + "data-encoding", + "serde", + "serde_json", +] + [[package]] name = "x25519-dalek" version = "2.0.1" @@ -2084,7 +2160,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", ] [[package]] @@ -2104,5 +2180,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.86", + "syn 2.0.87", ] diff --git a/Cargo.toml b/Cargo.toml index bcdb8b03f..645fb059c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "benchmarks", "fuzz", "libcrux-ml-kem", + "libcrux-ml-kem/fuzz", "libcrux-sha3", "libcrux-ml-dsa", "libcrux-intrinsics", @@ -16,7 +17,12 @@ members = [ "libcrux-hkdf", "libcrux-ecdh", "libcrux-psq", + "macros", "cavp", + "traits", + "sha2", + "ed25519", + "curve25519", ] [workspace.package] @@ -62,10 +68,14 @@ bench = false # so libtest doesn't eat the argumen libcrux-platform = { version = "=0.0.2-beta.2", path = "sys/platform" } [dependencies] +libcrux-traits = { version = "=0.0.2-beta.2", path = "traits" } +libcrux-hacl-rs = { version = "=0.0.2-beta.2", path = "hacl-rs" } libcrux-hacl = { version = "=0.0.2-beta.2", path = "sys/hacl" } libcrux-platform = { version = "=0.0.2-beta.2", path = "sys/platform" } libcrux-hkdf = { version = "=0.0.2-beta.2", path = "libcrux-hkdf" } libcrux-hmac = { version = "=0.0.2-beta.2", path = "libcrux-hmac" } +libcrux-sha2 = { version = "=0.0.2-beta.2", path = "sha2" } +libcrux-ed25519 = { version = "=0.0.2-beta.2", path = "ed25519" } libcrux-ecdh = { version = "=0.0.2-beta.2", path = "libcrux-ecdh" } libcrux-ml-kem = { version = "=0.0.2-beta.2", path = "libcrux-ml-kem" } libcrux-kem = { version = "=0.0.2-beta.2", path = "libcrux-kem" } @@ -74,13 +84,7 @@ log = { version = "0.4", optional = true } # WASM API wasm-bindgen = { version = "0.2.87", optional = true } getrandom = { version = "0.2", features = ["js"], optional = true } - -# When using the hax toolchain, we have more dependencies. -# This is only required when doing proofs. -#[target.'cfg(hax)'.dependencies] -[workspace.dependencies] -hax-lib-macros = { git = "https://github.com/hacspec/hax", branch = "main" } -hax-lib = { git = "https://github.com/hacspec/hax/", branch = "main" } +hax-lib = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax/" } [dev-dependencies] libcrux = { path = ".", features = ["rand", "tests"] } @@ -93,6 +97,7 @@ serde_json = { version = "1.0" } serde = { version = "1.0", features = ["derive"] } hex = { version = "0.4.3", features = ["serde"] } clap = { version = "4.5", features = ["derive"] } +wycheproof = "0.6.0" [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3" diff --git a/benchmarks/benches/kyber768.rs b/benchmarks/benches/kyber768.rs index 2fec056a9..0341a881e 100644 --- a/benchmarks/benches/kyber768.rs +++ b/benchmarks/benches/kyber768.rs @@ -80,7 +80,7 @@ pub fn comparisons_pk_validation(c: &mut Criterion) { b.iter_batched( || libcrux_kem::deterministic::mlkem768_generate_keypair_derand(seed), |key_pair| { - let _valid = libcrux_kem::ml_kem768_validate_public_key(key_pair.into_parts().1); + let _valid = libcrux_kem::ml_kem768_validate_public_key(&key_pair.into_parts().1); }, BatchSize::SmallInput, ) diff --git a/curve25519/Cargo.toml b/curve25519/Cargo.toml new file mode 100644 index 000000000..47e26ec85 --- /dev/null +++ b/curve25519/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "libcrux-curve25519" +description = "Formally verified curve25519 ECDH library" + +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +[features] +default = ["portable_hacl"] +portable_hacl = ["hacl"] +hacl = ["dep:libcrux-sha2", "dep:libcrux-hacl-rs", "dep:libcrux-macros"] + +[dependencies] +libcrux-hacl-rs = { version = "=0.0.2-beta.2", path = "../hacl-rs/", optional = true } +libcrux-sha2 = { version = "=0.0.2-beta.2", path = "../sha2", optional = true, features = [ + "hacl", +] } +libcrux-macros = { version = "=0.0.2-beta.2", path = "../macros", optional = true } diff --git a/curve25519/src/impl_hacl.rs b/curve25519/src/impl_hacl.rs new file mode 100644 index 000000000..5ff924a40 --- /dev/null +++ b/curve25519/src/impl_hacl.rs @@ -0,0 +1,21 @@ +use super::*; + +/// Implementation of Curve25519 backed by Hacl. +pub struct HaclCurve25519; + +impl Curve25519 for HaclCurve25519 { + // The hacl::ecdh function requires all parameters to be 32 byte long, which we enforce using + // types. + fn secret_to_public(pk: &mut [u8; PK_LEN], sk: &[u8; SK_LEN]) { + crate::hacl::secret_to_public(pk, sk) + } + + // The hacl::ecdh function requires all parameters to be 32 byte long, which we enforce using + // types. + fn ecdh(out: &mut [u8; SHK_LEN], pk: &[u8; PK_LEN], sk: &[u8; SK_LEN]) -> Result<(), Error> { + match crate::hacl::ecdh(out, sk, pk) { + true => Ok(()), + false => Err(Error), + } + } +} diff --git a/curve25519/src/lib.rs b/curve25519/src/lib.rs new file mode 100644 index 000000000..e1480f697 --- /dev/null +++ b/curve25519/src/lib.rs @@ -0,0 +1,41 @@ +#[cfg(feature = "hacl")] +pub use libcrux_hacl_rs::curve25519_51 as hacl; + +#[cfg(feature = "hacl")] +mod impl_hacl; + +#[cfg(feature = "portable_hacl")] +pub use impl_hacl::HaclCurve25519 as Impl; + +/// The length of Curve25519 secret keys. +pub const SK_LEN: usize = 32; + +/// The length of Curve25519 public keys. +pub const PK_LEN: usize = 32; + +/// The length of Curve25519 shared keys. +pub const SHK_LEN: usize = 32; + +/// Indicates that an error occurred +pub struct Error; + +/// This trait is implemented by the backing implementations. +/// Only used for implementation agility. +trait Curve25519 { + /// Computes a public key from a secret key. + fn secret_to_public(pk: &mut [u8; PK_LEN], sk: &[u8; SK_LEN]); + + /// Computes the scalar multiplication between the provided public and secret keys. Returns an + /// error if the result is 0. + fn ecdh(out: &mut [u8; SHK_LEN], pk: &[u8; PK_LEN], sk: &[u8; SK_LEN]) -> Result<(), Error>; +} + +/// Computes and writes the public key from the secret key `sk` and writes it into `pk`. +pub fn secret_to_public(pk: &mut [u8; PK_LEN], sk: &[u8; SK_LEN]) { + Impl::secret_to_public(pk, sk) +} + +/// Performs the ECDH computation and writes the key shared betweem `pk` and `sk` into `shk`. +pub fn ecdh(out: &mut [u8; SHK_LEN], pk: &[u8; PK_LEN], sk: &[u8; SK_LEN]) -> Result<(), Error> { + Impl::ecdh(out, pk, sk) +} diff --git a/ed25519/Cargo.toml b/ed25519/Cargo.toml new file mode 100644 index 000000000..879fcb49b --- /dev/null +++ b/ed25519/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "libcrux-ed25519" +description = "Formally verified ed25519 signature library" + +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +[features] +default = ["portable_hacl"] +portable_hacl = ["hacl"] +hacl = ["dep:libcrux-sha2", "dep:libcrux-hacl-rs", "dep:libcrux-macros"] + +[dependencies] +libcrux-hacl-rs = { version = "=0.0.2-beta.2", path = "../hacl-rs/", optional = true } +libcrux-sha2 = { version = "=0.0.2-beta.2", path = "../sha2", optional = true, features = [ + "hacl", +] } +libcrux-macros = { version = "=0.0.2-beta.2", path = "../macros", optional = true } diff --git a/ed25519/src/hacl/ed25519.rs b/ed25519/src/hacl/ed25519.rs new file mode 100644 index 000000000..94291a11e --- /dev/null +++ b/ed25519/src/hacl/ed25519.rs @@ -0,0 +1,1884 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_macros as krml; + +use libcrux_hacl_rs::bignum; +use libcrux_hacl_rs::fstar; +use libcrux_hacl_rs::lowstar; + +#[inline] +fn fsum(out: &mut [u64], a: &[u64], b: &[u64]) { + libcrux_hacl_rs::bignum25519_51::fadd(out, a, b) +} + +#[inline] +fn fdifference(out: &mut [u64], a: &[u64], b: &[u64]) { + libcrux_hacl_rs::bignum25519_51::fsub(out, a, b) +} + +pub(crate) fn reduce_513(a: &mut [u64]) { + let f0: u64 = a[0usize]; + let f1: u64 = a[1usize]; + let f2: u64 = a[2usize]; + let f3: u64 = a[3usize]; + let f4: u64 = a[4usize]; + let l·: u64 = f0.wrapping_add(0u64); + let tmp0: u64 = l· & 0x7ffffffffffffu64; + let c0: u64 = l·.wrapping_shr(51u32); + let l·0: u64 = f1.wrapping_add(c0); + let tmp1: u64 = l·0 & 0x7ffffffffffffu64; + let c1: u64 = l·0.wrapping_shr(51u32); + let l·1: u64 = f2.wrapping_add(c1); + let tmp2: u64 = l·1 & 0x7ffffffffffffu64; + let c2: u64 = l·1.wrapping_shr(51u32); + let l·2: u64 = f3.wrapping_add(c2); + let tmp3: u64 = l·2 & 0x7ffffffffffffu64; + let c3: u64 = l·2.wrapping_shr(51u32); + let l·3: u64 = f4.wrapping_add(c3); + let tmp4: u64 = l·3 & 0x7ffffffffffffu64; + let c4: u64 = l·3.wrapping_shr(51u32); + let l·4: u64 = tmp0.wrapping_add(c4.wrapping_mul(19u64)); + let tmp0·: u64 = l·4 & 0x7ffffffffffffu64; + let c5: u64 = l·4.wrapping_shr(51u32); + a[0usize] = tmp0·; + a[1usize] = tmp1.wrapping_add(c5); + a[2usize] = tmp2; + a[3usize] = tmp3; + a[4usize] = tmp4 +} + +#[inline] +fn fmul(output: &mut [u64], input: &[u64], input2: &[u64]) { + let tmp: [fstar::uint128::uint128; 10] = [fstar::uint128::uint64_to_uint128(0u64); 10usize]; + libcrux_hacl_rs::bignum25519_51::fmul(output, input, input2, &tmp) +} + +#[inline] +fn times_2(out: &mut [u64], a: &[u64]) { + let a0: u64 = a[0usize]; + let a1: u64 = a[1usize]; + let a2: u64 = a[2usize]; + let a3: u64 = a[3usize]; + let a4: u64 = a[4usize]; + let o0: u64 = 2u64.wrapping_mul(a0); + let o1: u64 = 2u64.wrapping_mul(a1); + let o2: u64 = 2u64.wrapping_mul(a2); + let o3: u64 = 2u64.wrapping_mul(a3); + let o4: u64 = 2u64.wrapping_mul(a4); + out[0usize] = o0; + out[1usize] = o1; + out[2usize] = o2; + out[3usize] = o3; + out[4usize] = o4 +} + +#[inline] +fn times_d(out: &mut [u64], a: &[u64]) { + let mut d: [u64; 5] = [0u64; 5usize]; + (&mut d)[0usize] = 0x00034dca135978a3u64; + (&mut d)[1usize] = 0x0001a8283b156ebdu64; + (&mut d)[2usize] = 0x0005e7a26001c029u64; + (&mut d)[3usize] = 0x000739c663a03cbbu64; + (&mut d)[4usize] = 0x00052036cee2b6ffu64; + crate::hacl::ed25519::fmul(out, &d, a) +} + +#[inline] +fn times_2d(out: &mut [u64], a: &[u64]) { + let mut d2: [u64; 5] = [0u64; 5usize]; + (&mut d2)[0usize] = 0x00069b9426b2f159u64; + (&mut d2)[1usize] = 0x00035050762add7au64; + (&mut d2)[2usize] = 0x0003cf44c0038052u64; + (&mut d2)[3usize] = 0x0006738cc7407977u64; + (&mut d2)[4usize] = 0x0002406d9dc56dffu64; + crate::hacl::ed25519::fmul(out, &d2, a) +} + +#[inline] +fn fsquare(out: &mut [u64], a: &[u64]) { + let tmp: [fstar::uint128::uint128; 5] = [fstar::uint128::uint64_to_uint128(0u64); 5usize]; + libcrux_hacl_rs::bignum25519_51::fsqr(out, a, &tmp) +} + +#[inline] +fn fsquare_times(output: &mut [u64], input: &[u64], count: u32) { + let tmp: [fstar::uint128::uint128; 5] = [fstar::uint128::uint64_to_uint128(0u64); 5usize]; + libcrux_hacl_rs::curve25519_51::fsquare_times(output, input, &tmp, count) +} + +#[inline] +fn fsquare_times_inplace(output: &mut [u64], count: u32) { + let tmp: [fstar::uint128::uint128; 5] = [fstar::uint128::uint64_to_uint128(0u64); 5usize]; + let mut input: [u64; 5] = [0u64; 5usize]; + ((&mut input)[0usize..5usize]).copy_from_slice(&output[0usize..5usize]); + libcrux_hacl_rs::curve25519_51::fsquare_times(output, &input, &tmp, count) +} + +pub(crate) fn inverse(out: &mut [u64], a: &[u64]) { + let tmp: [fstar::uint128::uint128; 10] = [fstar::uint128::uint64_to_uint128(0u64); 10usize]; + libcrux_hacl_rs::curve25519_51::finv(out, a, &tmp) +} + +#[inline] +fn reduce(out: &mut [u64]) { + let o0: u64 = out[0usize]; + let o1: u64 = out[1usize]; + let o2: u64 = out[2usize]; + let o3: u64 = out[3usize]; + let o4: u64 = out[4usize]; + let l·: u64 = o0.wrapping_add(0u64); + let tmp0: u64 = l· & 0x7ffffffffffffu64; + let c0: u64 = l·.wrapping_shr(51u32); + let l·0: u64 = o1.wrapping_add(c0); + let tmp1: u64 = l·0 & 0x7ffffffffffffu64; + let c1: u64 = l·0.wrapping_shr(51u32); + let l·1: u64 = o2.wrapping_add(c1); + let tmp2: u64 = l·1 & 0x7ffffffffffffu64; + let c2: u64 = l·1.wrapping_shr(51u32); + let l·2: u64 = o3.wrapping_add(c2); + let tmp3: u64 = l·2 & 0x7ffffffffffffu64; + let c3: u64 = l·2.wrapping_shr(51u32); + let l·3: u64 = o4.wrapping_add(c3); + let tmp4: u64 = l·3 & 0x7ffffffffffffu64; + let c4: u64 = l·3.wrapping_shr(51u32); + let l·4: u64 = tmp0.wrapping_add(c4.wrapping_mul(19u64)); + let tmp0·: u64 = l·4 & 0x7ffffffffffffu64; + let c5: u64 = l·4.wrapping_shr(51u32); + let f0: u64 = tmp0·; + let f1: u64 = tmp1.wrapping_add(c5); + let f2: u64 = tmp2; + let f3: u64 = tmp3; + let f4: u64 = tmp4; + let m0: u64 = fstar::uint64::gte_mask(f0, 0x7ffffffffffedu64); + let m1: u64 = fstar::uint64::eq_mask(f1, 0x7ffffffffffffu64); + let m2: u64 = fstar::uint64::eq_mask(f2, 0x7ffffffffffffu64); + let m3: u64 = fstar::uint64::eq_mask(f3, 0x7ffffffffffffu64); + let m4: u64 = fstar::uint64::eq_mask(f4, 0x7ffffffffffffu64); + let mask: u64 = m0 & m1 & m2 & m3 & m4; + let f0·: u64 = f0.wrapping_sub(mask & 0x7ffffffffffedu64); + let f1·: u64 = f1.wrapping_sub(mask & 0x7ffffffffffffu64); + let f2·: u64 = f2.wrapping_sub(mask & 0x7ffffffffffffu64); + let f3·: u64 = f3.wrapping_sub(mask & 0x7ffffffffffffu64); + let f4·: u64 = f4.wrapping_sub(mask & 0x7ffffffffffffu64); + let f01: u64 = f0·; + let f11: u64 = f1·; + let f21: u64 = f2·; + let f31: u64 = f3·; + let f41: u64 = f4·; + out[0usize] = f01; + out[1usize] = f11; + out[2usize] = f21; + out[3usize] = f31; + out[4usize] = f41 +} + +pub(crate) fn load_51(output: &mut [u64], input: &[u8]) { + let mut u64s: [u64; 4] = [0u64; 4usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let bj: (&[u8], &[u8]) = input.split_at(i.wrapping_mul(8u32) as usize); + let u: u64 = lowstar::endianness::load64_le(bj.1); + let r: u64 = u; + let x: u64 = r; + let os: (&mut [u64], &mut [u64]) = u64s.split_at_mut(0usize); + os.1[i as usize] = x + }); + let u64s3: u64 = (&u64s)[3usize]; + (&mut u64s)[3usize] = u64s3 & 0x7fffffffffffffffu64; + output[0usize] = (&u64s)[0usize] & 0x7ffffffffffffu64; + output[1usize] = ((&u64s)[0usize]).wrapping_shr(51u32) + | ((&u64s)[1usize] & 0x3fffffffffu64).wrapping_shl(13u32); + output[2usize] = ((&u64s)[1usize]).wrapping_shr(38u32) + | ((&u64s)[2usize] & 0x1ffffffu64).wrapping_shl(26u32); + output[3usize] = + ((&u64s)[2usize]).wrapping_shr(25u32) | ((&u64s)[3usize] & 0xfffu64).wrapping_shl(39u32); + output[4usize] = ((&u64s)[3usize]).wrapping_shr(12u32) +} + +pub(crate) fn store_51(output: &mut [u8], input: &[u64]) { + let mut u64s: [u64; 4] = [0u64; 4usize]; + libcrux_hacl_rs::bignum25519_51::store_felem(&mut u64s, input); + krml::unroll_for!( + 4, + "i", + 0u32, + 1u32, + lowstar::endianness::store64_le( + &mut output[i.wrapping_mul(8u32) as usize..], + (&u64s)[i as usize] + ) + ) +} + +pub(crate) fn point_double(out: &mut [u64], p: &[u64]) { + let mut tmp: [u64; 20] = [0u64; 20usize]; + let tmp1: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let tmp2: (&mut [u64], &mut [u64]) = tmp1.1.split_at_mut(5usize); + let tmp3: (&mut [u64], &mut [u64]) = tmp2.1.split_at_mut(5usize); + let tmp4: (&mut [u64], &mut [u64]) = tmp3.1.split_at_mut(5usize); + let x1: (&[u64], &[u64]) = p.split_at(0usize); + let y1: (&[u64], &[u64]) = x1.1.split_at(5usize); + let z1: (&[u64], &[u64]) = y1.1.split_at(5usize); + crate::hacl::ed25519::fsquare(tmp2.0, y1.0); + crate::hacl::ed25519::fsquare(tmp3.0, z1.0); + crate::hacl::ed25519::fsum(tmp4.0, tmp2.0, tmp3.0); + crate::hacl::ed25519::fdifference(tmp4.1, tmp2.0, tmp3.0); + crate::hacl::ed25519::fsquare(tmp2.0, z1.1); + let mut a_copy: [u64; 5] = [0u64; 5usize]; + ((&mut a_copy)[0usize..5usize]).copy_from_slice(&tmp2.0[0usize..5usize]); + crate::hacl::ed25519::times_2(tmp2.0, &a_copy); + let tmp10: (&mut [u64], &mut [u64]) = tmp2.0.split_at_mut(0usize); + let tmp20: (&mut [u64], &mut [u64]) = tmp3.0.split_at_mut(0usize); + let tmp30: (&mut [u64], &mut [u64]) = tmp4.0.split_at_mut(0usize); + let tmp40: (&mut [u64], &mut [u64]) = tmp4.1.split_at_mut(0usize); + let x10: (&[u64], &[u64]) = y1.0.split_at(0usize); + let y10: (&[u64], &[u64]) = z1.0.split_at(0usize); + crate::hacl::ed25519::fsum(tmp20.1, x10.1, y10.1); + let mut a_copy0: [u64; 5] = [0u64; 5usize]; + ((&mut a_copy0)[0usize..5usize]).copy_from_slice(&tmp20.1[0usize..5usize]); + crate::hacl::ed25519::fsquare(tmp20.1, &a_copy0); + crate::hacl::ed25519::reduce_513(tmp30.1); + let mut b_copy: [u64; 5] = [0u64; 5usize]; + ((&mut b_copy)[0usize..5usize]).copy_from_slice(&tmp20.1[0usize..5usize]); + crate::hacl::ed25519::fdifference(tmp20.1, tmp30.1, &b_copy); + crate::hacl::ed25519::reduce_513(tmp10.1); + crate::hacl::ed25519::reduce_513(tmp40.1); + let mut a_copy1: [u64; 5] = [0u64; 5usize]; + ((&mut a_copy1)[0usize..5usize]).copy_from_slice(&tmp10.1[0usize..5usize]); + crate::hacl::ed25519::fsum(tmp10.1, &a_copy1, tmp40.1); + let tmp_f: (&[u64], &[u64]) = tmp10.1.split_at(0usize); + let tmp_e: (&[u64], &[u64]) = tmp20.1.split_at(0usize); + let tmp_h: (&[u64], &[u64]) = tmp30.1.split_at(0usize); + let tmp_g: (&[u64], &[u64]) = tmp40.1.split_at(0usize); + let x3: (&mut [u64], &mut [u64]) = out.split_at_mut(0usize); + let y3: (&mut [u64], &mut [u64]) = x3.1.split_at_mut(5usize); + let z3: (&mut [u64], &mut [u64]) = y3.1.split_at_mut(5usize); + let t3: (&mut [u64], &mut [u64]) = z3.1.split_at_mut(5usize); + crate::hacl::ed25519::fmul(y3.0, tmp_e.1, tmp_f.1); + crate::hacl::ed25519::fmul(z3.0, tmp_g.1, tmp_h.1); + crate::hacl::ed25519::fmul(t3.1, tmp_e.1, tmp_h.1); + crate::hacl::ed25519::fmul(t3.0, tmp_f.1, tmp_g.1) +} + +pub(crate) fn point_add(out: &mut [u64], p: &[u64], q: &[u64]) { + let mut tmp: [u64; 30] = [0u64; 30usize]; + let tmp1: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let tmp2: (&mut [u64], &mut [u64]) = tmp1.1.split_at_mut(5usize); + let tmp3: (&mut [u64], &mut [u64]) = tmp2.1.split_at_mut(5usize); + let tmp4: (&mut [u64], &mut [u64]) = tmp3.1.split_at_mut(5usize); + let x1: (&[u64], &[u64]) = p.split_at(0usize); + let y1: (&[u64], &[u64]) = x1.1.split_at(5usize); + let x2: (&[u64], &[u64]) = q.split_at(0usize); + let y2: (&[u64], &[u64]) = x2.1.split_at(5usize); + crate::hacl::ed25519::fdifference(tmp2.0, y1.1, y1.0); + crate::hacl::ed25519::fdifference(tmp3.0, y2.1, y2.0); + crate::hacl::ed25519::fmul(tmp4.0, tmp2.0, tmp3.0); + crate::hacl::ed25519::fsum(tmp2.0, y1.1, y1.0); + crate::hacl::ed25519::fsum(tmp3.0, y2.1, y2.0); + crate::hacl::ed25519::fmul(tmp4.1, tmp2.0, tmp3.0); + let tmp10: (&mut [u64], &mut [u64]) = tmp2.0.split_at_mut(0usize); + let tmp20: (&mut [u64], &mut [u64]) = tmp3.0.split_at_mut(0usize); + let tmp30: (&[u64], &[u64]) = tmp4.0.split_at(0usize); + let tmp40: (&mut [u64], &mut [u64]) = tmp4.1.split_at_mut(0usize); + let tmp5: (&mut [u64], &mut [u64]) = tmp40.1.split_at_mut(5usize); + let tmp6: (&mut [u64], &mut [u64]) = tmp5.1.split_at_mut(5usize); + let z1: (&[u64], &[u64]) = y1.1.split_at(5usize); + let t1: (&[u64], &[u64]) = z1.1.split_at(5usize); + let z2: (&[u64], &[u64]) = y2.1.split_at(5usize); + let t2: (&[u64], &[u64]) = z2.1.split_at(5usize); + crate::hacl::ed25519::times_2d(tmp10.1, t1.1); + let mut inp_copy: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy)[0usize..5usize]).copy_from_slice(&tmp10.1[0usize..5usize]); + crate::hacl::ed25519::fmul(tmp10.1, &inp_copy, t2.1); + crate::hacl::ed25519::times_2(tmp20.1, t1.0); + let mut inp_copy0: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy0)[0usize..5usize]).copy_from_slice(&tmp20.1[0usize..5usize]); + crate::hacl::ed25519::fmul(tmp20.1, &inp_copy0, t2.0); + crate::hacl::ed25519::fdifference(tmp6.0, tmp5.0, tmp30.1); + crate::hacl::ed25519::fdifference(tmp6.1, tmp20.1, tmp10.1); + let mut a_copy: [u64; 5] = [0u64; 5usize]; + ((&mut a_copy)[0usize..5usize]).copy_from_slice(&tmp10.1[0usize..5usize]); + crate::hacl::ed25519::fsum(tmp10.1, &a_copy, tmp20.1); + crate::hacl::ed25519::fsum(tmp20.1, tmp5.0, tmp30.1); + let tmp_g: (&[u64], &[u64]) = tmp10.1.split_at(0usize); + let tmp_h: (&[u64], &[u64]) = tmp20.1.split_at(0usize); + let tmp_e: (&[u64], &[u64]) = tmp6.0.split_at(0usize); + let tmp_f: (&[u64], &[u64]) = tmp6.1.split_at(0usize); + let x3: (&mut [u64], &mut [u64]) = out.split_at_mut(0usize); + let y3: (&mut [u64], &mut [u64]) = x3.1.split_at_mut(5usize); + let z3: (&mut [u64], &mut [u64]) = y3.1.split_at_mut(5usize); + let t3: (&mut [u64], &mut [u64]) = z3.1.split_at_mut(5usize); + crate::hacl::ed25519::fmul(y3.0, tmp_e.1, tmp_f.1); + crate::hacl::ed25519::fmul(z3.0, tmp_g.1, tmp_h.1); + crate::hacl::ed25519::fmul(t3.1, tmp_e.1, tmp_h.1); + crate::hacl::ed25519::fmul(t3.0, tmp_f.1, tmp_g.1) +} + +pub(crate) fn make_point_inf(b: &mut [u64]) { + let x: (&mut [u64], &mut [u64]) = b.split_at_mut(0usize); + let y: (&mut [u64], &mut [u64]) = x.1.split_at_mut(5usize); + let z: (&mut [u64], &mut [u64]) = y.1.split_at_mut(5usize); + let t: (&mut [u64], &mut [u64]) = z.1.split_at_mut(5usize); + y.0[0usize] = 0u64; + y.0[1usize] = 0u64; + y.0[2usize] = 0u64; + y.0[3usize] = 0u64; + y.0[4usize] = 0u64; + z.0[0usize] = 1u64; + z.0[1usize] = 0u64; + z.0[2usize] = 0u64; + z.0[3usize] = 0u64; + z.0[4usize] = 0u64; + t.0[0usize] = 1u64; + t.0[1usize] = 0u64; + t.0[2usize] = 0u64; + t.0[3usize] = 0u64; + t.0[4usize] = 0u64; + t.1[0usize] = 0u64; + t.1[1usize] = 0u64; + t.1[2usize] = 0u64; + t.1[3usize] = 0u64; + t.1[4usize] = 0u64 +} + +#[inline] +fn pow2_252m2(out: &mut [u64], z: &[u64]) { + let mut buf: [u64; 20] = [0u64; 20usize]; + let a: (&mut [u64], &mut [u64]) = buf.split_at_mut(0usize); + let t0: (&mut [u64], &mut [u64]) = a.1.split_at_mut(5usize); + let b: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(5usize); + let c: (&mut [u64], &mut [u64]) = b.1.split_at_mut(5usize); + crate::hacl::ed25519::fsquare_times(t0.0, z, 1u32); + crate::hacl::ed25519::fsquare_times(b.0, t0.0, 2u32); + crate::hacl::ed25519::fmul(c.0, b.0, z); + let mut inp_copy: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy)[0usize..5usize]).copy_from_slice(&t0.0[0usize..5usize]); + crate::hacl::ed25519::fmul(t0.0, &inp_copy, c.0); + crate::hacl::ed25519::fsquare_times(b.0, t0.0, 1u32); + let mut inp_copy0: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy0)[0usize..5usize]).copy_from_slice(&c.0[0usize..5usize]); + crate::hacl::ed25519::fmul(c.0, &inp_copy0, b.0); + crate::hacl::ed25519::fsquare_times(b.0, c.0, 5u32); + let mut inp_copy1: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy1)[0usize..5usize]).copy_from_slice(&c.0[0usize..5usize]); + crate::hacl::ed25519::fmul(c.0, &inp_copy1, b.0); + crate::hacl::ed25519::fsquare_times(b.0, c.0, 10u32); + crate::hacl::ed25519::fmul(c.1, b.0, c.0); + crate::hacl::ed25519::fsquare_times(b.0, c.1, 20u32); + let mut inp_copy2: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy2)[0usize..5usize]).copy_from_slice(&b.0[0usize..5usize]); + crate::hacl::ed25519::fmul(b.0, &inp_copy2, c.1); + crate::hacl::ed25519::fsquare_times_inplace(b.0, 10u32); + let mut inp_copy3: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy3)[0usize..5usize]).copy_from_slice(&c.0[0usize..5usize]); + crate::hacl::ed25519::fmul(c.0, &inp_copy3, b.0); + crate::hacl::ed25519::fsquare_times(b.0, c.0, 50u32); + let a0: (&mut [u64], &mut [u64]) = t0.0.split_at_mut(0usize); + let t00: (&mut [u64], &mut [u64]) = b.0.split_at_mut(0usize); + let b0: (&[u64], &[u64]) = c.0.split_at(0usize); + let c0: (&mut [u64], &mut [u64]) = c.1.split_at_mut(0usize); + crate::hacl::ed25519::fsquare_times(a0.1, z, 1u32); + crate::hacl::ed25519::fmul(c0.1, t00.1, b0.1); + crate::hacl::ed25519::fsquare_times(t00.1, c0.1, 100u32); + let mut inp_copy4: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy4)[0usize..5usize]).copy_from_slice(&t00.1[0usize..5usize]); + crate::hacl::ed25519::fmul(t00.1, &inp_copy4, c0.1); + crate::hacl::ed25519::fsquare_times_inplace(t00.1, 50u32); + let mut inp_copy5: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy5)[0usize..5usize]).copy_from_slice(&t00.1[0usize..5usize]); + crate::hacl::ed25519::fmul(t00.1, &inp_copy5, b0.1); + crate::hacl::ed25519::fsquare_times_inplace(t00.1, 2u32); + crate::hacl::ed25519::fmul(out, t00.1, a0.1) +} + +#[inline] +fn is_0(x: &[u64]) -> bool { + let x0: u64 = x[0usize]; + let x1: u64 = x[1usize]; + let x2: u64 = x[2usize]; + let x3: u64 = x[3usize]; + let x4: u64 = x[4usize]; + x0 == 0u64 && x1 == 0u64 && x2 == 0u64 && x3 == 0u64 && x4 == 0u64 +} + +#[inline] +fn mul_modp_sqrt_m1(x: &mut [u64]) { + let mut sqrt_m1: [u64; 5] = [0u64; 5usize]; + (&mut sqrt_m1)[0usize] = 0x00061b274a0ea0b0u64; + (&mut sqrt_m1)[1usize] = 0x0000d5a5fc8f189du64; + (&mut sqrt_m1)[2usize] = 0x0007ef5e9cbd0c60u64; + (&mut sqrt_m1)[3usize] = 0x00078595a6804c9eu64; + (&mut sqrt_m1)[4usize] = 0x0002b8324804fc1du64; + let mut inp_copy: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy)[0usize..5usize]).copy_from_slice(&x[0usize..5usize]); + crate::hacl::ed25519::fmul(x, &inp_copy, &sqrt_m1) +} + +#[inline] +fn recover_x(x: &mut [u64], y: &[u64], sign: u64) -> bool { + let mut tmp: [u64; 15] = [0u64; 15usize]; + let x2: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let x0: u64 = y[0usize]; + let x1: u64 = y[1usize]; + let x21: u64 = y[2usize]; + let x3: u64 = y[3usize]; + let x4: u64 = y[4usize]; + let b: bool = x0 >= 0x7ffffffffffedu64 + && x1 == 0x7ffffffffffffu64 + && x21 == 0x7ffffffffffffu64 + && x3 == 0x7ffffffffffffu64 + && x4 == 0x7ffffffffffffu64; + let res: bool = if b { + false + } else { + let mut tmp1: [u64; 20] = [0u64; 20usize]; + let one: (&mut [u64], &mut [u64]) = tmp1.split_at_mut(0usize); + let y2: (&mut [u64], &mut [u64]) = one.1.split_at_mut(5usize); + let dyyi: (&mut [u64], &mut [u64]) = y2.1.split_at_mut(5usize); + let dyy: (&mut [u64], &mut [u64]) = dyyi.1.split_at_mut(5usize); + y2.0[0usize] = 1u64; + y2.0[1usize] = 0u64; + y2.0[2usize] = 0u64; + y2.0[3usize] = 0u64; + y2.0[4usize] = 0u64; + crate::hacl::ed25519::fsquare(dyyi.0, y); + crate::hacl::ed25519::times_d(dyy.1, dyyi.0); + let mut a_copy: [u64; 5] = [0u64; 5usize]; + ((&mut a_copy)[0usize..5usize]).copy_from_slice(&dyy.1[0usize..5usize]); + crate::hacl::ed25519::fsum(dyy.1, &a_copy, y2.0); + crate::hacl::ed25519::reduce_513(dyy.1); + crate::hacl::ed25519::inverse(dyy.0, dyy.1); + crate::hacl::ed25519::fdifference(x2.1, dyyi.0, y2.0); + let mut inp_copy: [u64; 5] = [0u64; 5usize]; + ((&mut inp_copy)[0usize..5usize]).copy_from_slice(&x2.1[0usize..5usize]); + crate::hacl::ed25519::fmul(x2.1, &inp_copy, dyy.0); + crate::hacl::ed25519::reduce(x2.1); + let x2_is_0: bool = crate::hacl::ed25519::is_0(x2.1); + let z: u8 = if x2_is_0 { + if sign == 0u64 { + x[0usize] = 0u64; + x[1usize] = 0u64; + x[2usize] = 0u64; + x[3usize] = 0u64; + x[4usize] = 0u64; + 1u8 + } else { + 0u8 + } + } else { + 2u8 + }; + if z == 0u8 { + false + } else if z == 1u8 { + true + } else { + let x210: (&mut [u64], &mut [u64]) = x2.1.split_at_mut(0usize); + let x30: (&mut [u64], &mut [u64]) = x210.1.split_at_mut(5usize); + let t0: (&mut [u64], &mut [u64]) = x30.1.split_at_mut(5usize); + crate::hacl::ed25519::pow2_252m2(t0.0, x30.0); + crate::hacl::ed25519::fsquare(t0.1, t0.0); + let mut a_copy0: [u64; 5] = [0u64; 5usize]; + ((&mut a_copy0)[0usize..5usize]).copy_from_slice(&t0.1[0usize..5usize]); + crate::hacl::ed25519::fdifference(t0.1, &a_copy0, x30.0); + crate::hacl::ed25519::reduce_513(t0.1); + crate::hacl::ed25519::reduce(t0.1); + let t0_is_0: bool = crate::hacl::ed25519::is_0(t0.1); + if !t0_is_0 { + crate::hacl::ed25519::mul_modp_sqrt_m1(t0.0) + }; + let x211: (&[u64], &[u64]) = x30.0.split_at(0usize); + let x31: (&mut [u64], &mut [u64]) = t0.0.split_at_mut(0usize); + let t00: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(0usize); + crate::hacl::ed25519::fsquare(t00.1, x31.1); + let mut a_copy1: [u64; 5] = [0u64; 5usize]; + ((&mut a_copy1)[0usize..5usize]).copy_from_slice(&t00.1[0usize..5usize]); + crate::hacl::ed25519::fdifference(t00.1, &a_copy1, x211.1); + crate::hacl::ed25519::reduce_513(t00.1); + crate::hacl::ed25519::reduce(t00.1); + let z1: bool = crate::hacl::ed25519::is_0(t00.1); + if z1 { + let x32: (&mut [u64], &mut [u64]) = x31.1.split_at_mut(0usize); + let t01: (&mut [u64], &mut [u64]) = t00.1.split_at_mut(0usize); + crate::hacl::ed25519::reduce(x32.1); + let x00: u64 = x32.1[0usize]; + let x01: u64 = x00 & 1u64; + if x01 != sign { + t01.1[0usize] = 0u64; + t01.1[1usize] = 0u64; + t01.1[2usize] = 0u64; + t01.1[3usize] = 0u64; + t01.1[4usize] = 0u64; + let mut b_copy: [u64; 5] = [0u64; 5usize]; + ((&mut b_copy)[0usize..5usize]).copy_from_slice(&x32.1[0usize..5usize]); + crate::hacl::ed25519::fdifference(x32.1, t01.1, &b_copy); + crate::hacl::ed25519::reduce_513(x32.1); + crate::hacl::ed25519::reduce(x32.1) + }; + (x[0usize..5usize]).copy_from_slice(&x32.1[0usize..5usize]); + true + } else { + false + } + } + }; + let res0: bool = res; + res0 +} + +pub(crate) fn point_decompress(out: &mut [u64], s: &[u8]) -> bool { + let mut tmp: [u64; 10] = [0u64; 10usize]; + let y: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let x: (&mut [u64], &mut [u64]) = y.1.split_at_mut(5usize); + let s31: u8 = s[31usize]; + let z: u8 = s31.wrapping_shr(7u32); + let sign: u64 = z as u64; + crate::hacl::ed25519::load_51(x.0, s); + let z0: bool = crate::hacl::ed25519::recover_x(x.1, x.0, sign); + let res: bool = if z0 { + let outx: (&mut [u64], &mut [u64]) = out.split_at_mut(0usize); + let outy: (&mut [u64], &mut [u64]) = outx.1.split_at_mut(5usize); + let outz: (&mut [u64], &mut [u64]) = outy.1.split_at_mut(5usize); + let outt: (&mut [u64], &mut [u64]) = outz.1.split_at_mut(5usize); + (outy.0[0usize..5usize]).copy_from_slice(&x.1[0usize..5usize]); + (outz.0[0usize..5usize]).copy_from_slice(&x.0[0usize..5usize]); + outt.0[0usize] = 1u64; + outt.0[1usize] = 0u64; + outt.0[2usize] = 0u64; + outt.0[3usize] = 0u64; + outt.0[4usize] = 0u64; + crate::hacl::ed25519::fmul(outt.1, x.1, x.0); + true + } else { + false + }; + let res0: bool = res; + res0 +} + +pub(crate) fn point_compress(z: &mut [u8], p: &[u64]) { + let mut tmp: [u64; 15] = [0u64; 15usize]; + let zinv: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let x: (&mut [u64], &mut [u64]) = zinv.1.split_at_mut(5usize); + let out: (&mut [u64], &mut [u64]) = x.1.split_at_mut(5usize); + let px: (&[u64], &[u64]) = p.split_at(0usize); + let py: (&[u64], &[u64]) = px.1.split_at(5usize); + let pz: (&[u64], &[u64]) = py.1.split_at(5usize); + crate::hacl::ed25519::inverse(x.0, pz.1); + crate::hacl::ed25519::fmul(out.0, py.0, x.0); + crate::hacl::ed25519::reduce(out.0); + crate::hacl::ed25519::fmul(out.1, pz.0, x.0); + crate::hacl::ed25519::reduce_513(out.1); + let x0: (&[u64], &[u64]) = out.0.split_at(0usize); + let out0: (&[u64], &[u64]) = out.1.split_at(0usize); + let x00: u64 = x0.1[0usize]; + let b: u64 = x00 & 1u64; + crate::hacl::ed25519::store_51(z, out0.1); + let xbyte: u8 = b as u8; + let o31: u8 = z[31usize]; + z[31usize] = o31.wrapping_add(xbyte.wrapping_shl(7u32)) +} + +#[inline] +fn barrett_reduction(z: &mut [u64], t: &[u64]) { + let t0: u64 = t[0usize]; + let t1: u64 = t[1usize]; + let t2: u64 = t[2usize]; + let t3: u64 = t[3usize]; + let t4: u64 = t[4usize]; + let t5: u64 = t[5usize]; + let t6: u64 = t[6usize]; + let t7: u64 = t[7usize]; + let t8: u64 = t[8usize]; + let t9: u64 = t[9usize]; + let m0: u64 = 0x12631a5cf5d3edu64; + let m1: u64 = 0xf9dea2f79cd658u64; + let m2: u64 = 0x000000000014deu64; + let m3: u64 = 0x00000000000000u64; + let m4: u64 = 0x00000010000000u64; + let m00: u64 = m0; + let m10: u64 = m1; + let m20: u64 = m2; + let m30: u64 = m3; + let m40: u64 = m4; + let m01: u64 = 0x9ce5a30a2c131bu64; + let m11: u64 = 0x215d086329a7edu64; + let m21: u64 = 0xffffffffeb2106u64; + let m31: u64 = 0xffffffffffffffu64; + let m41: u64 = 0x00000fffffffffu64; + let mu0: u64 = m01; + let mu1: u64 = m11; + let mu2: u64 = m21; + let mu3: u64 = m31; + let mu4: u64 = m41; + let y·: u64 = (t5 & 0xffffffu64).wrapping_shl(32u32); + let x·: u64 = t4.wrapping_shr(24u32); + let z0: u64 = x· | y·; + let y·0: u64 = (t6 & 0xffffffu64).wrapping_shl(32u32); + let x·0: u64 = t5.wrapping_shr(24u32); + let z1: u64 = x·0 | y·0; + let y·1: u64 = (t7 & 0xffffffu64).wrapping_shl(32u32); + let x·1: u64 = t6.wrapping_shr(24u32); + let z2: u64 = x·1 | y·1; + let y·2: u64 = (t8 & 0xffffffu64).wrapping_shl(32u32); + let x·2: u64 = t7.wrapping_shr(24u32); + let z3: u64 = x·2 | y·2; + let y·3: u64 = (t9 & 0xffffffu64).wrapping_shl(32u32); + let x·3: u64 = t8.wrapping_shr(24u32); + let z4: u64 = x·3 | y·3; + let q0: u64 = z0; + let q1: u64 = z1; + let q2: u64 = z2; + let q3: u64 = z3; + let q4: u64 = z4; + let xy00: fstar::uint128::uint128 = fstar::uint128::mul_wide(q0, mu0); + let xy01: fstar::uint128::uint128 = fstar::uint128::mul_wide(q0, mu1); + let xy02: fstar::uint128::uint128 = fstar::uint128::mul_wide(q0, mu2); + let xy03: fstar::uint128::uint128 = fstar::uint128::mul_wide(q0, mu3); + let xy04: fstar::uint128::uint128 = fstar::uint128::mul_wide(q0, mu4); + let xy10: fstar::uint128::uint128 = fstar::uint128::mul_wide(q1, mu0); + let xy11: fstar::uint128::uint128 = fstar::uint128::mul_wide(q1, mu1); + let xy12: fstar::uint128::uint128 = fstar::uint128::mul_wide(q1, mu2); + let xy13: fstar::uint128::uint128 = fstar::uint128::mul_wide(q1, mu3); + let xy14: fstar::uint128::uint128 = fstar::uint128::mul_wide(q1, mu4); + let xy20: fstar::uint128::uint128 = fstar::uint128::mul_wide(q2, mu0); + let xy21: fstar::uint128::uint128 = fstar::uint128::mul_wide(q2, mu1); + let xy22: fstar::uint128::uint128 = fstar::uint128::mul_wide(q2, mu2); + let xy23: fstar::uint128::uint128 = fstar::uint128::mul_wide(q2, mu3); + let xy24: fstar::uint128::uint128 = fstar::uint128::mul_wide(q2, mu4); + let xy30: fstar::uint128::uint128 = fstar::uint128::mul_wide(q3, mu0); + let xy31: fstar::uint128::uint128 = fstar::uint128::mul_wide(q3, mu1); + let xy32: fstar::uint128::uint128 = fstar::uint128::mul_wide(q3, mu2); + let xy33: fstar::uint128::uint128 = fstar::uint128::mul_wide(q3, mu3); + let xy34: fstar::uint128::uint128 = fstar::uint128::mul_wide(q3, mu4); + let xy40: fstar::uint128::uint128 = fstar::uint128::mul_wide(q4, mu0); + let xy41: fstar::uint128::uint128 = fstar::uint128::mul_wide(q4, mu1); + let xy42: fstar::uint128::uint128 = fstar::uint128::mul_wide(q4, mu2); + let xy43: fstar::uint128::uint128 = fstar::uint128::mul_wide(q4, mu3); + let xy44: fstar::uint128::uint128 = fstar::uint128::mul_wide(q4, mu4); + let z00: fstar::uint128::uint128 = xy00; + let z10: fstar::uint128::uint128 = fstar::uint128::add_mod(xy01, xy10); + let z20: fstar::uint128::uint128 = + fstar::uint128::add_mod(fstar::uint128::add_mod(xy02, xy11), xy20); + let z30: fstar::uint128::uint128 = fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy03, xy12), xy21), + xy30, + ); + let z40: fstar::uint128::uint128 = fstar::uint128::add_mod( + fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy04, xy13), xy22), + xy31, + ), + xy40, + ); + let z5: fstar::uint128::uint128 = fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy14, xy23), xy32), + xy41, + ); + let z6: fstar::uint128::uint128 = + fstar::uint128::add_mod(fstar::uint128::add_mod(xy24, xy33), xy42); + let z7: fstar::uint128::uint128 = fstar::uint128::add_mod(xy34, xy43); + let z8: fstar::uint128::uint128 = xy44; + let carry: fstar::uint128::uint128 = fstar::uint128::shift_right(z00, 56u32); + let c0: fstar::uint128::uint128 = carry; + let carry0: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z10, c0), 56u32); + let c1: fstar::uint128::uint128 = carry0; + let carry1: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z20, c1), 56u32); + let c2: fstar::uint128::uint128 = carry1; + let carry2: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z30, c2), 56u32); + let c3: fstar::uint128::uint128 = carry2; + let carry3: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z40, c3), 56u32); + let t10: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z40, c3)) & 0xffffffffffffffu64; + let c4: fstar::uint128::uint128 = carry3; + let t41: u64 = t10; + let carry4: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z5, c4), 56u32); + let t100: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z5, c4)) & 0xffffffffffffffu64; + let c5: fstar::uint128::uint128 = carry4; + let t51: u64 = t100; + let carry5: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z6, c5), 56u32); + let t101: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z6, c5)) & 0xffffffffffffffu64; + let c6: fstar::uint128::uint128 = carry5; + let t61: u64 = t101; + let carry6: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z7, c6), 56u32); + let t102: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z7, c6)) & 0xffffffffffffffu64; + let c7: fstar::uint128::uint128 = carry6; + let t71: u64 = t102; + let carry7: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z8, c7), 56u32); + let t103: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z8, c7)) & 0xffffffffffffffu64; + let c8: fstar::uint128::uint128 = carry7; + let t81: u64 = t103; + let t91: u64 = fstar::uint128::uint128_to_uint64(c8); + let qmu4·: u64 = t41; + let qmu5·: u64 = t51; + let qmu6·: u64 = t61; + let qmu7·: u64 = t71; + let qmu8·: u64 = t81; + let qmu9·: u64 = t91; + let y·4: u64 = (qmu5· & 0xffffffffffu64).wrapping_shl(16u32); + let x·4: u64 = qmu4·.wrapping_shr(40u32); + let z01: u64 = x·4 | y·4; + let y·5: u64 = (qmu6· & 0xffffffffffu64).wrapping_shl(16u32); + let x·5: u64 = qmu5·.wrapping_shr(40u32); + let z11: u64 = x·5 | y·5; + let y·6: u64 = (qmu7· & 0xffffffffffu64).wrapping_shl(16u32); + let x·6: u64 = qmu6·.wrapping_shr(40u32); + let z21: u64 = x·6 | y·6; + let y·7: u64 = (qmu8· & 0xffffffffffu64).wrapping_shl(16u32); + let x·7: u64 = qmu7·.wrapping_shr(40u32); + let z31: u64 = x·7 | y·7; + let y·8: u64 = (qmu9· & 0xffffffffffu64).wrapping_shl(16u32); + let x·8: u64 = qmu8·.wrapping_shr(40u32); + let z41: u64 = x·8 | y·8; + let qdiv0: u64 = z01; + let qdiv1: u64 = z11; + let qdiv2: u64 = z21; + let qdiv3: u64 = z31; + let qdiv4: u64 = z41; + let r0: u64 = t0; + let r1: u64 = t1; + let r2: u64 = t2; + let r3: u64 = t3; + let r4: u64 = t4 & 0xffffffffffu64; + let xy000: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv0, m00); + let xy010: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv0, m10); + let xy020: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv0, m20); + let xy030: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv0, m30); + let xy040: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv0, m40); + let xy100: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv1, m00); + let xy110: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv1, m10); + let xy120: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv1, m20); + let xy130: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv1, m30); + let xy200: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv2, m00); + let xy210: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv2, m10); + let xy220: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv2, m20); + let xy300: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv3, m00); + let xy310: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv3, m10); + let xy400: fstar::uint128::uint128 = fstar::uint128::mul_wide(qdiv4, m00); + let carry8: fstar::uint128::uint128 = fstar::uint128::shift_right(xy000, 56u32); + let t104: u64 = fstar::uint128::uint128_to_uint64(xy000) & 0xffffffffffffffu64; + let c00: fstar::uint128::uint128 = carry8; + let t01: u64 = t104; + let carry9: fstar::uint128::uint128 = fstar::uint128::shift_right( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy010, xy100), c00), + 56u32, + ); + let t105: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod( + fstar::uint128::add_mod(xy010, xy100), + c00, + )) & 0xffffffffffffffu64; + let c10: fstar::uint128::uint128 = carry9; + let t11: u64 = t105; + let carry10: fstar::uint128::uint128 = fstar::uint128::shift_right( + fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy020, xy110), xy200), + c10, + ), + 56u32, + ); + let t106: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy020, xy110), xy200), + c10, + )) & 0xffffffffffffffu64; + let c20: fstar::uint128::uint128 = carry10; + let t21: u64 = t106; + let carry11: fstar::uint128::uint128 = fstar::uint128::shift_right( + fstar::uint128::add_mod( + fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy030, xy120), xy210), + xy300, + ), + c20, + ), + 56u32, + ); + let t107: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod( + fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy030, xy120), xy210), + xy300, + ), + c20, + )) & 0xffffffffffffffu64; + let c30: fstar::uint128::uint128 = carry11; + let t31: u64 = t107; + let t410: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod( + fstar::uint128::add_mod( + fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy040, xy130), xy220), + xy310, + ), + xy400, + ), + c30, + )) & 0xffffffffffu64; + let qmul0: u64 = t01; + let qmul1: u64 = t11; + let qmul2: u64 = t21; + let qmul3: u64 = t31; + let qmul4: u64 = t410; + let b: u64 = r0.wrapping_sub(qmul0).wrapping_shr(63u32); + let t108: u64 = b.wrapping_shl(56u32).wrapping_add(r0).wrapping_sub(qmul0); + let c11: u64 = b; + let t010: u64 = t108; + let b0: u64 = r1.wrapping_sub(qmul1.wrapping_add(c11)).wrapping_shr(63u32); + let t109: u64 = b0 + .wrapping_shl(56u32) + .wrapping_add(r1) + .wrapping_sub(qmul1.wrapping_add(c11)); + let c21: u64 = b0; + let t110: u64 = t109; + let b1: u64 = r2.wrapping_sub(qmul2.wrapping_add(c21)).wrapping_shr(63u32); + let t1010: u64 = b1 + .wrapping_shl(56u32) + .wrapping_add(r2) + .wrapping_sub(qmul2.wrapping_add(c21)); + let c31: u64 = b1; + let t210: u64 = t1010; + let b2: u64 = r3.wrapping_sub(qmul3.wrapping_add(c31)).wrapping_shr(63u32); + let t1011: u64 = b2 + .wrapping_shl(56u32) + .wrapping_add(r3) + .wrapping_sub(qmul3.wrapping_add(c31)); + let c40: u64 = b2; + let t310: u64 = t1011; + let b3: u64 = r4.wrapping_sub(qmul4.wrapping_add(c40)).wrapping_shr(63u32); + let t1012: u64 = b3 + .wrapping_shl(40u32) + .wrapping_add(r4) + .wrapping_sub(qmul4.wrapping_add(c40)); + let t411: u64 = t1012; + let s0: u64 = t010; + let s1: u64 = t110; + let s2: u64 = t210; + let s3: u64 = t310; + let s4: u64 = t411; + let m010: u64 = 0x12631a5cf5d3edu64; + let m110: u64 = 0xf9dea2f79cd658u64; + let m210: u64 = 0x000000000014deu64; + let m310: u64 = 0x00000000000000u64; + let m410: u64 = 0x00000010000000u64; + let y0: u64 = m010; + let y1: u64 = m110; + let y2: u64 = m210; + let y3: u64 = m310; + let y4: u64 = m410; + let b4: u64 = s0.wrapping_sub(y0).wrapping_shr(63u32); + let t1013: u64 = b4.wrapping_shl(56u32).wrapping_add(s0).wrapping_sub(y0); + let b00: u64 = b4; + let t011: u64 = t1013; + let b5: u64 = s1.wrapping_sub(y1.wrapping_add(b00)).wrapping_shr(63u32); + let t1014: u64 = b5 + .wrapping_shl(56u32) + .wrapping_add(s1) + .wrapping_sub(y1.wrapping_add(b00)); + let b10: u64 = b5; + let t111: u64 = t1014; + let b6: u64 = s2.wrapping_sub(y2.wrapping_add(b10)).wrapping_shr(63u32); + let t1015: u64 = b6 + .wrapping_shl(56u32) + .wrapping_add(s2) + .wrapping_sub(y2.wrapping_add(b10)); + let b20: u64 = b6; + let t211: u64 = t1015; + let b7: u64 = s3.wrapping_sub(y3.wrapping_add(b20)).wrapping_shr(63u32); + let t1016: u64 = b7 + .wrapping_shl(56u32) + .wrapping_add(s3) + .wrapping_sub(y3.wrapping_add(b20)); + let b30: u64 = b7; + let t311: u64 = t1016; + let b8: u64 = s4.wrapping_sub(y4.wrapping_add(b30)).wrapping_shr(63u32); + let t1017: u64 = b8 + .wrapping_shl(56u32) + .wrapping_add(s4) + .wrapping_sub(y4.wrapping_add(b30)); + let b40: u64 = b8; + let t412: u64 = t1017; + let mask: u64 = b40.wrapping_sub(1u64); + let z02: u64 = s0 ^ mask & (s0 ^ t011); + let z12: u64 = s1 ^ mask & (s1 ^ t111); + let z22: u64 = s2 ^ mask & (s2 ^ t211); + let z32: u64 = s3 ^ mask & (s3 ^ t311); + let z42: u64 = s4 ^ mask & (s4 ^ t412); + let z03: u64 = z02; + let z13: u64 = z12; + let z23: u64 = z22; + let z33: u64 = z32; + let z43: u64 = z42; + let o0: u64 = z03; + let o1: u64 = z13; + let o2: u64 = z23; + let o3: u64 = z33; + let o4: u64 = z43; + let z04: u64 = o0; + let z14: u64 = o1; + let z24: u64 = o2; + let z34: u64 = o3; + let z44: u64 = o4; + z[0usize] = z04; + z[1usize] = z14; + z[2usize] = z24; + z[3usize] = z34; + z[4usize] = z44 +} + +#[inline] +fn mul_modq(out: &mut [u64], x: &[u64], y: &[u64]) { + let mut tmp: [u64; 10] = [0u64; 10usize]; + let x0: u64 = x[0usize]; + let x1: u64 = x[1usize]; + let x2: u64 = x[2usize]; + let x3: u64 = x[3usize]; + let x4: u64 = x[4usize]; + let y0: u64 = y[0usize]; + let y1: u64 = y[1usize]; + let y2: u64 = y[2usize]; + let y3: u64 = y[3usize]; + let y4: u64 = y[4usize]; + let xy00: fstar::uint128::uint128 = fstar::uint128::mul_wide(x0, y0); + let xy01: fstar::uint128::uint128 = fstar::uint128::mul_wide(x0, y1); + let xy02: fstar::uint128::uint128 = fstar::uint128::mul_wide(x0, y2); + let xy03: fstar::uint128::uint128 = fstar::uint128::mul_wide(x0, y3); + let xy04: fstar::uint128::uint128 = fstar::uint128::mul_wide(x0, y4); + let xy10: fstar::uint128::uint128 = fstar::uint128::mul_wide(x1, y0); + let xy11: fstar::uint128::uint128 = fstar::uint128::mul_wide(x1, y1); + let xy12: fstar::uint128::uint128 = fstar::uint128::mul_wide(x1, y2); + let xy13: fstar::uint128::uint128 = fstar::uint128::mul_wide(x1, y3); + let xy14: fstar::uint128::uint128 = fstar::uint128::mul_wide(x1, y4); + let xy20: fstar::uint128::uint128 = fstar::uint128::mul_wide(x2, y0); + let xy21: fstar::uint128::uint128 = fstar::uint128::mul_wide(x2, y1); + let xy22: fstar::uint128::uint128 = fstar::uint128::mul_wide(x2, y2); + let xy23: fstar::uint128::uint128 = fstar::uint128::mul_wide(x2, y3); + let xy24: fstar::uint128::uint128 = fstar::uint128::mul_wide(x2, y4); + let xy30: fstar::uint128::uint128 = fstar::uint128::mul_wide(x3, y0); + let xy31: fstar::uint128::uint128 = fstar::uint128::mul_wide(x3, y1); + let xy32: fstar::uint128::uint128 = fstar::uint128::mul_wide(x3, y2); + let xy33: fstar::uint128::uint128 = fstar::uint128::mul_wide(x3, y3); + let xy34: fstar::uint128::uint128 = fstar::uint128::mul_wide(x3, y4); + let xy40: fstar::uint128::uint128 = fstar::uint128::mul_wide(x4, y0); + let xy41: fstar::uint128::uint128 = fstar::uint128::mul_wide(x4, y1); + let xy42: fstar::uint128::uint128 = fstar::uint128::mul_wide(x4, y2); + let xy43: fstar::uint128::uint128 = fstar::uint128::mul_wide(x4, y3); + let xy44: fstar::uint128::uint128 = fstar::uint128::mul_wide(x4, y4); + let z0: fstar::uint128::uint128 = xy00; + let z1: fstar::uint128::uint128 = fstar::uint128::add_mod(xy01, xy10); + let z2: fstar::uint128::uint128 = + fstar::uint128::add_mod(fstar::uint128::add_mod(xy02, xy11), xy20); + let z3: fstar::uint128::uint128 = fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy03, xy12), xy21), + xy30, + ); + let z4: fstar::uint128::uint128 = fstar::uint128::add_mod( + fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy04, xy13), xy22), + xy31, + ), + xy40, + ); + let z5: fstar::uint128::uint128 = fstar::uint128::add_mod( + fstar::uint128::add_mod(fstar::uint128::add_mod(xy14, xy23), xy32), + xy41, + ); + let z6: fstar::uint128::uint128 = + fstar::uint128::add_mod(fstar::uint128::add_mod(xy24, xy33), xy42); + let z7: fstar::uint128::uint128 = fstar::uint128::add_mod(xy34, xy43); + let z8: fstar::uint128::uint128 = xy44; + let carry: fstar::uint128::uint128 = fstar::uint128::shift_right(z0, 56u32); + let t: u64 = fstar::uint128::uint128_to_uint64(z0) & 0xffffffffffffffu64; + let c0: fstar::uint128::uint128 = carry; + let t0: u64 = t; + let carry0: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z1, c0), 56u32); + let t1: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z1, c0)) & 0xffffffffffffffu64; + let c1: fstar::uint128::uint128 = carry0; + let t10: u64 = t1; + let carry1: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z2, c1), 56u32); + let t2: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z2, c1)) & 0xffffffffffffffu64; + let c2: fstar::uint128::uint128 = carry1; + let t20: u64 = t2; + let carry2: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z3, c2), 56u32); + let t3: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z3, c2)) & 0xffffffffffffffu64; + let c3: fstar::uint128::uint128 = carry2; + let t30: u64 = t3; + let carry3: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z4, c3), 56u32); + let t4: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z4, c3)) & 0xffffffffffffffu64; + let c4: fstar::uint128::uint128 = carry3; + let t40: u64 = t4; + let carry4: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z5, c4), 56u32); + let t5: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z5, c4)) & 0xffffffffffffffu64; + let c5: fstar::uint128::uint128 = carry4; + let t50: u64 = t5; + let carry5: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z6, c5), 56u32); + let t6: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z6, c5)) & 0xffffffffffffffu64; + let c6: fstar::uint128::uint128 = carry5; + let t60: u64 = t6; + let carry6: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z7, c6), 56u32); + let t7: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z7, c6)) & 0xffffffffffffffu64; + let c7: fstar::uint128::uint128 = carry6; + let t70: u64 = t7; + let carry7: fstar::uint128::uint128 = + fstar::uint128::shift_right(fstar::uint128::add_mod(z8, c7), 56u32); + let t8: u64 = + fstar::uint128::uint128_to_uint64(fstar::uint128::add_mod(z8, c7)) & 0xffffffffffffffu64; + let c8: fstar::uint128::uint128 = carry7; + let t80: u64 = t8; + let t9: u64 = fstar::uint128::uint128_to_uint64(c8); + let z00: u64 = t0; + let z10: u64 = t10; + let z20: u64 = t20; + let z30: u64 = t30; + let z40: u64 = t40; + let z50: u64 = t50; + let z60: u64 = t60; + let z70: u64 = t70; + let z80: u64 = t80; + let z9: u64 = t9; + (&mut tmp)[0usize] = z00; + (&mut tmp)[1usize] = z10; + (&mut tmp)[2usize] = z20; + (&mut tmp)[3usize] = z30; + (&mut tmp)[4usize] = z40; + (&mut tmp)[5usize] = z50; + (&mut tmp)[6usize] = z60; + (&mut tmp)[7usize] = z70; + (&mut tmp)[8usize] = z80; + (&mut tmp)[9usize] = z9; + crate::hacl::ed25519::barrett_reduction(out, &tmp) +} + +#[inline] +fn add_modq(out: &mut [u64], x: &[u64], y: &[u64]) { + let x0: u64 = x[0usize]; + let x1: u64 = x[1usize]; + let x2: u64 = x[2usize]; + let x3: u64 = x[3usize]; + let x4: u64 = x[4usize]; + let y0: u64 = y[0usize]; + let y1: u64 = y[1usize]; + let y2: u64 = y[2usize]; + let y3: u64 = y[3usize]; + let y4: u64 = y[4usize]; + let carry: u64 = x0.wrapping_add(y0).wrapping_shr(56u32); + let t: u64 = x0.wrapping_add(y0) & 0xffffffffffffffu64; + let t0: u64 = t; + let c0: u64 = carry; + let carry0: u64 = x1.wrapping_add(y1).wrapping_add(c0).wrapping_shr(56u32); + let t1: u64 = x1.wrapping_add(y1).wrapping_add(c0) & 0xffffffffffffffu64; + let t10: u64 = t1; + let c1: u64 = carry0; + let carry1: u64 = x2.wrapping_add(y2).wrapping_add(c1).wrapping_shr(56u32); + let t2: u64 = x2.wrapping_add(y2).wrapping_add(c1) & 0xffffffffffffffu64; + let t20: u64 = t2; + let c2: u64 = carry1; + let carry2: u64 = x3.wrapping_add(y3).wrapping_add(c2).wrapping_shr(56u32); + let t3: u64 = x3.wrapping_add(y3).wrapping_add(c2) & 0xffffffffffffffu64; + let t30: u64 = t3; + let c3: u64 = carry2; + let t4: u64 = x4.wrapping_add(y4).wrapping_add(c3); + let m0: u64 = 0x12631a5cf5d3edu64; + let m1: u64 = 0xf9dea2f79cd658u64; + let m2: u64 = 0x000000000014deu64; + let m3: u64 = 0x00000000000000u64; + let m4: u64 = 0x00000010000000u64; + let y01: u64 = m0; + let y11: u64 = m1; + let y21: u64 = m2; + let y31: u64 = m3; + let y41: u64 = m4; + let b: u64 = t0.wrapping_sub(y01).wrapping_shr(63u32); + let t5: u64 = b.wrapping_shl(56u32).wrapping_add(t0).wrapping_sub(y01); + let b0: u64 = b; + let t01: u64 = t5; + let b1: u64 = t10.wrapping_sub(y11.wrapping_add(b0)).wrapping_shr(63u32); + let t6: u64 = b1 + .wrapping_shl(56u32) + .wrapping_add(t10) + .wrapping_sub(y11.wrapping_add(b0)); + let b10: u64 = b1; + let t11: u64 = t6; + let b2: u64 = t20.wrapping_sub(y21.wrapping_add(b10)).wrapping_shr(63u32); + let t7: u64 = b2 + .wrapping_shl(56u32) + .wrapping_add(t20) + .wrapping_sub(y21.wrapping_add(b10)); + let b20: u64 = b2; + let t21: u64 = t7; + let b3: u64 = t30.wrapping_sub(y31.wrapping_add(b20)).wrapping_shr(63u32); + let t8: u64 = b3 + .wrapping_shl(56u32) + .wrapping_add(t30) + .wrapping_sub(y31.wrapping_add(b20)); + let b30: u64 = b3; + let t31: u64 = t8; + let b4: u64 = t4.wrapping_sub(y41.wrapping_add(b30)).wrapping_shr(63u32); + let t9: u64 = b4 + .wrapping_shl(56u32) + .wrapping_add(t4) + .wrapping_sub(y41.wrapping_add(b30)); + let b40: u64 = b4; + let t41: u64 = t9; + let mask: u64 = b40.wrapping_sub(1u64); + let z0: u64 = t0 ^ mask & (t0 ^ t01); + let z1: u64 = t10 ^ mask & (t10 ^ t11); + let z2: u64 = t20 ^ mask & (t20 ^ t21); + let z3: u64 = t30 ^ mask & (t30 ^ t31); + let z4: u64 = t4 ^ mask & (t4 ^ t41); + let z00: u64 = z0; + let z10: u64 = z1; + let z20: u64 = z2; + let z30: u64 = z3; + let z40: u64 = z4; + let o0: u64 = z00; + let o1: u64 = z10; + let o2: u64 = z20; + let o3: u64 = z30; + let o4: u64 = z40; + let z01: u64 = o0; + let z11: u64 = o1; + let z21: u64 = o2; + let z31: u64 = o3; + let z41: u64 = o4; + out[0usize] = z01; + out[1usize] = z11; + out[2usize] = z21; + out[3usize] = z31; + out[4usize] = z41 +} + +#[inline] +fn gte_q(s: &[u64]) -> bool { + let s0: u64 = s[0usize]; + let s1: u64 = s[1usize]; + let s2: u64 = s[2usize]; + let s3: u64 = s[3usize]; + let s4: u64 = s[4usize]; + if s4 > 0x00000010000000u64 { + true + } else if s4 < 0x00000010000000u64 { + false + } else if s3 > 0x00000000000000u64 || s2 > 0x000000000014deu64 { + true + } else if s2 < 0x000000000014deu64 { + false + } else if s1 > 0xf9dea2f79cd658u64 { + true + } else if s1 < 0xf9dea2f79cd658u64 { + false + } else { + s0 >= 0x12631a5cf5d3edu64 + } +} + +#[inline] +fn eq(a: &[u64], b: &[u64]) -> bool { + let a0: u64 = a[0usize]; + let a1: u64 = a[1usize]; + let a2: u64 = a[2usize]; + let a3: u64 = a[3usize]; + let a4: u64 = a[4usize]; + let b0: u64 = b[0usize]; + let b1: u64 = b[1usize]; + let b2: u64 = b[2usize]; + let b3: u64 = b[3usize]; + let b4: u64 = b[4usize]; + a0 == b0 && a1 == b1 && a2 == b2 && a3 == b3 && a4 == b4 +} + +pub(crate) fn point_equal(p: &[u64], q: &[u64]) -> bool { + let mut tmp: [u64; 20] = [0u64; 20usize]; + let pxqz: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let qxpz: (&mut [u64], &mut [u64]) = pxqz.1.split_at_mut(5usize); + crate::hacl::ed25519::fmul(qxpz.0, &p[0usize..], &q[10usize..]); + crate::hacl::ed25519::reduce(qxpz.0); + crate::hacl::ed25519::fmul(qxpz.1, &q[0usize..], &p[10usize..]); + crate::hacl::ed25519::reduce(qxpz.1); + let b: bool = crate::hacl::ed25519::eq(qxpz.0, qxpz.1); + if b { + let pyqz: (&mut [u64], &mut [u64]) = qxpz.1.split_at_mut(5usize); + let qypz: (&mut [u64], &mut [u64]) = pyqz.1.split_at_mut(5usize); + crate::hacl::ed25519::fmul(qypz.0, &p[5usize..], &q[10usize..]); + crate::hacl::ed25519::reduce(qypz.0); + crate::hacl::ed25519::fmul(qypz.1, &q[5usize..], &p[10usize..]); + crate::hacl::ed25519::reduce(qypz.1); + crate::hacl::ed25519::eq(qypz.0, qypz.1) + } else { + false + } +} + +pub(crate) fn point_negate(p: &[u64], out: &mut [u64]) { + let mut zero: [u64; 5] = [0u64; 5usize]; + (&mut zero)[0usize] = 0u64; + (&mut zero)[1usize] = 0u64; + (&mut zero)[2usize] = 0u64; + (&mut zero)[3usize] = 0u64; + (&mut zero)[4usize] = 0u64; + let x: (&[u64], &[u64]) = p.split_at(0usize); + let y: (&[u64], &[u64]) = x.1.split_at(5usize); + let z: (&[u64], &[u64]) = y.1.split_at(5usize); + let t: (&[u64], &[u64]) = z.1.split_at(5usize); + let x1: (&mut [u64], &mut [u64]) = out.split_at_mut(0usize); + let y1: (&mut [u64], &mut [u64]) = x1.1.split_at_mut(5usize); + let z1: (&mut [u64], &mut [u64]) = y1.1.split_at_mut(5usize); + let t1: (&mut [u64], &mut [u64]) = z1.1.split_at_mut(5usize); + crate::hacl::ed25519::fdifference(y1.0, &zero, y.0); + crate::hacl::ed25519::reduce_513(y1.0); + (z1.0[0usize..5usize]).copy_from_slice(&z.0[0usize..5usize]); + (t1.0[0usize..5usize]).copy_from_slice(&t.0[0usize..5usize]); + crate::hacl::ed25519::fdifference(t1.1, &zero, t.1); + crate::hacl::ed25519::reduce_513(t1.1) +} + +#[inline] +fn precomp_get_consttime(table: &[u64], bits_l: u64, tmp: &mut [u64]) { + (tmp[0usize..20usize]).copy_from_slice(&(&table[0usize..])[0usize..20usize]); + krml::unroll_for!(15, "i", 0u32, 1u32, { + let c: u64 = fstar::uint64::eq_mask(bits_l, i.wrapping_add(1u32) as u64); + let res_j: (&[u64], &[u64]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(20u32) as usize); + krml::unroll_for!(20, "i0", 0u32, 1u32, { + let x: u64 = c & res_j.1[i0 as usize] | !c & tmp[i0 as usize]; + let os: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + os.1[i0 as usize] = x + }) + }) +} + +#[inline] +fn point_mul_g(out: &mut [u64], scalar: &[u8]) { + let mut bscalar: [u64; 4] = [0u64; 4usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let bj: (&[u8], &[u8]) = scalar.split_at(i.wrapping_mul(8u32) as usize); + let u: u64 = lowstar::endianness::load64_le(bj.1); + let r: u64 = u; + let x: u64 = r; + let os: (&mut [u64], &mut [u64]) = bscalar.split_at_mut(0usize); + os.1[i as usize] = x + }); + let mut q1: [u64; 20] = [0u64; 20usize]; + let gx: (&mut [u64], &mut [u64]) = q1.split_at_mut(0usize); + let gy: (&mut [u64], &mut [u64]) = gx.1.split_at_mut(5usize); + let gz: (&mut [u64], &mut [u64]) = gy.1.split_at_mut(5usize); + let gt: (&mut [u64], &mut [u64]) = gz.1.split_at_mut(5usize); + gy.0[0usize] = 0x00062d608f25d51au64; + gy.0[1usize] = 0x000412a4b4f6592au64; + gy.0[2usize] = 0x00075b7171a4b31du64; + gy.0[3usize] = 0x0001ff60527118feu64; + gy.0[4usize] = 0x000216936d3cd6e5u64; + gz.0[0usize] = 0x0006666666666658u64; + gz.0[1usize] = 0x0004ccccccccccccu64; + gz.0[2usize] = 0x0001999999999999u64; + gz.0[3usize] = 0x0003333333333333u64; + gz.0[4usize] = 0x0006666666666666u64; + gt.0[0usize] = 1u64; + gt.0[1usize] = 0u64; + gt.0[2usize] = 0u64; + gt.0[3usize] = 0u64; + gt.0[4usize] = 0u64; + gt.1[0usize] = 0x00068ab3a5b7dda3u64; + gt.1[1usize] = 0x00000eea2a5eadbbu64; + gt.1[2usize] = 0x0002af8df483c27eu64; + gt.1[3usize] = 0x000332b375274732u64; + gt.1[4usize] = 0x00067875f0fd78b7u64; + let q2: [u64; 20] = [ + 13559344787725u64, + 2051621493703448u64, + 1947659315640708u64, + 626856790370168u64, + 1592804284034836u64, + 1781728767459187u64, + 278818420518009u64, + 2038030359908351u64, + 910625973862690u64, + 471887343142239u64, + 1298543306606048u64, + 794147365642417u64, + 129968992326749u64, + 523140861678572u64, + 1166419653909231u64, + 2009637196928390u64, + 1288020222395193u64, + 1007046974985829u64, + 208981102651386u64, + 2074009315253380u64, + ]; + let q3: [u64; 20] = [ + 557549315715710u64, + 196756086293855u64, + 846062225082495u64, + 1865068224838092u64, + 991112090754908u64, + 522916421512828u64, + 2098523346722375u64, + 1135633221747012u64, + 858420432114866u64, + 186358544306082u64, + 1044420411868480u64, + 2080052304349321u64, + 557301814716724u64, + 1305130257814057u64, + 2126012765451197u64, + 1441004402875101u64, + 353948968859203u64, + 470765987164835u64, + 1507675957683570u64, + 1086650358745097u64, + ]; + let q4: [u64; 20] = [ + 1129953239743101u64, + 1240339163956160u64, + 61002583352401u64, + 2017604552196030u64, + 1576867829229863u64, + 1508654942849389u64, + 270111619664077u64, + 1253097517254054u64, + 721798270973250u64, + 161923365415298u64, + 828530877526011u64, + 1494851059386763u64, + 662034171193976u64, + 1315349646974670u64, + 2199229517308806u64, + 497078277852673u64, + 1310507715989956u64, + 1881315714002105u64, + 2214039404983803u64, + 1331036420272667u64, + ]; + let r1: (&[u64], &[u64]) = bscalar.split_at(0usize); + let r2: (&[u64], &[u64]) = r1.1.split_at(1usize); + let r3: (&[u64], &[u64]) = r2.1.split_at(1usize); + let r4: (&[u64], &[u64]) = r3.1.split_at(1usize); + crate::hacl::ed25519::make_point_inf(out); + let mut tmp: [u64; 20] = [0u64; 20usize]; + krml::unroll_for!(16, "i", 0u32, 1u32, { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut p_copy: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_double(out, &p_copy) + }); + let k: u32 = 64u32.wrapping_sub(4u32.wrapping_mul(i)).wrapping_sub(4u32); + let bits_l: u64 = bignum::bignum_base::bn_get_bits_u64(1u32, r4.1, k, 4u32); + lowstar::ignore::ignore::<&[u64]>( + &crate::hacl::ed25519_precomptable::precomp_g_pow2_192_table_w4, + ); + crate::hacl::ed25519::precomp_get_consttime( + &crate::hacl::ed25519_precomptable::precomp_g_pow2_192_table_w4, + bits_l, + &mut tmp, + ); + let mut p_copy: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_add(out, &p_copy, &tmp); + let k0: u32 = 64u32.wrapping_sub(4u32.wrapping_mul(i)).wrapping_sub(4u32); + let bits_l0: u64 = bignum::bignum_base::bn_get_bits_u64(1u32, r4.0, k0, 4u32); + lowstar::ignore::ignore::<&[u64]>( + &crate::hacl::ed25519_precomptable::precomp_g_pow2_128_table_w4, + ); + crate::hacl::ed25519::precomp_get_consttime( + &crate::hacl::ed25519_precomptable::precomp_g_pow2_128_table_w4, + bits_l0, + &mut tmp, + ); + let mut p_copy0: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy0)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_add(out, &p_copy0, &tmp); + let k1: u32 = 64u32.wrapping_sub(4u32.wrapping_mul(i)).wrapping_sub(4u32); + let bits_l1: u64 = bignum::bignum_base::bn_get_bits_u64(1u32, r3.0, k1, 4u32); + lowstar::ignore::ignore::<&[u64]>( + &crate::hacl::ed25519_precomptable::precomp_g_pow2_64_table_w4, + ); + crate::hacl::ed25519::precomp_get_consttime( + &crate::hacl::ed25519_precomptable::precomp_g_pow2_64_table_w4, + bits_l1, + &mut tmp, + ); + let mut p_copy1: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy1)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_add(out, &p_copy1, &tmp); + let k2: u32 = 64u32.wrapping_sub(4u32.wrapping_mul(i)).wrapping_sub(4u32); + let bits_l2: u64 = bignum::bignum_base::bn_get_bits_u64(1u32, r2.0, k2, 4u32); + lowstar::ignore::ignore::<&[u64]>( + &crate::hacl::ed25519_precomptable::precomp_basepoint_table_w4, + ); + crate::hacl::ed25519::precomp_get_consttime( + &crate::hacl::ed25519_precomptable::precomp_basepoint_table_w4, + bits_l2, + &mut tmp, + ); + let mut p_copy2: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy2)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_add(out, &p_copy2, &tmp) + }); + lowstar::ignore::ignore::<&[u64]>(&q2); + lowstar::ignore::ignore::<&[u64]>(&q3); + lowstar::ignore::ignore::<&[u64]>(&q4) +} + +#[inline] +fn point_mul_g_double_vartime(out: &mut [u64], scalar1: &[u8], scalar2: &[u8], q2: &[u64]) { + let mut tmp: [u64; 28] = [0u64; 28usize]; + let g: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let bscalar1: (&mut [u64], &mut [u64]) = g.1.split_at_mut(20usize); + let bscalar2: (&mut [u64], &mut [u64]) = bscalar1.1.split_at_mut(4usize); + let gx: (&mut [u64], &mut [u64]) = bscalar1.0.split_at_mut(0usize); + let gy: (&mut [u64], &mut [u64]) = gx.1.split_at_mut(5usize); + let gz: (&mut [u64], &mut [u64]) = gy.1.split_at_mut(5usize); + let gt: (&mut [u64], &mut [u64]) = gz.1.split_at_mut(5usize); + gy.0[0usize] = 0x00062d608f25d51au64; + gy.0[1usize] = 0x000412a4b4f6592au64; + gy.0[2usize] = 0x00075b7171a4b31du64; + gy.0[3usize] = 0x0001ff60527118feu64; + gy.0[4usize] = 0x000216936d3cd6e5u64; + gz.0[0usize] = 0x0006666666666658u64; + gz.0[1usize] = 0x0004ccccccccccccu64; + gz.0[2usize] = 0x0001999999999999u64; + gz.0[3usize] = 0x0003333333333333u64; + gz.0[4usize] = 0x0006666666666666u64; + gt.0[0usize] = 1u64; + gt.0[1usize] = 0u64; + gt.0[2usize] = 0u64; + gt.0[3usize] = 0u64; + gt.0[4usize] = 0u64; + gt.1[0usize] = 0x00068ab3a5b7dda3u64; + gt.1[1usize] = 0x00000eea2a5eadbbu64; + gt.1[2usize] = 0x0002af8df483c27eu64; + gt.1[3usize] = 0x000332b375274732u64; + gt.1[4usize] = 0x00067875f0fd78b7u64; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let bj: (&[u8], &[u8]) = scalar1.split_at(i.wrapping_mul(8u32) as usize); + let u: u64 = lowstar::endianness::load64_le(bj.1); + let r: u64 = u; + let x: u64 = r; + let os: (&mut [u64], &mut [u64]) = bscalar2.0.split_at_mut(0usize); + os.1[i as usize] = x + }); + krml::unroll_for!(4, "i", 0u32, 1u32, { + let bj: (&[u8], &[u8]) = scalar2.split_at(i.wrapping_mul(8u32) as usize); + let u: u64 = lowstar::endianness::load64_le(bj.1); + let r: u64 = u; + let x: u64 = r; + let os: (&mut [u64], &mut [u64]) = bscalar2.1.split_at_mut(0usize); + os.1[i as usize] = x + }); + let mut table2: [u64; 640] = [0u64; 640usize]; + let mut tmp1: [u64; 20] = [0u64; 20usize]; + let t0: (&mut [u64], &mut [u64]) = table2.split_at_mut(0usize); + let t1: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(20usize); + crate::hacl::ed25519::make_point_inf(t1.0); + (t1.1[0usize..20usize]).copy_from_slice(&q2[0usize..20usize]); + lowstar::ignore::ignore::<&[u64]>(&table2); + krml::unroll_for!(15, "i", 0u32, 1u32, { + let t11: (&[u64], &[u64]) = + table2.split_at(i.wrapping_add(1u32).wrapping_mul(20u32) as usize); + let mut p_copy: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy)[0usize..20usize]).copy_from_slice(&t11.1[0usize..20usize]); + crate::hacl::ed25519::point_double(&mut tmp1, &p_copy); + ((&mut table2)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(20u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(20u32) as usize + 20usize]) + .copy_from_slice(&(&tmp1)[0usize..20usize]); + let t2: (&[u64], &[u64]) = + table2.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(20u32) as usize); + let mut p_copy0: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy0)[0usize..20usize]).copy_from_slice(&q2[0usize..20usize]); + crate::hacl::ed25519::point_add(&mut tmp1, &p_copy0, t2.1); + ((&mut table2)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(20u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(20u32) as usize + 20usize]) + .copy_from_slice(&(&tmp1)[0usize..20usize]) + }); + let mut tmp10: [u64; 20] = [0u64; 20usize]; + let i: u32 = 255u32; + let bits_c: u64 = bignum::bignum_base::bn_get_bits_u64(4u32, bscalar2.0, i, 5u32); + let bits_l32: u32 = bits_c as u32; + let a_bits_l: &[u64] = &(&crate::hacl::ed25519_precomptable::precomp_basepoint_table_w5) + [bits_l32.wrapping_mul(20u32) as usize..]; + (out[0usize..20usize]).copy_from_slice(&a_bits_l[0usize..20usize]); + let i0: u32 = 255u32; + let bits_c0: u64 = bignum::bignum_base::bn_get_bits_u64(4u32, bscalar2.1, i0, 5u32); + let bits_l320: u32 = bits_c0 as u32; + let a_bits_l0: (&[u64], &[u64]) = table2.split_at(bits_l320.wrapping_mul(20u32) as usize); + ((&mut tmp10)[0usize..20usize]).copy_from_slice(&a_bits_l0.1[0usize..20usize]); + let mut p_copy: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_add(out, &p_copy, &tmp10); + let mut tmp11: [u64; 20] = [0u64; 20usize]; + for i1 in 0u32..51u32 { + krml::unroll_for!(5, "_i", 0u32, 1u32, { + let mut p_copy0: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy0)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_double(out, &p_copy0) + }); + let k: u32 = 255u32 + .wrapping_sub(5u32.wrapping_mul(i1)) + .wrapping_sub(5u32); + let bits_l: u64 = bignum::bignum_base::bn_get_bits_u64(4u32, bscalar2.1, k, 5u32); + lowstar::ignore::ignore::<&[u64]>(&table2); + let bits_l321: u32 = bits_l as u32; + let a_bits_l1: (&[u64], &[u64]) = table2.split_at(bits_l321.wrapping_mul(20u32) as usize); + ((&mut tmp11)[0usize..20usize]).copy_from_slice(&a_bits_l1.1[0usize..20usize]); + let mut p_copy0: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy0)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_add(out, &p_copy0, &tmp11); + let k0: u32 = 255u32 + .wrapping_sub(5u32.wrapping_mul(i1)) + .wrapping_sub(5u32); + let bits_l0: u64 = bignum::bignum_base::bn_get_bits_u64(4u32, bscalar2.0, k0, 5u32); + lowstar::ignore::ignore::<&[u64]>( + &crate::hacl::ed25519_precomptable::precomp_basepoint_table_w5, + ); + let bits_l322: u32 = bits_l0 as u32; + let a_bits_l2: &[u64] = &(&crate::hacl::ed25519_precomptable::precomp_basepoint_table_w5) + [bits_l322.wrapping_mul(20u32) as usize..]; + ((&mut tmp11)[0usize..20usize]).copy_from_slice(&a_bits_l2[0usize..20usize]); + let mut p_copy1: [u64; 20] = [0u64; 20usize]; + ((&mut p_copy1)[0usize..20usize]).copy_from_slice(&out[0usize..20usize]); + crate::hacl::ed25519::point_add(out, &p_copy1, &tmp11) + } +} + +#[inline] +fn point_negate_mul_double_g_vartime(out: &mut [u64], scalar1: &[u8], scalar2: &[u8], q2: &[u64]) { + let mut q2_neg: [u64; 20] = [0u64; 20usize]; + crate::hacl::ed25519::point_negate(q2, &mut q2_neg); + crate::hacl::ed25519::point_mul_g_double_vartime(out, scalar1, scalar2, &q2_neg) +} + +#[inline] +fn store_56(out: &mut [u8], b: &[u64]) { + let b0: u64 = b[0usize]; + let b1: u64 = b[1usize]; + let b2: u64 = b[2usize]; + let b3: u64 = b[3usize]; + let b4: u64 = b[4usize]; + let b4·: u32 = b4 as u32; + let b8: (&mut [u8], &mut [u8]) = out.split_at_mut(0usize); + lowstar::endianness::store64_le(b8.1, b0); + let b80: (&mut [u8], &mut [u8]) = b8.1.split_at_mut(7usize); + lowstar::endianness::store64_le(b80.1, b1); + let b81: (&mut [u8], &mut [u8]) = b80.1.split_at_mut(7usize); + lowstar::endianness::store64_le(b81.1, b2); + let b82: (&mut [u8], &mut [u8]) = b81.1.split_at_mut(7usize); + lowstar::endianness::store64_le(b82.1, b3); + lowstar::endianness::store32_le(&mut out[28usize..], b4·) +} + +#[inline] +fn load_64_bytes(out: &mut [u64], b: &[u8]) { + let b8: (&[u8], &[u8]) = b.split_at(0usize); + let u: u64 = lowstar::endianness::load64_le(b8.1); + let z: u64 = u; + let b0: u64 = z & 0xffffffffffffffu64; + let b80: (&[u8], &[u8]) = b8.1.split_at(7usize); + let u0: u64 = lowstar::endianness::load64_le(b80.1); + let z0: u64 = u0; + let b1: u64 = z0 & 0xffffffffffffffu64; + let b81: (&[u8], &[u8]) = b80.1.split_at(7usize); + let u1: u64 = lowstar::endianness::load64_le(b81.1); + let z1: u64 = u1; + let b2: u64 = z1 & 0xffffffffffffffu64; + let b82: (&[u8], &[u8]) = b81.1.split_at(7usize); + let u2: u64 = lowstar::endianness::load64_le(b82.1); + let z2: u64 = u2; + let b3: u64 = z2 & 0xffffffffffffffu64; + let b83: (&[u8], &[u8]) = b82.1.split_at(7usize); + let u3: u64 = lowstar::endianness::load64_le(b83.1); + let z3: u64 = u3; + let b4: u64 = z3 & 0xffffffffffffffu64; + let b84: (&[u8], &[u8]) = b83.1.split_at(7usize); + let u4: u64 = lowstar::endianness::load64_le(b84.1); + let z4: u64 = u4; + let b5: u64 = z4 & 0xffffffffffffffu64; + let b85: (&[u8], &[u8]) = b84.1.split_at(7usize); + let u5: u64 = lowstar::endianness::load64_le(b85.1); + let z5: u64 = u5; + let b6: u64 = z5 & 0xffffffffffffffu64; + let b86: (&[u8], &[u8]) = b85.1.split_at(7usize); + let u6: u64 = lowstar::endianness::load64_le(b86.1); + let z6: u64 = u6; + let b7: u64 = z6 & 0xffffffffffffffu64; + let b87: (&[u8], &[u8]) = b86.1.split_at(7usize); + let u7: u64 = lowstar::endianness::load64_le(b87.1); + let z7: u64 = u7; + let b88: u64 = z7 & 0xffffffffffffffu64; + let b63: u8 = b[63usize]; + let b9: u64 = b63 as u64; + out[0usize] = b0; + out[1usize] = b1; + out[2usize] = b2; + out[3usize] = b3; + out[4usize] = b4; + out[5usize] = b5; + out[6usize] = b6; + out[7usize] = b7; + out[8usize] = b88; + out[9usize] = b9 +} + +#[inline] +fn load_32_bytes(out: &mut [u64], b: &[u8]) { + let b8: (&[u8], &[u8]) = b.split_at(0usize); + let u: u64 = lowstar::endianness::load64_le(b8.1); + let z: u64 = u; + let b0: u64 = z & 0xffffffffffffffu64; + let b80: (&[u8], &[u8]) = b8.1.split_at(7usize); + let u0: u64 = lowstar::endianness::load64_le(b80.1); + let z0: u64 = u0; + let b1: u64 = z0 & 0xffffffffffffffu64; + let b81: (&[u8], &[u8]) = b80.1.split_at(7usize); + let u1: u64 = lowstar::endianness::load64_le(b81.1); + let z1: u64 = u1; + let b2: u64 = z1 & 0xffffffffffffffu64; + let b82: (&[u8], &[u8]) = b81.1.split_at(7usize); + let u2: u64 = lowstar::endianness::load64_le(b82.1); + let z2: u64 = u2; + let b3: u64 = z2 & 0xffffffffffffffu64; + let u3: u32 = lowstar::endianness::load32_le(&b[28usize..]); + let b4: u32 = u3; + let b41: u64 = b4 as u64; + out[0usize] = b0; + out[1usize] = b1; + out[2usize] = b2; + out[3usize] = b3; + out[4usize] = b41 +} + +#[inline] +fn sha512_pre_msg(hash: &mut [u8], prefix: &[u8], len: u32, input: &[u8]) { + let buf: [u8; 128] = [0u8; 128usize]; + let mut block_state: [u64; 8] = [0u64; 8usize]; + libcrux_sha2::hacl::sha512_init(&mut block_state); + let s: libcrux_hacl_rs::streaming_types::state_64 = + libcrux_hacl_rs::streaming_types::state_64 { + block_state: Box::new(block_state), + buf: Box::new(buf), + total_len: 0u32 as u64, + }; + let mut p: [libcrux_hacl_rs::streaming_types::state_64; 1] = [s; 1usize]; + let st: &mut [libcrux_hacl_rs::streaming_types::state_64] = &mut p; + let err0: libcrux_hacl_rs::streaming_types::error_code = + libcrux_sha2::hacl::update_512(st, prefix, 32u32); + let err1: libcrux_hacl_rs::streaming_types::error_code = + libcrux_sha2::hacl::update_512(st, input, len); + lowstar::ignore::ignore::(err0); + lowstar::ignore::ignore::(err1); + libcrux_sha2::hacl::digest_512(st, hash) +} + +#[inline] +fn sha512_pre_pre2_msg(hash: &mut [u8], prefix: &[u8], prefix2: &[u8], len: u32, input: &[u8]) { + let buf: [u8; 128] = [0u8; 128usize]; + let mut block_state: [u64; 8] = [0u64; 8usize]; + libcrux_sha2::hacl::sha512_init(&mut block_state); + let s: libcrux_hacl_rs::streaming_types::state_64 = + libcrux_hacl_rs::streaming_types::state_64 { + block_state: Box::new(block_state), + buf: Box::new(buf), + total_len: 0u32 as u64, + }; + let mut p: [libcrux_hacl_rs::streaming_types::state_64; 1] = [s; 1usize]; + let st: &mut [libcrux_hacl_rs::streaming_types::state_64] = &mut p; + let err0: libcrux_hacl_rs::streaming_types::error_code = + libcrux_sha2::hacl::update_512(st, prefix, 32u32); + let err1: libcrux_hacl_rs::streaming_types::error_code = + libcrux_sha2::hacl::update_512(st, prefix2, 32u32); + let err2: libcrux_hacl_rs::streaming_types::error_code = + libcrux_sha2::hacl::update_512(st, input, len); + lowstar::ignore::ignore::(err0); + lowstar::ignore::ignore::(err1); + lowstar::ignore::ignore::(err2); + libcrux_sha2::hacl::digest_512(st, hash) +} + +#[inline] +fn sha512_modq_pre(out: &mut [u64], prefix: &[u8], len: u32, input: &[u8]) { + let mut tmp: [u64; 10] = [0u64; 10usize]; + let mut hash: [u8; 64] = [0u8; 64usize]; + crate::hacl::ed25519::sha512_pre_msg(&mut hash, prefix, len, input); + crate::hacl::ed25519::load_64_bytes(&mut tmp, &hash); + crate::hacl::ed25519::barrett_reduction(out, &tmp) +} + +#[inline] +fn sha512_modq_pre_pre2(out: &mut [u64], prefix: &[u8], prefix2: &[u8], len: u32, input: &[u8]) { + let mut tmp: [u64; 10] = [0u64; 10usize]; + let mut hash: [u8; 64] = [0u8; 64usize]; + crate::hacl::ed25519::sha512_pre_pre2_msg(&mut hash, prefix, prefix2, len, input); + crate::hacl::ed25519::load_64_bytes(&mut tmp, &hash); + crate::hacl::ed25519::barrett_reduction(out, &tmp) +} + +#[inline] +fn point_mul_g_compress(out: &mut [u8], s: &[u8]) { + let mut tmp: [u64; 20] = [0u64; 20usize]; + crate::hacl::ed25519::point_mul_g(&mut tmp, s); + crate::hacl::ed25519::point_compress(out, &tmp) +} + +#[inline] +fn secret_expand(expanded: &mut [u8], secret: &[u8]) { + libcrux_sha2::hacl::hash_512(expanded, secret, 32u32); + let h_low: (&mut [u8], &mut [u8]) = expanded.split_at_mut(0usize); + let h_low0: u8 = h_low.1[0usize]; + let h_low31: u8 = h_low.1[31usize]; + h_low.1[0usize] = h_low0 & 0xf8u8; + h_low.1[31usize] = h_low31 & 127u8 | 64u8 +} + +/** +Compute the public key from the private key. + + @param[out] public_key Points to 32 bytes of valid memory, i.e., `uint8_t[32]`. Must not overlap the memory location of `private_key`. + @param[in] private_key Points to 32 bytes of valid memory containing the private key, i.e., `uint8_t[32]`. +*/ +pub fn secret_to_public(public_key: &mut [u8], private_key: &[u8]) { + let mut expanded_secret: [u8; 64] = [0u8; 64usize]; + crate::hacl::ed25519::secret_expand(&mut expanded_secret, private_key); + let a: (&[u8], &[u8]) = expanded_secret.split_at(0usize); + crate::hacl::ed25519::point_mul_g_compress(public_key, a.1) +} + +/** +Compute the expanded keys for an Ed25519 signature. + + @param[out] expanded_keys Points to 96 bytes of valid memory, i.e., `uint8_t[96]`. Must not overlap the memory location of `private_key`. + @param[in] private_key Points to 32 bytes of valid memory containing the private key, i.e., `uint8_t[32]`. + + If one needs to sign several messages under the same private key, it is more efficient + to call `expand_keys` only once and `sign_expanded` multiple times, for each message. +*/ +pub fn expand_keys(expanded_keys: &mut [u8], private_key: &[u8]) { + let s_prefix: (&mut [u8], &mut [u8]) = expanded_keys.split_at_mut(32usize); + crate::hacl::ed25519::secret_expand(s_prefix.1, private_key); + let public_key: (&mut [u8], &mut [u8]) = s_prefix.0.split_at_mut(0usize); + let s: (&[u8], &[u8]) = s_prefix.1.split_at(0usize); + crate::hacl::ed25519::point_mul_g_compress(public_key.1, s.1) +} + +/** +Create an Ed25519 signature with the (precomputed) expanded keys. + + @param[out] signature Points to 64 bytes of valid memory, i.e., `uint8_t[64]`. Must not overlap the memory locations of `expanded_keys` nor `msg`. + @param[in] expanded_keys Points to 96 bytes of valid memory, i.e., `uint8_t[96]`, containing the expanded keys obtained by invoking `expand_keys`. + @param[in] msg_len Length of `msg`. + @param[in] msg Points to `msg_len` bytes of valid memory containing the message, i.e., `uint8_t[msg_len]`. + + If one needs to sign several messages under the same private key, it is more efficient + to call `expand_keys` only once and `sign_expanded` multiple times, for each message. +*/ +pub fn sign_expanded(signature: &mut [u8], expanded_keys: &[u8], msg_len: u32, msg: &[u8]) { + let rs: (&mut [u8], &mut [u8]) = signature.split_at_mut(0usize); + let ss: (&mut [u8], &mut [u8]) = rs.1.split_at_mut(32usize); + let mut rq: [u64; 5] = [0u64; 5usize]; + let mut hq: [u64; 5] = [0u64; 5usize]; + let mut rb: [u8; 32] = [0u8; 32usize]; + let public_key: (&[u8], &[u8]) = expanded_keys.split_at(0usize); + let s: (&[u8], &[u8]) = public_key.1.split_at(32usize); + let prefix: (&[u8], &[u8]) = s.1.split_at(32usize); + crate::hacl::ed25519::sha512_modq_pre(&mut rq, prefix.1, msg_len, msg); + crate::hacl::ed25519::store_56(&mut rb, &rq); + crate::hacl::ed25519::point_mul_g_compress(ss.0, &rb); + crate::hacl::ed25519::sha512_modq_pre_pre2(&mut hq, ss.0, s.0, msg_len, msg); + let mut aq: [u64; 5] = [0u64; 5usize]; + crate::hacl::ed25519::load_32_bytes(&mut aq, prefix.0); + let mut y_copy: [u64; 5] = [0u64; 5usize]; + ((&mut y_copy)[0usize..5usize]).copy_from_slice(&(&aq)[0usize..5usize]); + crate::hacl::ed25519::mul_modq(&mut aq, &hq, &y_copy); + let mut y_copy0: [u64; 5] = [0u64; 5usize]; + ((&mut y_copy0)[0usize..5usize]).copy_from_slice(&(&aq)[0usize..5usize]); + crate::hacl::ed25519::add_modq(&mut aq, &rq, &y_copy0); + crate::hacl::ed25519::store_56(ss.1, &aq) +} + +/** +Create an Ed25519 signature. + + @param[out] signature Points to 64 bytes of valid memory, i.e., `uint8_t[64]`. Must not overlap the memory locations of `private_key` nor `msg`. + @param[in] private_key Points to 32 bytes of valid memory containing the private key, i.e., `uint8_t[32]`. + @param[in] msg_len Length of `msg`. + @param[in] msg Points to `msg_len` bytes of valid memory containing the message, i.e., `uint8_t[msg_len]`. + + The function first calls `expand_keys` and then invokes `sign_expanded`. + + If one needs to sign several messages under the same private key, it is more efficient + to call `expand_keys` only once and `sign_expanded` multiple times, for each message. +*/ +pub fn sign(signature: &mut [u8], private_key: &[u8], msg_len: u32, msg: &[u8]) { + let mut expanded_keys: [u8; 96] = [0u8; 96usize]; + crate::hacl::ed25519::expand_keys(&mut expanded_keys, private_key); + crate::hacl::ed25519::sign_expanded(signature, &expanded_keys, msg_len, msg) +} + +/** +Verify an Ed25519 signature. + + @param public_key Points to 32 bytes of valid memory containing the public key, i.e., `uint8_t[32]`. + @param msg_len Length of `msg`. + @param msg Points to `msg_len` bytes of valid memory containing the message, i.e., `uint8_t[msg_len]`. + @param signature Points to 64 bytes of valid memory containing the signature, i.e., `uint8_t[64]`. + + @return Returns `true` if the signature is valid and `false` otherwise. +*/ +pub fn verify(public_key: &[u8], msg_len: u32, msg: &[u8], signature: &[u8]) -> bool { + let mut a·: [u64; 20] = [0u64; 20usize]; + let b: bool = crate::hacl::ed25519::point_decompress(&mut a·, public_key); + if b { + let mut r·: [u64; 20] = [0u64; 20usize]; + let rs: (&[u8], &[u8]) = signature.split_at(0usize); + let b·: bool = crate::hacl::ed25519::point_decompress(&mut r·, rs.1); + if b· { + let mut hb: [u8; 32] = [0u8; 32usize]; + let rs1: (&[u8], &[u8]) = rs.1.split_at(0usize); + let sb: (&[u8], &[u8]) = rs1.1.split_at(32usize); + let mut tmp: [u64; 5] = [0u64; 5usize]; + crate::hacl::ed25519::load_32_bytes(&mut tmp, sb.1); + let b1: bool = crate::hacl::ed25519::gte_q(&tmp); + let b10: bool = b1; + if b10 { + false + } else { + let mut tmp0: [u64; 5] = [0u64; 5usize]; + crate::hacl::ed25519::sha512_modq_pre_pre2( + &mut tmp0, sb.0, public_key, msg_len, msg, + ); + crate::hacl::ed25519::store_56(&mut hb, &tmp0); + let mut exp_d: [u64; 20] = [0u64; 20usize]; + crate::hacl::ed25519::point_negate_mul_double_g_vartime(&mut exp_d, sb.1, &hb, &a·); + let b2: bool = crate::hacl::ed25519::point_equal(&exp_d, &r·); + b2 + } + } else { + false + } + } else { + false + } +} diff --git a/ed25519/src/hacl/ed25519_precomptable.rs b/ed25519/src/hacl/ed25519_precomptable.rs new file mode 100644 index 000000000..f0e8def64 --- /dev/null +++ b/ed25519/src/hacl/ed25519_precomptable.rs @@ -0,0 +1,1940 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +pub(crate) const precomp_basepoint_table_w4: [u64; 320] = [ + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1738742601995546u64, + 1146398526822698u64, + 2070867633025821u64, + 562264141797630u64, + 587772402128613u64, + 1801439850948184u64, + 1351079888211148u64, + 450359962737049u64, + 900719925474099u64, + 1801439850948198u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1841354044333475u64, + 16398895984059u64, + 755974180946558u64, + 900171276175154u64, + 1821297809914039u64, + 1661154287933054u64, + 284530020860578u64, + 1390261174866914u64, + 1524110943907984u64, + 1045603498418422u64, + 928651508580478u64, + 1383326941296346u64, + 961937908925785u64, + 80455759693706u64, + 904734540352947u64, + 1507481815385608u64, + 2223447444246085u64, + 1083941587175919u64, + 2059929906842505u64, + 1581435440146976u64, + 782730187692425u64, + 9928394897574u64, + 1539449519985236u64, + 1923587931078510u64, + 552919286076056u64, + 376925408065760u64, + 447320488831784u64, + 1362918338468019u64, + 1470031896696846u64, + 2189796996539902u64, + 1337552949959847u64, + 1762287177775726u64, + 237994495816815u64, + 1277840395970544u64, + 543972849007241u64, + 1224692671618814u64, + 162359533289271u64, + 282240927125249u64, + 586909166382289u64, + 17726488197838u64, + 377014554985659u64, + 1433835303052512u64, + 702061469493692u64, + 1142253108318154u64, + 318297794307551u64, + 954362646308543u64, + 517363881452320u64, + 1868013482130416u64, + 262562472373260u64, + 902232853249919u64, + 2107343057055746u64, + 462368348619024u64, + 1893758677092974u64, + 2177729767846389u64, + 2168532543559143u64, + 443867094639821u64, + 730169342581022u64, + 1564589016879755u64, + 51218195700649u64, + 76684578423745u64, + 560266272480743u64, + 922517457707697u64, + 2066645939860874u64, + 1318277348414638u64, + 1576726809084003u64, + 1817337608563665u64, + 1874240939237666u64, + 754733726333910u64, + 97085310406474u64, + 751148364309235u64, + 1622159695715187u64, + 1444098819684916u64, + 130920805558089u64, + 1260449179085308u64, + 1860021740768461u64, + 110052860348509u64, + 193830891643810u64, + 164148413933881u64, + 180017794795332u64, + 1523506525254651u64, + 465981629225956u64, + 559733514964572u64, + 1279624874416974u64, + 2026642326892306u64, + 1425156829982409u64, + 2160936383793147u64, + 1061870624975247u64, + 2023497043036941u64, + 117942212883190u64, + 490339622800774u64, + 1729931303146295u64, + 422305932971074u64, + 529103152793096u64, + 1211973233775992u64, + 721364955929681u64, + 1497674430438813u64, + 342545521275073u64, + 2102107575279372u64, + 2108462244669966u64, + 1382582406064082u64, + 2206396818383323u64, + 2109093268641147u64, + 10809845110983u64, + 1605176920880099u64, + 744640650753946u64, + 1712758897518129u64, + 373410811281809u64, + 648838265800209u64, + 813058095530999u64, + 513987632620169u64, + 465516160703329u64, + 2136322186126330u64, + 1979645899422932u64, + 1197131006470786u64, + 1467836664863979u64, + 1340751381374628u64, + 1810066212667962u64, + 1009933588225499u64, + 1106129188080873u64, + 1388980405213901u64, + 533719246598044u64, + 1169435803073277u64, + 198920999285821u64, + 487492330629854u64, + 1807093008537778u64, + 1540899012923865u64, + 2075080271659867u64, + 1527990806921523u64, + 1323728742908002u64, + 1568595959608205u64, + 1388032187497212u64, + 2026968840050568u64, + 1396591153295755u64, + 820416950170901u64, + 520060313205582u64, + 2016404325094901u64, + 1584709677868520u64, + 272161374469956u64, + 1567188603996816u64, + 1986160530078221u64, + 553930264324589u64, + 1058426729027503u64, + 8762762886675u64, + 2216098143382988u64, + 1835145266889223u64, + 1712936431558441u64, + 1017009937844974u64, + 585361667812740u64, + 2114711541628181u64, + 2238729632971439u64, + 121257546253072u64, + 847154149018345u64, + 211972965476684u64, + 287499084460129u64, + 2098247259180197u64, + 839070411583329u64, + 339551619574372u64, + 1432951287640743u64, + 526481249498942u64, + 931991661905195u64, + 1884279965674487u64, + 200486405604411u64, + 364173020594788u64, + 518034455936955u64, + 1085564703965501u64, + 16030410467927u64, + 604865933167613u64, + 1695298441093964u64, + 498856548116159u64, + 2193030062787034u64, + 1706339802964179u64, + 1721199073493888u64, + 820740951039755u64, + 1216053436896834u64, + 23954895815139u64, + 1662515208920491u64, + 1705443427511899u64, + 1957928899570365u64, + 1189636258255725u64, + 1795695471103809u64, + 1691191297654118u64, + 282402585374360u64, + 460405330264832u64, + 63765529445733u64, + 469763447404473u64, + 733607089694996u64, + 685410420186959u64, + 1096682630419738u64, + 1162548510542362u64, + 1020949526456676u64, + 1211660396870573u64, + 613126398222696u64, + 1117829165843251u64, + 742432540886650u64, + 1483755088010658u64, + 942392007134474u64, + 1447834130944107u64, + 489368274863410u64, + 23192985544898u64, + 648442406146160u64, + 785438843373876u64, + 249464684645238u64, + 170494608205618u64, + 335112827260550u64, + 1462050123162735u64, + 1084803668439016u64, + 853459233600325u64, + 215777728187495u64, + 1965759433526974u64, + 1349482894446537u64, + 694163317612871u64, + 860536766165036u64, + 1178788094084321u64, + 1652739626626996u64, + 2115723946388185u64, + 1577204379094664u64, + 1083882859023240u64, + 1768759143381635u64, + 1737180992507258u64, + 246054513922239u64, + 577253134087234u64, + 356340280578042u64, + 1638917769925142u64, + 223550348130103u64, + 470592666638765u64, + 22663573966996u64, + 596552461152400u64, + 364143537069499u64, + 3942119457699u64, + 107951982889287u64, + 1843471406713209u64, + 1625773041610986u64, + 1466141092501702u64, + 1043024095021271u64, + 310429964047508u64, + 98559121500372u64, + 152746933782868u64, + 259407205078261u64, + 828123093322585u64, + 1576847274280091u64, + 1170871375757302u64, + 1588856194642775u64, + 984767822341977u64, + 1141497997993760u64, + 809325345150796u64, + 1879837728202511u64, + 201340910657893u64, + 1079157558888483u64, + 1052373448588065u64, + 1732036202501778u64, + 2105292670328445u64, + 679751387312402u64, + 1679682144926229u64, + 1695823455818780u64, + 498852317075849u64, + 1786555067788433u64, + 1670727545779425u64, + 117945875433544u64, + 407939139781844u64, + 854632120023778u64, + 1413383148360437u64, + 286030901733673u64, + 1207361858071196u64, + 461340408181417u64, + 1096919590360164u64, + 1837594897475685u64, + 533755561544165u64, + 1638688042247712u64, + 1431653684793005u64, + 1036458538873559u64, + 390822120341779u64, + 1920929837111618u64, + 543426740024168u64, + 645751357799929u64, + 2245025632994463u64, + 1550778638076452u64, + 223738153459949u64, + 1337209385492033u64, + 1276967236456531u64, + 1463815821063071u64, + 2070620870191473u64, + 1199170709413753u64, + 273230877394166u64, + 1873264887608046u64, + 890877152910775u64, +]; + +pub(crate) const precomp_g_pow2_64_table_w4: [u64; 320] = [ + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 13559344787725u64, + 2051621493703448u64, + 1947659315640708u64, + 626856790370168u64, + 1592804284034836u64, + 1781728767459187u64, + 278818420518009u64, + 2038030359908351u64, + 910625973862690u64, + 471887343142239u64, + 1298543306606048u64, + 794147365642417u64, + 129968992326749u64, + 523140861678572u64, + 1166419653909231u64, + 2009637196928390u64, + 1288020222395193u64, + 1007046974985829u64, + 208981102651386u64, + 2074009315253380u64, + 1564056062071967u64, + 276822668750618u64, + 206621292512572u64, + 470304361809269u64, + 895215438398493u64, + 1527859053868686u64, + 1624967223409369u64, + 811821865979736u64, + 350450534838340u64, + 219143807921807u64, + 507994540371254u64, + 986513794574720u64, + 1142661369967121u64, + 621278293399257u64, + 556189161519781u64, + 351964007865066u64, + 2011573453777822u64, + 1367125527151537u64, + 1691316722438196u64, + 731328817345164u64, + 1284781192709232u64, + 478439299539269u64, + 204842178076429u64, + 2085125369913651u64, + 1980773492792985u64, + 1480264409524940u64, + 688389585376233u64, + 612962643526972u64, + 165595382536676u64, + 1850300069212263u64, + 1176357203491551u64, + 1880164984292321u64, + 10786153104736u64, + 1242293560510203u64, + 1358399951884084u64, + 1901358796610357u64, + 1385092558795806u64, + 1734893785311348u64, + 2046201851951191u64, + 1233811309557352u64, + 1531160168656129u64, + 1543287181303358u64, + 516121446374119u64, + 723422668089935u64, + 1228176774959679u64, + 1598014722726267u64, + 1630810326658412u64, + 1343833067463760u64, + 1024397964362099u64, + 1157142161346781u64, + 56422174971792u64, + 544901687297092u64, + 1291559028869009u64, + 1336918672345120u64, + 1390874603281353u64, + 1127199512010904u64, + 992644979940964u64, + 1035213479783573u64, + 36043651196100u64, + 1220961519321221u64, + 1348190007756977u64, + 579420200329088u64, + 1703819961008985u64, + 1993919213460047u64, + 2225080008232251u64, + 392785893702372u64, + 464312521482632u64, + 1224525362116057u64, + 810394248933036u64, + 932513521649107u64, + 592314953488703u64, + 586334603791548u64, + 1310888126096549u64, + 650842674074281u64, + 1596447001791059u64, + 2086767406328284u64, + 1866377645879940u64, + 1721604362642743u64, + 738502322566890u64, + 1851901097729689u64, + 1158347571686914u64, + 2023626733470827u64, + 329625404653699u64, + 563555875598551u64, + 516554588079177u64, + 1134688306104598u64, + 186301198420809u64, + 1339952213563300u64, + 643605614625891u64, + 1947505332718043u64, + 1722071694852824u64, + 601679570440694u64, + 1821275721236351u64, + 1808307842870389u64, + 1654165204015635u64, + 1457334100715245u64, + 217784948678349u64, + 1820622417674817u64, + 1946121178444661u64, + 597980757799332u64, + 1745271227710764u64, + 2010952890941980u64, + 339811849696648u64, + 1066120666993872u64, + 261276166508990u64, + 323098645774553u64, + 207454744271283u64, + 941448672977675u64, + 71890920544375u64, + 840849789313357u64, + 1223996070717926u64, + 196832550853408u64, + 115986818309231u64, + 1586171527267675u64, + 1666169080973450u64, + 1456454731176365u64, + 44467854369003u64, + 2149656190691480u64, + 283446383597589u64, + 2040542647729974u64, + 305705593840224u64, + 475315822269791u64, + 648133452550632u64, + 169218658835720u64, + 24960052338251u64, + 938907951346766u64, + 425970950490510u64, + 1037622011013183u64, + 1026882082708180u64, + 1635699409504916u64, + 1644776942870488u64, + 2151820331175914u64, + 824120674069819u64, + 835744976610113u64, + 1991271032313190u64, + 96507354724855u64, + 400645405133260u64, + 343728076650825u64, + 1151585441385566u64, + 1403339955333520u64, + 230186314139774u64, + 1736248861506714u64, + 1010804378904572u64, + 1394932289845636u64, + 1901351256960852u64, + 2187471430089807u64, + 1003853262342670u64, + 1327743396767461u64, + 1465160415991740u64, + 366625359144534u64, + 1534791405247604u64, + 1790905930250187u64, + 1255484115292738u64, + 2223291365520443u64, + 210967717407408u64, + 26722916813442u64, + 1919574361907910u64, + 468825088280256u64, + 2230011775946070u64, + 1628365642214479u64, + 568871869234932u64, + 1066987968780488u64, + 1692242903745558u64, + 1678903997328589u64, + 214262165888021u64, + 1929686748607204u64, + 1790138967989670u64, + 1790261616022076u64, + 1559824537553112u64, + 1230364591311358u64, + 147531939886346u64, + 1528207085815487u64, + 477957922927292u64, + 285670243881618u64, + 264430080123332u64, + 1163108160028611u64, + 373201522147371u64, + 34903775270979u64, + 1750870048600662u64, + 1319328308741084u64, + 1547548634278984u64, + 1691259592202927u64, + 2247758037259814u64, + 329611399953677u64, + 1385555496268877u64, + 2242438354031066u64, + 1329523854843632u64, + 399895373846055u64, + 678005703193452u64, + 1496357700997771u64, + 71909969781942u64, + 1515391418612349u64, + 470110837888178u64, + 1981307309417466u64, + 1259888737412276u64, + 669991710228712u64, + 1048546834514303u64, + 1678323291295512u64, + 2172033978088071u64, + 1529278455500556u64, + 901984601941894u64, + 780867622403807u64, + 550105677282793u64, + 975860231176136u64, + 525188281689178u64, + 49966114807992u64, + 1776449263836645u64, + 267851776380338u64, + 2225969494054620u64, + 2016794225789822u64, + 1186108678266608u64, + 1023083271408882u64, + 1119289418565906u64, + 1248185897348801u64, + 1846081539082697u64, + 23756429626075u64, + 1441999021105403u64, + 724497586552825u64, + 1287761623605379u64, + 685303359654224u64, + 2217156930690570u64, + 163769288918347u64, + 1098423278284094u64, + 1391470723006008u64, + 570700152353516u64, + 744804507262556u64, + 2200464788609495u64, + 624141899161992u64, + 2249570166275684u64, + 378706441983561u64, + 122486379999375u64, + 430741162798924u64, + 113847463452574u64, + 266250457840685u64, + 2120743625072743u64, + 222186221043927u64, + 1964290018305582u64, + 1435278008132477u64, + 1670867456663734u64, + 2009989552599079u64, + 1348024113448744u64, + 1158423886300455u64, + 1356467152691569u64, + 306943042363674u64, + 926879628664255u64, + 1349295689598324u64, + 725558330071205u64, + 536569987519948u64, + 116436990335366u64, + 1551888573800376u64, + 2044698345945451u64, + 104279940291311u64, + 251526570943220u64, + 754735828122925u64, + 33448073576361u64, + 994605876754543u64, + 546007584022006u64, + 2217332798409487u64, + 706477052561591u64, + 131174619428653u64, + 2148698284087243u64, + 239290486205186u64, + 2161325796952184u64, + 1713452845607994u64, + 1297861562938913u64, + 1779539876828514u64, + 1926559018603871u64, + 296485747893968u64, + 1859208206640686u64, + 538513979002718u64, + 103998826506137u64, + 2025375396538469u64, + 1370680785701206u64, + 1698557311253840u64, + 1411096399076595u64, + 2132580530813677u64, + 2071564345845035u64, + 498581428556735u64, + 1136010486691371u64, + 1927619356993146u64, +]; + +pub(crate) const precomp_g_pow2_128_table_w4: [u64; 320] = [ + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 557549315715710u64, + 196756086293855u64, + 846062225082495u64, + 1865068224838092u64, + 991112090754908u64, + 522916421512828u64, + 2098523346722375u64, + 1135633221747012u64, + 858420432114866u64, + 186358544306082u64, + 1044420411868480u64, + 2080052304349321u64, + 557301814716724u64, + 1305130257814057u64, + 2126012765451197u64, + 1441004402875101u64, + 353948968859203u64, + 470765987164835u64, + 1507675957683570u64, + 1086650358745097u64, + 1911913434398388u64, + 66086091117182u64, + 1137511952425971u64, + 36958263512141u64, + 2193310025325256u64, + 1085191426269045u64, + 1232148267909446u64, + 1449894406170117u64, + 1241416717139557u64, + 1940876999212868u64, + 829758415918121u64, + 309608450373449u64, + 2228398547683851u64, + 1580623271960188u64, + 1675601502456740u64, + 1360363115493548u64, + 1098397313096815u64, + 1809255384359797u64, + 1458261916834384u64, + 210682545649705u64, + 1606836641068115u64, + 1230478270405318u64, + 1843192771547802u64, + 1794596343564051u64, + 229060710252162u64, + 2169742775467181u64, + 701467067318072u64, + 696018499035555u64, + 521051885339807u64, + 158329567901874u64, + 740426481832143u64, + 1369811177301441u64, + 503351589084015u64, + 1781114827942261u64, + 1650493549693035u64, + 2174562418345156u64, + 456517194809244u64, + 2052761522121179u64, + 2233342271123682u64, + 1445872925177435u64, + 1131882576902813u64, + 220765848055241u64, + 1280259961403769u64, + 1581497080160712u64, + 1477441080108824u64, + 218428165202767u64, + 1970598141278907u64, + 643366736173069u64, + 2167909426804014u64, + 834993711408259u64, + 1922437166463212u64, + 1900036281472252u64, + 513794844386304u64, + 1297904164900114u64, + 1147626295373268u64, + 1910101606251299u64, + 182933838633381u64, + 806229530787362u64, + 155511666433200u64, + 290522463375462u64, + 534373523491751u64, + 1302938814480515u64, + 1664979184120445u64, + 304235649499423u64, + 339284524318609u64, + 1881717946973483u64, + 1670802286833842u64, + 2223637120675737u64, + 135818919485814u64, + 1144856572842792u64, + 2234981613434386u64, + 963917024969826u64, + 402275378284993u64, + 141532417412170u64, + 921537468739387u64, + 963905069722607u64, + 1405442890733358u64, + 1567763927164655u64, + 1664776329195930u64, + 2095924165508507u64, + 994243110271379u64, + 1243925610609353u64, + 1029845815569727u64, + 1001968867985629u64, + 170368934002484u64, + 1100906131583801u64, + 1825190326449569u64, + 1462285121182096u64, + 1545240767016377u64, + 797859025652273u64, + 1062758326657530u64, + 1125600735118266u64, + 739325756774527u64, + 1420144485966996u64, + 1915492743426702u64, + 752968196344993u64, + 882156396938351u64, + 1909097048763227u64, + 849058590685611u64, + 840754951388500u64, + 1832926948808323u64, + 2023317100075297u64, + 322382745442827u64, + 1569741341737601u64, + 1678986113194987u64, + 757598994581938u64, + 29678659580705u64, + 1239680935977986u64, + 1509239427168474u64, + 1055981929287006u64, + 1894085471158693u64, + 916486225488490u64, + 642168890366120u64, + 300453362620010u64, + 1858797242721481u64, + 2077989823177130u64, + 510228455273334u64, + 1473284798689270u64, + 5173934574301u64, + 765285232030050u64, + 1007154707631065u64, + 1862128712885972u64, + 168873464821340u64, + 1967853269759318u64, + 1489896018263031u64, + 592451806166369u64, + 1242298565603883u64, + 1838918921339058u64, + 697532763910695u64, + 294335466239059u64, + 135687058387449u64, + 2133734403874176u64, + 2121911143127699u64, + 20222476737364u64, + 1200824626476747u64, + 1397731736540791u64, + 702378430231418u64, + 59059527640068u64, + 460992547183981u64, + 1016125857842765u64, + 1273530839608957u64, + 96724128829301u64, + 1313433042425233u64, + 3543822857227u64, + 761975685357118u64, + 110417360745248u64, + 1079634164577663u64, + 2044574510020457u64, + 338709058603120u64, + 94541336042799u64, + 127963233585039u64, + 94427896272258u64, + 1143501979342182u64, + 1217958006212230u64, + 2153887831492134u64, + 1519219513255575u64, + 251793195454181u64, + 392517349345200u64, + 1507033011868881u64, + 2208494254670752u64, + 1364389582694359u64, + 2214069430728063u64, + 1272814257105752u64, + 741450148906352u64, + 1105776675555685u64, + 824447222014984u64, + 528745219306376u64, + 589427609121575u64, + 1501786838809155u64, + 379067373073147u64, + 184909476589356u64, + 1346887560616185u64, + 1932023742314082u64, + 1633302311869264u64, + 1685314821133069u64, + 1836610282047884u64, + 1595571594397150u64, + 615441688872198u64, + 1926435616702564u64, + 235632180396480u64, + 1051918343571810u64, + 2150570051687050u64, + 879198845408738u64, + 1443966275205464u64, + 481362545245088u64, + 512807443532642u64, + 641147578283480u64, + 1594276116945596u64, + 1844812743300602u64, + 2044559316019485u64, + 202620777969020u64, + 852992984136302u64, + 1500869642692910u64, + 1085216217052457u64, + 1736294372259758u64, + 2009666354486552u64, + 1262389020715248u64, + 1166527705256867u64, + 1409917450806036u64, + 1705819160057637u64, + 1116901782584378u64, + 1278460472285473u64, + 257879811360157u64, + 40314007176886u64, + 701309846749639u64, + 1380457676672777u64, + 631519782380272u64, + 1196339573466793u64, + 955537708940017u64, + 532725633381530u64, + 641190593731833u64, + 7214357153807u64, + 481922072107983u64, + 1634886189207352u64, + 1247659758261633u64, + 1655809614786430u64, + 43105797900223u64, + 76205809912607u64, + 1936575107455823u64, + 1107927314642236u64, + 2199986333469333u64, + 802974829322510u64, + 718173128143482u64, + 539385184235615u64, + 2075693785611221u64, + 953281147333690u64, + 1623571637172587u64, + 655274535022250u64, + 1568078078819021u64, + 101142125049712u64, + 1488441673350881u64, + 1457969561944515u64, + 1492622544287712u64, + 2041460689280803u64, + 1961848091392887u64, + 461003520846938u64, + 934728060399807u64, + 117723291519705u64, + 1027773762863526u64, + 56765304991567u64, + 2184028379550479u64, + 1768767711894030u64, + 1304432068983172u64, + 498080974452325u64, + 2134905654858163u64, + 1446137427202647u64, + 551613831549590u64, + 680288767054205u64, + 1278113339140386u64, + 378149431842614u64, + 80520494426960u64, + 2080985256348782u64, + 673432591799820u64, + 739189463724560u64, + 1847191452197509u64, + 527737312871602u64, + 477609358840073u64, + 1891633072677946u64, + 1841456828278466u64, + 2242502936489002u64, + 524791829362709u64, + 276648168514036u64, + 991706903257619u64, + 512580228297906u64, + 1216855104975946u64, + 67030930303149u64, + 769593945208213u64, + 2048873385103577u64, + 455635274123107u64, + 2077404927176696u64, + 1803539634652306u64, + 1837579953843417u64, + 1564240068662828u64, + 1964310918970435u64, + 832822906252492u64, + 1516044634195010u64, + 770571447506889u64, + 602215152486818u64, + 1760828333136947u64, + 730156776030376u64, +]; + +pub(crate) const precomp_g_pow2_192_table_w4: [u64; 320] = [ + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1129953239743101u64, + 1240339163956160u64, + 61002583352401u64, + 2017604552196030u64, + 1576867829229863u64, + 1508654942849389u64, + 270111619664077u64, + 1253097517254054u64, + 721798270973250u64, + 161923365415298u64, + 828530877526011u64, + 1494851059386763u64, + 662034171193976u64, + 1315349646974670u64, + 2199229517308806u64, + 497078277852673u64, + 1310507715989956u64, + 1881315714002105u64, + 2214039404983803u64, + 1331036420272667u64, + 296286697520787u64, + 1179367922639127u64, + 25348441419697u64, + 2200984961703188u64, + 150893128908291u64, + 1978614888570852u64, + 1539657347172046u64, + 553810196523619u64, + 246017573977646u64, + 1440448985385485u64, + 346049108099981u64, + 601166606218546u64, + 855822004151713u64, + 1957521326383188u64, + 1114240380430887u64, + 1349639675122048u64, + 957375954499040u64, + 111551795360136u64, + 618586733648988u64, + 490708840688866u64, + 1267002049697314u64, + 1130723224930028u64, + 215603029480828u64, + 1277138555414710u64, + 1556750324971322u64, + 1407903521793741u64, + 1836836546590749u64, + 576500297444199u64, + 2074707599091135u64, + 1826239864380012u64, + 1935365705983312u64, + 239501825683682u64, + 1594236669034980u64, + 1283078975055301u64, + 856745636255925u64, + 1342128647959981u64, + 945216428379689u64, + 938746202496410u64, + 105775123333919u64, + 1379852610117266u64, + 1770216827500275u64, + 1016017267535704u64, + 1902885522469532u64, + 994184703730489u64, + 2227487538793763u64, + 53155967096055u64, + 1264120808114350u64, + 1334928769376729u64, + 393911808079997u64, + 826229239481845u64, + 1827903006733192u64, + 1449283706008465u64, + 1258040415217849u64, + 1641484112868370u64, + 1140150841968176u64, + 391113338021313u64, + 162138667815833u64, + 742204396566060u64, + 110709233440557u64, + 90179377432917u64, + 530511949644489u64, + 911568635552279u64, + 135869304780166u64, + 617719999563692u64, + 1802525001631319u64, + 1836394639510490u64, + 1862739456475085u64, + 1378284444664288u64, + 1617882529391756u64, + 876124429891172u64, + 1147654641445091u64, + 1476943370400542u64, + 688601222759067u64, + 2120281968990205u64, + 1387113236912611u64, + 2125245820685788u64, + 1030674016350092u64, + 1594684598654247u64, + 1165939511879820u64, + 271499323244173u64, + 546587254515484u64, + 945603425742936u64, + 1242252568170226u64, + 561598728058142u64, + 604827091794712u64, + 19869753585186u64, + 565367744708915u64, + 536755754533603u64, + 1767258313589487u64, + 907952975936127u64, + 292851652613937u64, + 163573546237963u64, + 837601408384564u64, + 591996990118301u64, + 2126051747693057u64, + 182247548824566u64, + 908369044122868u64, + 1335442699947273u64, + 2234292296528612u64, + 689537529333034u64, + 2174778663790714u64, + 1011407643592667u64, + 1856130618715473u64, + 1557437221651741u64, + 2250285407006102u64, + 1412384213410827u64, + 1428042038612456u64, + 962709733973660u64, + 313995703125919u64, + 1844969155869325u64, + 787716782673657u64, + 622504542173478u64, + 930119043384654u64, + 2128870043952488u64, + 537781531479523u64, + 1556666269904940u64, + 417333635741346u64, + 1986743846438415u64, + 877620478041197u64, + 2205624582983829u64, + 595260668884488u64, + 2025159350373157u64, + 2091659716088235u64, + 1423634716596391u64, + 653686638634080u64, + 1972388399989956u64, + 795575741798014u64, + 889240107997846u64, + 1446156876910732u64, + 1028507012221776u64, + 1071697574586478u64, + 1689630411899691u64, + 604092816502174u64, + 1909917373896122u64, + 1602544877643837u64, + 1227177032923867u64, + 62684197535630u64, + 186146290753883u64, + 414449055316766u64, + 1560555880866750u64, + 157579947096755u64, + 230526795502384u64, + 1197673369665894u64, + 593779215869037u64, + 214638834474097u64, + 1796344443484478u64, + 493550548257317u64, + 1628442824033694u64, + 1410811655893495u64, + 1009361960995171u64, + 604736219740352u64, + 392445928555351u64, + 1254295770295706u64, + 1958074535046128u64, + 508699942241019u64, + 739405911261325u64, + 1678760393882409u64, + 517763708545996u64, + 640040257898722u64, + 384966810872913u64, + 407454748380128u64, + 152604679407451u64, + 185102854927662u64, + 1448175503649595u64, + 100328519208674u64, + 1153263667012830u64, + 1643926437586490u64, + 609632142834154u64, + 980984004749261u64, + 855290732258779u64, + 2186022163021506u64, + 1254052618626070u64, + 1850030517182611u64, + 162348933090207u64, + 1948712273679932u64, + 1331832516262191u64, + 1219400369175863u64, + 89689036937483u64, + 1554886057235815u64, + 1520047528432789u64, + 81263957652811u64, + 146612464257008u64, + 2207945627164163u64, + 919846660682546u64, + 1925694087906686u64, + 2102027292388012u64, + 887992003198635u64, + 1817924871537027u64, + 746660005584342u64, + 753757153275525u64, + 91394270908699u64, + 511837226544151u64, + 736341543649373u64, + 1256371121466367u64, + 1977778299551813u64, + 817915174462263u64, + 1602323381418035u64, + 190035164572930u64, + 603796401391181u64, + 2152666873671669u64, + 1813900316324112u64, + 1292622433358041u64, + 888439870199892u64, + 978918155071994u64, + 534184417909805u64, + 466460084317313u64, + 1275223140288685u64, + 786407043883517u64, + 1620520623925754u64, + 1753625021290269u64, + 751937175104525u64, + 905301961820613u64, + 697059847245437u64, + 584919033981144u64, + 1272165506533156u64, + 1532180021450866u64, + 1901407354005301u64, + 1421319720492586u64, + 2179081609765456u64, + 2193253156667632u64, + 1080248329608584u64, + 2158422436462066u64, + 759167597017850u64, + 545759071151285u64, + 641600428493698u64, + 943791424499848u64, + 469571542427864u64, + 951117845222467u64, + 1780538594373407u64, + 614611122040309u64, + 1354826131886963u64, + 221898131992340u64, + 1145699723916219u64, + 798735379961769u64, + 1843560518208287u64, + 1424523160161545u64, + 205549016574779u64, + 2239491587362749u64, + 1918363582399888u64, + 1292183072788455u64, + 1783513123192567u64, + 1584027954317205u64, + 1890421443925740u64, + 1718459319874929u64, + 1522091040748809u64, + 399467600667219u64, + 1870973059066576u64, + 287514433150348u64, + 1397845311152885u64, + 1880440629872863u64, + 709302939340341u64, + 1813571361109209u64, + 86598795876860u64, + 1146964554310612u64, + 1590956584862432u64, + 2097004628155559u64, + 656227622102390u64, + 1808500445541891u64, + 958336726523135u64, + 2007604569465975u64, + 313504950390997u64, + 1399686004953620u64, + 1759732788465234u64, + 1562539721055836u64, + 1575722765016293u64, + 793318366641259u64, + 443876859384887u64, + 547308921989704u64, + 636698687503328u64, + 2179175835287340u64, + 498333551718258u64, + 932248760026176u64, + 1612395686304653u64, + 2179774103745626u64, + 1359658123541018u64, + 171488501802442u64, + 1625034951791350u64, + 520196922773633u64, + 1873787546341877u64, + 303457823885368u64, +]; + +pub(crate) const precomp_basepoint_table_w5: [u64; 640] = [ + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1738742601995546u64, + 1146398526822698u64, + 2070867633025821u64, + 562264141797630u64, + 587772402128613u64, + 1801439850948184u64, + 1351079888211148u64, + 450359962737049u64, + 900719925474099u64, + 1801439850948198u64, + 1u64, + 0u64, + 0u64, + 0u64, + 0u64, + 1841354044333475u64, + 16398895984059u64, + 755974180946558u64, + 900171276175154u64, + 1821297809914039u64, + 1661154287933054u64, + 284530020860578u64, + 1390261174866914u64, + 1524110943907984u64, + 1045603498418422u64, + 928651508580478u64, + 1383326941296346u64, + 961937908925785u64, + 80455759693706u64, + 904734540352947u64, + 1507481815385608u64, + 2223447444246085u64, + 1083941587175919u64, + 2059929906842505u64, + 1581435440146976u64, + 782730187692425u64, + 9928394897574u64, + 1539449519985236u64, + 1923587931078510u64, + 552919286076056u64, + 376925408065760u64, + 447320488831784u64, + 1362918338468019u64, + 1470031896696846u64, + 2189796996539902u64, + 1337552949959847u64, + 1762287177775726u64, + 237994495816815u64, + 1277840395970544u64, + 543972849007241u64, + 1224692671618814u64, + 162359533289271u64, + 282240927125249u64, + 586909166382289u64, + 17726488197838u64, + 377014554985659u64, + 1433835303052512u64, + 702061469493692u64, + 1142253108318154u64, + 318297794307551u64, + 954362646308543u64, + 517363881452320u64, + 1868013482130416u64, + 262562472373260u64, + 902232853249919u64, + 2107343057055746u64, + 462368348619024u64, + 1893758677092974u64, + 2177729767846389u64, + 2168532543559143u64, + 443867094639821u64, + 730169342581022u64, + 1564589016879755u64, + 51218195700649u64, + 76684578423745u64, + 560266272480743u64, + 922517457707697u64, + 2066645939860874u64, + 1318277348414638u64, + 1576726809084003u64, + 1817337608563665u64, + 1874240939237666u64, + 754733726333910u64, + 97085310406474u64, + 751148364309235u64, + 1622159695715187u64, + 1444098819684916u64, + 130920805558089u64, + 1260449179085308u64, + 1860021740768461u64, + 110052860348509u64, + 193830891643810u64, + 164148413933881u64, + 180017794795332u64, + 1523506525254651u64, + 465981629225956u64, + 559733514964572u64, + 1279624874416974u64, + 2026642326892306u64, + 1425156829982409u64, + 2160936383793147u64, + 1061870624975247u64, + 2023497043036941u64, + 117942212883190u64, + 490339622800774u64, + 1729931303146295u64, + 422305932971074u64, + 529103152793096u64, + 1211973233775992u64, + 721364955929681u64, + 1497674430438813u64, + 342545521275073u64, + 2102107575279372u64, + 2108462244669966u64, + 1382582406064082u64, + 2206396818383323u64, + 2109093268641147u64, + 10809845110983u64, + 1605176920880099u64, + 744640650753946u64, + 1712758897518129u64, + 373410811281809u64, + 648838265800209u64, + 813058095530999u64, + 513987632620169u64, + 465516160703329u64, + 2136322186126330u64, + 1979645899422932u64, + 1197131006470786u64, + 1467836664863979u64, + 1340751381374628u64, + 1810066212667962u64, + 1009933588225499u64, + 1106129188080873u64, + 1388980405213901u64, + 533719246598044u64, + 1169435803073277u64, + 198920999285821u64, + 487492330629854u64, + 1807093008537778u64, + 1540899012923865u64, + 2075080271659867u64, + 1527990806921523u64, + 1323728742908002u64, + 1568595959608205u64, + 1388032187497212u64, + 2026968840050568u64, + 1396591153295755u64, + 820416950170901u64, + 520060313205582u64, + 2016404325094901u64, + 1584709677868520u64, + 272161374469956u64, + 1567188603996816u64, + 1986160530078221u64, + 553930264324589u64, + 1058426729027503u64, + 8762762886675u64, + 2216098143382988u64, + 1835145266889223u64, + 1712936431558441u64, + 1017009937844974u64, + 585361667812740u64, + 2114711541628181u64, + 2238729632971439u64, + 121257546253072u64, + 847154149018345u64, + 211972965476684u64, + 287499084460129u64, + 2098247259180197u64, + 839070411583329u64, + 339551619574372u64, + 1432951287640743u64, + 526481249498942u64, + 931991661905195u64, + 1884279965674487u64, + 200486405604411u64, + 364173020594788u64, + 518034455936955u64, + 1085564703965501u64, + 16030410467927u64, + 604865933167613u64, + 1695298441093964u64, + 498856548116159u64, + 2193030062787034u64, + 1706339802964179u64, + 1721199073493888u64, + 820740951039755u64, + 1216053436896834u64, + 23954895815139u64, + 1662515208920491u64, + 1705443427511899u64, + 1957928899570365u64, + 1189636258255725u64, + 1795695471103809u64, + 1691191297654118u64, + 282402585374360u64, + 460405330264832u64, + 63765529445733u64, + 469763447404473u64, + 733607089694996u64, + 685410420186959u64, + 1096682630419738u64, + 1162548510542362u64, + 1020949526456676u64, + 1211660396870573u64, + 613126398222696u64, + 1117829165843251u64, + 742432540886650u64, + 1483755088010658u64, + 942392007134474u64, + 1447834130944107u64, + 489368274863410u64, + 23192985544898u64, + 648442406146160u64, + 785438843373876u64, + 249464684645238u64, + 170494608205618u64, + 335112827260550u64, + 1462050123162735u64, + 1084803668439016u64, + 853459233600325u64, + 215777728187495u64, + 1965759433526974u64, + 1349482894446537u64, + 694163317612871u64, + 860536766165036u64, + 1178788094084321u64, + 1652739626626996u64, + 2115723946388185u64, + 1577204379094664u64, + 1083882859023240u64, + 1768759143381635u64, + 1737180992507258u64, + 246054513922239u64, + 577253134087234u64, + 356340280578042u64, + 1638917769925142u64, + 223550348130103u64, + 470592666638765u64, + 22663573966996u64, + 596552461152400u64, + 364143537069499u64, + 3942119457699u64, + 107951982889287u64, + 1843471406713209u64, + 1625773041610986u64, + 1466141092501702u64, + 1043024095021271u64, + 310429964047508u64, + 98559121500372u64, + 152746933782868u64, + 259407205078261u64, + 828123093322585u64, + 1576847274280091u64, + 1170871375757302u64, + 1588856194642775u64, + 984767822341977u64, + 1141497997993760u64, + 809325345150796u64, + 1879837728202511u64, + 201340910657893u64, + 1079157558888483u64, + 1052373448588065u64, + 1732036202501778u64, + 2105292670328445u64, + 679751387312402u64, + 1679682144926229u64, + 1695823455818780u64, + 498852317075849u64, + 1786555067788433u64, + 1670727545779425u64, + 117945875433544u64, + 407939139781844u64, + 854632120023778u64, + 1413383148360437u64, + 286030901733673u64, + 1207361858071196u64, + 461340408181417u64, + 1096919590360164u64, + 1837594897475685u64, + 533755561544165u64, + 1638688042247712u64, + 1431653684793005u64, + 1036458538873559u64, + 390822120341779u64, + 1920929837111618u64, + 543426740024168u64, + 645751357799929u64, + 2245025632994463u64, + 1550778638076452u64, + 223738153459949u64, + 1337209385492033u64, + 1276967236456531u64, + 1463815821063071u64, + 2070620870191473u64, + 1199170709413753u64, + 273230877394166u64, + 1873264887608046u64, + 890877152910775u64, + 983226445635730u64, + 44873798519521u64, + 697147127512130u64, + 961631038239304u64, + 709966160696826u64, + 1706677689540366u64, + 502782733796035u64, + 812545535346033u64, + 1693622521296452u64, + 1955813093002510u64, + 1259937612881362u64, + 1873032503803559u64, + 1140330566016428u64, + 1675726082440190u64, + 60029928909786u64, + 170335608866763u64, + 766444312315022u64, + 2025049511434113u64, + 2200845622430647u64, + 1201269851450408u64, + 590071752404907u64, + 1400995030286946u64, + 2152637413853822u64, + 2108495473841983u64, + 3855406710349u64, + 1726137673168580u64, + 51004317200100u64, + 1749082328586939u64, + 1704088976144558u64, + 1977318954775118u64, + 2062602253162400u64, + 948062503217479u64, + 361953965048030u64, + 1528264887238440u64, + 62582552172290u64, + 2241602163389280u64, + 156385388121765u64, + 2124100319761492u64, + 388928050571382u64, + 1556123596922727u64, + 979310669812384u64, + 113043855206104u64, + 2023223924825469u64, + 643651703263034u64, + 2234446903655540u64, + 1577241261424997u64, + 860253174523845u64, + 1691026473082448u64, + 1091672764933872u64, + 1957463109756365u64, + 530699502660193u64, + 349587141723569u64, + 674661681919563u64, + 1633727303856240u64, + 708909037922144u64, + 2160722508518119u64, + 1302188051602540u64, + 976114603845777u64, + 120004758721939u64, + 1681630708873780u64, + 622274095069244u64, + 1822346309016698u64, + 1100921177951904u64, + 2216952659181677u64, + 1844020550362490u64, + 1976451368365774u64, + 1321101422068822u64, + 1189859436282668u64, + 2008801879735257u64, + 2219413454333565u64, + 424288774231098u64, + 359793146977912u64, + 270293357948703u64, + 587226003677000u64, + 1482071926139945u64, + 1419630774650359u64, + 1104739070570175u64, + 1662129023224130u64, + 1609203612533411u64, + 1250932720691980u64, + 95215711818495u64, + 498746909028150u64, + 158151296991874u64, + 1201379988527734u64, + 561599945143989u64, + 2211577425617888u64, + 2166577612206324u64, + 1057590354233512u64, + 1968123280416769u64, + 1316586165401313u64, + 762728164447634u64, + 2045395244316047u64, + 1531796898725716u64, + 315385971670425u64, + 1109421039396756u64, + 2183635256408562u64, + 1896751252659461u64, + 840236037179080u64, + 796245792277211u64, + 508345890111193u64, + 1275386465287222u64, + 513560822858784u64, + 1784735733120313u64, + 1346467478899695u64, + 601125231208417u64, + 701076661112726u64, + 1841998436455089u64, + 1156768600940434u64, + 1967853462343221u64, + 2178318463061452u64, + 481885520752741u64, + 675262828640945u64, + 1033539418596582u64, + 1743329872635846u64, + 159322641251283u64, + 1573076470127113u64, + 954827619308195u64, + 778834750662635u64, + 619912782122617u64, + 515681498488209u64, + 1675866144246843u64, + 811716020969981u64, + 1125515272217398u64, + 1398917918287342u64, + 1301680949183175u64, + 726474739583734u64, + 587246193475200u64, + 1096581582611864u64, + 1469911826213486u64, + 1990099711206364u64, + 1256496099816508u64, + 2019924615195672u64, + 1251232456707555u64, + 2042971196009755u64, + 214061878479265u64, + 115385726395472u64, + 1677875239524132u64, + 756888883383540u64, + 1153862117756233u64, + 503391530851096u64, + 946070017477513u64, + 1878319040542579u64, + 1101349418586920u64, + 793245696431613u64, + 397920495357645u64, + 2174023872951112u64, + 1517867915189593u64, + 1829855041462995u64, + 1046709983503619u64, + 424081940711857u64, + 2112438073094647u64, + 1504338467349861u64, + 2244574127374532u64, + 2136937537441911u64, + 1741150838990304u64, + 25894628400571u64, + 512213526781178u64, + 1168384260796379u64, + 1424607682379833u64, + 938677789731564u64, + 872882241891896u64, + 1713199397007700u64, + 1410496326218359u64, + 854379752407031u64, + 465141611727634u64, + 315176937037857u64, + 1020115054571233u64, + 1856290111077229u64, + 2028366269898204u64, + 1432980880307543u64, + 469932710425448u64, + 581165267592247u64, + 496399148156603u64, + 2063435226705903u64, + 2116841086237705u64, + 498272567217048u64, + 1829438076967906u64, + 1573925801278491u64, + 460763576329867u64, + 1705264723728225u64, + 999514866082412u64, + 29635061779362u64, + 1884233592281020u64, + 1449755591461338u64, + 42579292783222u64, + 1869504355369200u64, + 495506004805251u64, + 264073104888427u64, + 2088880861028612u64, + 104646456386576u64, + 1258445191399967u64, + 1348736801545799u64, + 2068276361286613u64, + 884897216646374u64, + 922387476801376u64, + 1043886580402805u64, + 1240883498470831u64, + 1601554651937110u64, + 804382935289482u64, + 512379564477239u64, + 1466384519077032u64, + 1280698500238386u64, + 211303836685749u64, + 2081725624793803u64, + 545247644516879u64, + 215313359330384u64, + 286479751145614u64, + 2213650281751636u64, + 2164927945999874u64, + 2072162991540882u64, + 1443769115444779u64, + 1581473274363095u64, + 434633875922699u64, + 340456055781599u64, + 373043091080189u64, + 839476566531776u64, + 1856706858509978u64, + 931616224909153u64, + 1888181317414065u64, + 213654322650262u64, + 1161078103416244u64, + 1822042328851513u64, + 915817709028812u64, + 1828297056698188u64, + 1212017130909403u64, + 60258343247333u64, + 342085800008230u64, + 930240559508270u64, + 1549884999174952u64, + 809895264249462u64, + 184726257947682u64, + 1157065433504828u64, + 1209999630381477u64, + 999920399374391u64, + 1714770150788163u64, + 2026130985413228u64, + 506776632883140u64, + 1349042668246528u64, + 1937232292976967u64, + 942302637530730u64, + 160211904766226u64, + 1042724500438571u64, + 212454865139142u64, + 244104425172642u64, + 1376990622387496u64, + 76126752421227u64, + 1027540886376422u64, + 1912210655133026u64, + 13410411589575u64, + 1475856708587773u64, + 615563352691682u64, + 1446629324872644u64, + 1683670301784014u64, + 1049873327197127u64, + 1826401704084838u64, + 2032577048760775u64, + 1922203607878853u64, + 836708788764806u64, + 2193084654695012u64, + 1342923183256659u64, + 849356986294271u64, + 1228863973965618u64, + 94886161081867u64, + 1423288430204892u64, + 2016167528707016u64, + 1633187660972877u64, + 1550621242301752u64, + 340630244512994u64, + 2103577710806901u64, + 221625016538931u64, + 421544147350960u64, + 580428704555156u64, + 1479831381265617u64, + 518057926544698u64, + 955027348790630u64, + 1326749172561598u64, + 1118304625755967u64, + 1994005916095176u64, + 1799757332780663u64, + 751343129396941u64, + 1468672898746144u64, + 1451689964451386u64, + 755070293921171u64, + 904857405877052u64, + 1276087530766984u64, + 403986562858511u64, + 1530661255035337u64, + 1644972908910502u64, + 1370170080438957u64, + 139839536695744u64, + 909930462436512u64, + 1899999215356933u64, + 635992381064566u64, + 788740975837654u64, + 224241231493695u64, + 1267090030199302u64, + 998908061660139u64, + 1784537499699278u64, + 859195370018706u64, + 1953966091439379u64, + 2189271820076010u64, + 2039067059943978u64, + 1526694380855202u64, + 2040321513194941u64, + 329922071218689u64, + 1953032256401326u64, + 989631424403521u64, + 328825014934242u64, + 9407151397696u64, + 63551373671268u64, + 1624728632895792u64, + 1608324920739262u64, + 1178239350351945u64, + 1198077399579702u64, + 277620088676229u64, + 1775359437312528u64, + 1653558177737477u64, + 1652066043408850u64, + 1063359889686622u64, + 1975063804860653u64, +]; diff --git a/ed25519/src/impl_hacl.rs b/ed25519/src/impl_hacl.rs new file mode 100644 index 000000000..bb61db011 --- /dev/null +++ b/ed25519/src/impl_hacl.rs @@ -0,0 +1,54 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Error { + SigningError, + InvalidSignature, +} + +/// The hacl implementation requires that +/// - the private key is a 32 byte buffer +/// - the signature is a 64 byte buffer, +/// - the payload buffer is not shorter than payload_len. +/// +/// We enforce the first two using types, and the latter by using `payload.len()` and `payload_len`. +/// This has the caveat that `payload_len` must be <= u32::MAX, so we return an error if that is +/// not the case. +pub fn sign(payload: &[u8], private_key: &[u8; 32]) -> Result<[u8; 64], Error> { + let mut signature = [0u8; 64]; + crate::hacl::ed25519::sign( + &mut signature, + private_key, + payload.len().try_into().map_err(|_| Error::SigningError)?, + payload, + ); + + Ok(signature) +} + +/// The hacl implementation requires that +/// - the public key is a 32 byte buffer +/// - the signature is a 64 byte buffer, +/// - the payload buffer is not shorter than payload_len. +/// +/// We enforce the first two using types, and the latter by using `payload.len()` and `payload_len`. +/// This has the caveat that `payload_len` must be <= u32::MAX, so we return an error if that is +/// not the case. +/// +pub fn verify(payload: &[u8], public_key: &[u8; 32], signature: &[u8; 64]) -> Result<(), Error> { + if crate::hacl::ed25519::verify( + public_key, + payload.len().try_into().map_err(|_| Error::SigningError)?, + payload, + signature, + ) { + Ok(()) + } else { + Err(Error::InvalidSignature) + } +} + +/// Compute the public point for the given secret key `sk`. +/// The hacl implementation requires that these are both 32 byte buffers, which we enforce through +/// types. +pub fn secret_to_public(pk: &mut [u8; 32], sk: &[u8; 32]) { + crate::hacl::ed25519::secret_to_public(pk, sk) +} diff --git a/ed25519/src/lib.rs b/ed25519/src/lib.rs new file mode 100644 index 000000000..e8896ce66 --- /dev/null +++ b/ed25519/src/lib.rs @@ -0,0 +1,13 @@ +#[cfg(feature = "hacl")] +pub mod hacl { + //! This module contains generated hacl code. + + pub mod ed25519; + pub mod ed25519_precomptable; +} + +#[cfg(feature = "hacl")] +mod impl_hacl; + +#[cfg(feature = "portable_hacl")] +pub use impl_hacl::*; diff --git a/flake.lock b/flake.lock index 4f2422f00..49c4b787e 100644 --- a/flake.lock +++ b/flake.lock @@ -12,11 +12,11 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1718119153, - "narHash": "sha256-/7Lv10doYagB+h9LzoT8hG9ns5ejEsAXBnii2kNDSoQ=", + "lastModified": 1731500951, + "narHash": "sha256-bITTJFxjrq6XfBNUnqFn15f7V6+ypILm2BTu2cxd+iI=", "owner": "aeneasverif", "repo": "charon", - "rev": "0d3ba218b611b31cd9b800c237f15f7ffc787845", + "rev": "454078ebdb4a607e2b21dc115e1ca99b516e436f", "type": "github" }, "original": { @@ -26,18 +26,12 @@ } }, "crane": { - "inputs": { - "nixpkgs": [ - "charon", - "nixpkgs" - ] - }, "locked": { - "lastModified": 1701622587, - "narHash": "sha256-o3XhxCCyrUHZ0tlta2W7/MuXzy+n0+BUt3rKFK3DIK4=", + "lastModified": 1727316705, + "narHash": "sha256-/mumx8AQ5xFuCJqxCIOFCHTVlxHkMT21idpbgbm/TIE=", "owner": "ipetkov", "repo": "crane", - "rev": "c09d2cbe84cc2adfe1943cb2a0b55a71c835ca9a", + "rev": "5b03654ce046b5167e7b0bccbd8244cb56c16f0e", "type": "github" }, "original": { @@ -47,17 +41,12 @@ } }, "crane_2": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, "locked": { - "lastModified": 1718078026, - "narHash": "sha256-LbQabH6h86ZzTvDnaZHmMwedRZNB2jYtUQzmoqWQoJ8=", + "lastModified": 1731098351, + "narHash": "sha256-HQkYvKvaLQqNa10KEFGgWHfMAbWBfFp+4cAgkut+NNE=", "owner": "ipetkov", "repo": "crane", - "rev": "a3f0c63eed74a516298932b9b1627dd80b9c3892", + "rev": "ef80ead953c1b28316cc3f8613904edc2eb90c28", "type": "github" }, "original": { @@ -68,23 +57,17 @@ }, "crane_3": { "inputs": { - "flake-compat": "flake-compat_2", - "flake-utils": [ - "hax", - "flake-utils" - ], "nixpkgs": [ "hax", "nixpkgs" - ], - "rust-overlay": "rust-overlay_2" + ] }, "locked": { - "lastModified": 1693787605, - "narHash": "sha256-rwq5U8dy+a9JFny/73L0SJu1GfWwATMPMTp7D+mjHy8=", + "lastModified": 1717386774, + "narHash": "sha256-YYMGHDo4f+tu7k2q6hWNiI5C8gAN5eksb3g3EbKFf4k=", "owner": "ipetkov", "repo": "crane", - "rev": "8b4f7a4dab2120cf41e7957a28a853f45016bd9d", + "rev": "ad21f86e47a2751faa99aecd0d494be70411d5e9", "type": "github" }, "original": { @@ -108,11 +91,11 @@ ] }, "locked": { - "lastModified": 1718124394, - "narHash": "sha256-1sYQb6Oy/BtMBiWJ7X+nOf8+ZVWBmmm+29NtrIj3w2s=", + "lastModified": 1731504425, + "narHash": "sha256-v51ze2+yq/rkyQrjBoGQEhzpy8fxtkgCfL9WuQJgHXg=", "owner": "aeneasverif", "repo": "eurydice", - "rev": "b2b62fffab78f91de07c20a7fa7385242fd54a0d", + "rev": "7d686376ec943225ff89942978c6c3028bac689c", "type": "github" }, "original": { @@ -123,11 +106,11 @@ }, "flake-compat": { "locked": { - "lastModified": 1688025799, - "narHash": "sha256-ktpB4dRtnksm9F5WawoIkEneh1nrEvuxb5lJFt1iOyw=", + "lastModified": 1717312683, + "narHash": "sha256-FrlieJH50AuvagamEvWMIE6D2OAnERuDboFDYAED/dE=", "owner": "nix-community", "repo": "flake-compat", - "rev": "8bf105319d44f6b9f0d764efa4fdef9f1cc9ba1c", + "rev": "38fd3954cf65ce6faf3d0d45cd26059e059f07ea", "type": "github" }, "original": { @@ -136,32 +119,16 @@ "type": "github" } }, - "flake-compat_2": { - "flake": false, - "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "type": "github" }, "original": { @@ -175,11 +142,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "type": "github" }, "original": { @@ -227,11 +194,11 @@ "systems": "systems_5" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -245,11 +212,11 @@ "systems": "systems_6" }, "locked": { - "lastModified": 1692799911, - "narHash": "sha256-3eihraek4qL744EvQXsK1Ha6C3CR7nnT8X2qWap4RNk=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "f9e7cf818399d17d347f847525c5a5a8032e4e44", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -264,11 +231,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1717456679, - "narHash": "sha256-GjDR+YhmIBHJ/1WotSwcHYmXP1VvkZS5I2YpPJlzWDc=", + "lastModified": 1731120038, + "narHash": "sha256-KfKaTvgjxGe+Z5KU+9rW/1Wr0SH4QOWIAm0UYL1FcBI=", "owner": "FStarLang", "repo": "fstar", - "rev": "6d124af2bda315ae20f9fe974ffc668f8bd5791d", + "rev": "668e45909b2a485e0b5152d016ddec93f470d24d", "type": "github" }, "original": { @@ -283,11 +250,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1717456679, - "narHash": "sha256-GjDR+YhmIBHJ/1WotSwcHYmXP1VvkZS5I2YpPJlzWDc=", + "lastModified": 1731120038, + "narHash": "sha256-KfKaTvgjxGe+Z5KU+9rW/1Wr0SH4QOWIAm0UYL1FcBI=", "owner": "fstarlang", "repo": "fstar", - "rev": "6d124af2bda315ae20f9fe974ffc668f8bd5791d", + "rev": "668e45909b2a485e0b5152d016ddec93f470d24d", "type": "github" }, "original": { @@ -325,11 +292,11 @@ "hacl-star": { "flake": false, "locked": { - "lastModified": 1699634660, - "narHash": "sha256-/mAi8wdlO1HHYKVj8pN/y5FUM/AwVPNazYFSy9pDlpY=", + "lastModified": 1716379562, + "narHash": "sha256-42dF8kPEiveSPgHoicxZG/CCu3IhwJhtfvVNfrLczu8=", "owner": "hacl-star", "repo": "hacl-star", - "rev": "7f42aba60b37bc011d19472284bfcd3b95c1538e", + "rev": "9149b0c26b06a8e06a0920a07c33ddd18d94c519", "type": "github" }, "original": { @@ -345,14 +312,15 @@ "fstar": "fstar_3", "hacl-star": "hacl-star", "nixpkgs": "nixpkgs_3", - "rust-overlay": "rust-overlay_3" + "rust-by-examples": "rust-by-examples", + "rust-overlay": "rust-overlay_2" }, "locked": { - "lastModified": 1717675342, - "narHash": "sha256-ZeBd/7OFaw5QXdHhMbspSrc2QiEYKKxtWHIZ6mHsCBY=", + "lastModified": 1731578084, + "narHash": "sha256-m223G1Hz0+AP1nM2jBWZT6ISOV15q7bvumAKjbzluIQ=", "owner": "hacspec", "repo": "hax", - "rev": "46bb5c19fb6f6397e15d9a4ff86c556482f81802", + "rev": "14c6f430db9a0f469ba525085216d204b1ed741d", "type": "github" }, "original": { @@ -378,11 +346,11 @@ ] }, "locked": { - "lastModified": 1718042424, - "narHash": "sha256-6rpa26YdxXiV+PftX11ODFu1yiUAWHHRNgtOhf9mFoY=", + "lastModified": 1730490029, + "narHash": "sha256-PDOd0tW7DDZfXlozrcTZ33mgWAukR/UH4Ilt5ew8oPw=", "owner": "FStarLang", "repo": "karamel", - "rev": "22425a93c68d9e3794909f98854aaffdc0560510", + "rev": "5f7e9be838ba8ec0ed3323132e6beb6276f6acf2", "type": "github" }, "original": { @@ -423,25 +391,26 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1694343207, - "narHash": "sha256-jWi7OwFxU5Owi4k2JmiL1sa/OuBCQtpaAesuj5LXC8w=", - "owner": "NixOS", + "lastModified": 1717402443, + "narHash": "sha256-KlFiT8xFAVy29iYJU9nBwvkC7WTfUC/jak5jNFz5wHM=", + "owner": "nixos", "repo": "nixpkgs", - "rev": "78058d810644f5ed276804ce7ea9e82d92bee293", + "rev": "c149b8818b982d612f519c7e73449d355206a89a", "type": "github" }, "original": { - "id": "nixpkgs", - "type": "indirect" + "owner": "nixos", + "repo": "nixpkgs", + "type": "github" } }, "nixpkgs_4": { "locked": { - "lastModified": 1717974879, - "narHash": "sha256-GTO3C88+5DX171F/gVS3Qga/hOs/eRMxPFpiHq2t+D8=", + "lastModified": 1731319897, + "narHash": "sha256-PbABj4tnbWFMfBp6OcUK5iGy1QY+/Z96ZcLpooIbuEI=", "owner": "nixos", "repo": "nixpkgs", - "rev": "c7b821ba2e1e635ba5a76d299af62821cbcb09f3", + "rev": "dc460ec76cbff0e66e269457d7b728432263166c", "type": "github" }, "original": { @@ -469,50 +438,35 @@ "nixpkgs": "nixpkgs_4" } }, - "rust-overlay": { - "inputs": { - "flake-utils": [ - "charon", - "flake-utils" - ], - "nixpkgs": [ - "charon", - "nixpkgs" - ] - }, + "rust-by-examples": { + "flake": false, "locked": { - "lastModified": 1701656211, - "narHash": "sha256-lfFXsLWH4hVbEKR6K+UcDiKxeS6Lz4FkC1DZ9LHqf9Y=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "47a276e820ae4ae1b8d98a503bf09d2ceb52dfd8", + "lastModified": 1729958822, + "narHash": "sha256-/X1dI2MPYSfOdqOOxpNFCykoJtVetQCOo7WfBa7XAyU=", + "owner": "rust-lang", + "repo": "rust-by-example", + "rev": "4e3881e0cb1b690158acca3c16e271fdadf736da", "type": "github" }, "original": { - "owner": "oxalica", - "repo": "rust-overlay", + "owner": "rust-lang", + "repo": "rust-by-example", "type": "github" } }, - "rust-overlay_2": { + "rust-overlay": { "inputs": { - "flake-utils": [ - "hax", - "crane", - "flake-utils" - ], "nixpkgs": [ - "hax", - "crane", + "charon", "nixpkgs" ] }, "locked": { - "lastModified": 1693707092, - "narHash": "sha256-HR1EnynBSPqbt+04/yxxqsG1E3n6uXrOl7SPco/UnYo=", + "lastModified": 1729736953, + "narHash": "sha256-Rb6JUop7NRklg0uzcre+A+Ebrn/ZiQPkm4QdKg6/3pw=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "98ccb73e6eefc481da6039ee57ad8818d1ca8d56", + "rev": "29b1275740d9283467b8117499ec8cbb35250584", "type": "github" }, "original": { @@ -521,23 +475,19 @@ "type": "github" } }, - "rust-overlay_3": { + "rust-overlay_2": { "inputs": { - "flake-utils": [ - "hax", - "flake-utils" - ], "nixpkgs": [ "hax", "nixpkgs" ] }, "locked": { - "lastModified": 1716862669, - "narHash": "sha256-7oTPM9lcdwiI1cpRC313B+lHawocgpY5F07N+Rbm5Uk=", + "lastModified": 1729736953, + "narHash": "sha256-Rb6JUop7NRklg0uzcre+A+Ebrn/ZiQPkm4QdKg6/3pw=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "47b2d15658b37716393b2463a019000dbd6ce4bc", + "rev": "29b1275740d9283467b8117499ec8cbb35250584", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index bca103803..5efc50bff 100644 --- a/flake.nix +++ b/flake.nix @@ -60,44 +60,85 @@ FSTAR_REV = inputs.fstar.rev; }; - craneLib = inputs.crane.mkLib pkgs; - src = ./.; - cargoArtifacts = craneLib.buildDepsOnly { inherit src; }; - ml-kem = craneLib.buildPackage (tools-environment // { - name = "ml-kem"; - inherit src cargoArtifacts; + ml-kem = pkgs.callPackage + ({ pkgs + , lib + , clang-tools + , cmake + , mold-wrapped + , ninja + , python3 + , runCommand + , crane + , hax + , googletest + , benchmark + , json + , tools-environment + , cargoLock ? ./Cargo.lock + , checkHax ? true + , runBenchmarks ? true + }: + let + craneLib = crane.mkLib pkgs; + src = runCommand "libcrux-src" { } '' + cp -r ${./.} $out + chmod u+w $out + rm -f $out/Cargo.lock + cp ${cargoLock} $out/Cargo.lock + ''; + cargoArtifacts = craneLib.buildDepsOnly { inherit src; }; + in + craneLib.buildPackage (tools-environment // { + name = "ml-kem"; + inherit src cargoArtifacts; - nativeBuildInputs = [ - pkgs.clang-tools - pkgs.cmake - pkgs.mold-wrapped - pkgs.ninja - pkgs.python3 - inputs.hax.packages.${system}.default - ]; - buildPhase = '' - cd libcrux-ml-kem - python hax.py extract - bash c.sh - cd c - cmake \ - -DFETCHCONTENT_SOURCE_DIR_GOOGLETEST=${googletest} \ - -DFETCHCONTENT_SOURCE_DIR_BENCHMARK=${benchmark} \ - -DFETCHCONTENT_SOURCE_DIR_JSON=${json} \ - -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" \ - -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" \ - -G "Ninja Multi-Config" -B build - cmake --build build --config Release - ''; - checkPhase = '' - build/Release/ml_kem_test - build/Release/ml_kem_bench - ''; - installPhase = '' - cd ./.. - cp -r . $out - ''; - }); + nativeBuildInputs = [ + clang-tools + cmake + mold-wrapped + ninja + python3 + ] ++ lib.optional checkHax [ + hax + ]; + buildPhase = '' + cd libcrux-ml-kem + ${lib.optionalString checkHax '' + python hax.py extract + ''} + bash c.sh + cd c + ${lib.optionalString runBenchmarks "LIBCRUX_BENCHMARKS=1"} \ + cmake \ + -DFETCHCONTENT_SOURCE_DIR_GOOGLETEST=${googletest} \ + -DFETCHCONTENT_SOURCE_DIR_BENCHMARK=${benchmark} \ + -DFETCHCONTENT_SOURCE_DIR_JSON=${json} \ + -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" \ + -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" \ + -G "Ninja Multi-Config" -B build + cmake --build build --config Release + rm -rf build/_deps + ''; + checkPhase = '' + build/Release/ml_kem_test + '' + lib.optionalString runBenchmarks '' + build/Release/ml_kem_bench + ''; + installPhase = '' + cd ./.. + cp -r . $out + ''; + }) + ) + { + inherit + googletest benchmark json + tools-environment; + crane = inputs.crane; + hax = + inputs.hax.packages.${system}.default; + }; in rec { packages = { diff --git a/fstar-helpers/Makefile.base b/fstar-helpers/Makefile.base index b4e0d962b..54c2552b1 100644 --- a/fstar-helpers/Makefile.base +++ b/fstar-helpers/Makefile.base @@ -1,5 +1,5 @@ # Base Makefile for F* in libcrux. -# This inherits from Makefile.generic, and adds the `specs` folder from HACL and the `libcrux-ml-kem/proofs/fstar/spec` folder. +# This inherits from Makefile.generic, and adds the `specs` folder from HACL. VERIFY_SLOW_MODULES ?= no ifeq (${VERIFY_SLOW_MODULES},no) @@ -10,5 +10,5 @@ EXTRA_HELPMESSAGE += printf "Libcrux specifics:\n"; EXTRA_HELPMESSAGE += target SLOW_MODULES 'a list of modules to verify fully only when `VERIFY_SLOW_MODULES` is set to `yes`. When `VERIFY_SLOW_MODULES`, those modules are admitted.'; EXTRA_HELPMESSAGE += target VERIFY_SLOW_MODULES '`yes` or `no`, defaults to `no`'; -FSTAR_INCLUDE_DIRS_EXTRA += $(HACL_HOME)/specs $(shell git rev-parse --show-toplevel)/libcrux-ml-kem/proofs/fstar/spec $(shell git rev-parse --show-toplevel)/fstar-helpers/fstar-bitvec +FSTAR_INCLUDE_DIRS_EXTRA += $(HACL_HOME)/specs include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.generic diff --git a/fstar-helpers/README.md b/fstar-helpers/README.md deleted file mode 100644 index 122ed5b03..000000000 --- a/fstar-helpers/README.md +++ /dev/null @@ -1,5 +0,0 @@ -This folder provides F* helpers: - - - `Makefile.generic` is the generic hax Makefile, available here: https://gist.github.com/W95Psp/4c304132a1f85c5af4e4959dd6b356c3. `Makefile.generic` is not supposed to be edited. - - `Makefile.base` is the base file that adds a couple of include folders that are useful generally in the scope of libcrux verification with F*. - - `fstar-bitvec` F* modules related to bitvectors. diff --git a/hacl-rs/Cargo.toml b/hacl-rs/Cargo.toml new file mode 100644 index 000000000..f1cd580d6 --- /dev/null +++ b/hacl-rs/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "libcrux-hacl-rs" +description = "Formally verified Rust code extracted from HACL* - helper library" + +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libcrux-macros = { path = "../macros", version = "=0.0.2-beta.2" } + +[lib] diff --git a/hacl-rs/src/bignum.rs b/hacl-rs/src/bignum.rs new file mode 100644 index 000000000..0f885088f --- /dev/null +++ b/hacl-rs/src/bignum.rs @@ -0,0 +1,12 @@ +pub mod base; +pub mod bignum256; +pub mod bignum256_32; +pub mod bignum32; +pub mod bignum4096; +pub mod bignum4096_32; +pub mod bignum64; +pub mod bignum_base; + +pub mod test { + // pub mod bignum4096; +} diff --git a/hacl-rs/src/bignum/base.rs b/hacl-rs/src/bignum/base.rs new file mode 100644 index 000000000..1d575e5c3 --- /dev/null +++ b/hacl-rs/src/bignum/base.rs @@ -0,0 +1,2150 @@ +#![allow(clippy::too_many_arguments)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_macros as krml; + +use crate::fstar; +use crate::lowstar; +use crate::util as lib; + +pub(crate) fn bn_karatsuba_mul_uint32( + aLen: u32, + a: &[u32], + b: &[u32], + tmp: &mut [u32], + res: &mut [u32], +) { + if aLen < 32u32 || aLen.wrapping_rem(2u32) == 1u32 { + super::bignum_base::bn_mul_u32(aLen, a, aLen, b, res) + } else { + let len2: u32 = aLen.wrapping_div(2u32); + let a0: (&[u32], &[u32]) = a.split_at(0usize); + let a1: (&[u32], &[u32]) = a0.1.split_at(len2 as usize); + let b0: (&[u32], &[u32]) = b.split_at(0usize); + let b1: (&[u32], &[u32]) = b0.1.split_at(len2 as usize); + let t0: (&mut [u32], &mut [u32]) = tmp.split_at_mut(0usize); + let t1: (&mut [u32], &mut [u32]) = t0.1.split_at_mut(len2 as usize); + let tmp·: (&mut [u32], &mut [u32]) = t1.1.split_at_mut(aLen as usize - len2 as usize); + let c0: u32 = super::bignum_base::bn_sub_eq_len_u32(len2, a1.0, a1.1, tmp·.1); + let c1: u32 = super::bignum_base::bn_sub_eq_len_u32(len2, a1.1, a1.0, t1.0); + for i in 0u32..len2 { + let x: u32 = 0u32.wrapping_sub(c0) & t1.0[i as usize] + | !0u32.wrapping_sub(c0) & tmp·.1[i as usize]; + let os: (&mut [u32], &mut [u32]) = t1.0.split_at_mut(0usize); + os.1[i as usize] = x + } + lowstar::ignore::ignore::(c1); + let c00: u32 = c0; + let c01: u32 = super::bignum_base::bn_sub_eq_len_u32(len2, b1.0, b1.1, tmp·.1); + let c10: u32 = super::bignum_base::bn_sub_eq_len_u32(len2, b1.1, b1.0, tmp·.0); + for i in 0u32..len2 { + let x: u32 = 0u32.wrapping_sub(c01) & tmp·.0[i as usize] + | !0u32.wrapping_sub(c01) & tmp·.1[i as usize]; + let os: (&mut [u32], &mut [u32]) = tmp·.0.split_at_mut(0usize); + os.1[i as usize] = x + } + lowstar::ignore::ignore::(c10); + let c11: u32 = c01; + let t23: (&mut [u32], &mut [u32]) = tmp·.1.split_at_mut(0usize); + let tmp1: (&mut [u32], &mut [u32]) = t23 + .1 + .split_at_mut(aLen.wrapping_add(aLen) as usize - aLen as usize); + super::base::bn_karatsuba_mul_uint32(len2, t1.0, tmp·.0, tmp1.1, tmp1.0); + let r01: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + let r23: (&mut [u32], &mut [u32]) = r01.1.split_at_mut(aLen as usize); + super::base::bn_karatsuba_mul_uint32(len2, a1.0, b1.0, tmp1.1, r23.0); + super::base::bn_karatsuba_mul_uint32(len2, a1.1, b1.1, tmp1.1, r23.1); + lowstar::ignore::ignore::<&[u32]>(res); + lowstar::ignore::ignore::<&[u32]>(tmp); + let r011: (&[u32], &[u32]) = res.split_at(0usize); + let r231: (&[u32], &[u32]) = r011.1.split_at(aLen as usize); + let t01: (&mut [u32], &mut [u32]) = tmp.split_at_mut(0usize); + let t231: (&mut [u32], &mut [u32]) = t01.1.split_at_mut(aLen as usize); + let t45: (&mut [u32], &mut [u32]) = t231 + .1 + .split_at_mut(2u32.wrapping_mul(aLen) as usize - aLen as usize); + let t67: (&mut [u32], &mut [u32]) = t45 + .1 + .split_at_mut(3u32.wrapping_mul(aLen) as usize - 2u32.wrapping_mul(aLen) as usize); + let c2: u32 = super::bignum_base::bn_add_eq_len_u32(aLen, r231.0, r231.1, t231.0); + let c_sign: u32 = c00 ^ c11; + let c3: u32 = super::bignum_base::bn_sub_eq_len_u32(aLen, t231.0, t45.0, t67.1); + let c31: u32 = c2.wrapping_sub(c3); + let c4: u32 = super::bignum_base::bn_add_eq_len_u32(aLen, t231.0, t45.0, t67.0); + let c41: u32 = c2.wrapping_add(c4); + let mask: u32 = 0u32.wrapping_sub(c_sign); + for i in 0u32..aLen { + let x: u32 = mask & t67.0[i as usize] | !mask & t67.1[i as usize]; + let os: (&mut [u32], &mut [u32]) = t67.0.split_at_mut(0usize); + os.1[i as usize] = x + } + let c5: u32 = mask & c41 | !mask & c31; + let aLen2: u32 = aLen.wrapping_div(2u32); + lowstar::ignore::ignore::<&[u32]>(res); + let r: (&mut [u32], &mut [u32]) = res.split_at_mut(aLen2 as usize); + let mut a_copy: Box<[u32]> = vec![0u32; aLen as usize].into_boxed_slice(); + let mut b_copy: Box<[u32]> = vec![0u32; aLen as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..aLen as usize]).copy_from_slice(&r.1[0usize..aLen as usize]); + ((&mut b_copy)[0usize..aLen as usize]).copy_from_slice(&t67.0[0usize..aLen as usize]); + let r1: u32 = super::bignum_base::bn_add_eq_len_u32(aLen, &a_copy, &b_copy, r.1); + let r10: u32 = r1; + let c: u32 = r10; + let c6: u32 = c; + let c7: u32 = c5.wrapping_add(c6); + lowstar::ignore::ignore::<&[u32]>(res); + let r0: (&mut [u32], &mut [u32]) = res.split_at_mut(aLen.wrapping_add(aLen2) as usize); + let c010: u32 = + lib::inttypes_intrinsics::add_carry_u32(0u32, r0.1[0usize], c7, &mut r0.1[0usize..]); + let r11: u32 = if 1u32 + < aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + { + let res1: (&mut [u32], &mut [u32]) = r0.1.split_at_mut(1usize); + let mut c8: [u32; 1] = [c010; 1usize]; + for i in 0u32..aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + .wrapping_div(4u32) + { + let t11: u32 = res1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c8)[0usize], t11, 0u32, res_i.1); + let t110: u32 = res1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 1usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c8)[0usize], t110, 0u32, res_i0.1); + let t111: u32 = res1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 2usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c8)[0usize], t111, 0u32, res_i1.1); + let t112: u32 = res1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 3usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c8)[0usize], t112, 0u32, res_i2.1) + } + for i in aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + .wrapping_div(4u32) + .wrapping_mul(4u32) + ..aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + { + let t11: u32 = res1.1[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res1.1.split_at_mut(i as usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c8)[0usize], t11, 0u32, res_i.1) + } + let c110: u32 = (&c8)[0usize]; + c110 + } else { + c010 + }; + let c8: u32 = r11; + let c9: u32 = c8; + let c12: u32 = c9; + lowstar::ignore::ignore::(c12) + } +} + +pub(crate) fn bn_karatsuba_mul_uint64( + aLen: u32, + a: &[u64], + b: &[u64], + tmp: &mut [u64], + res: &mut [u64], +) { + if aLen < 32u32 || aLen.wrapping_rem(2u32) == 1u32 { + super::bignum_base::bn_mul_u64(aLen, a, aLen, b, res) + } else { + let len2: u32 = aLen.wrapping_div(2u32); + let a0: (&[u64], &[u64]) = a.split_at(0usize); + let a1: (&[u64], &[u64]) = a0.1.split_at(len2 as usize); + let b0: (&[u64], &[u64]) = b.split_at(0usize); + let b1: (&[u64], &[u64]) = b0.1.split_at(len2 as usize); + let t0: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let t1: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(len2 as usize); + let tmp·: (&mut [u64], &mut [u64]) = t1.1.split_at_mut(aLen as usize - len2 as usize); + let c0: u64 = super::bignum_base::bn_sub_eq_len_u64(len2, a1.0, a1.1, tmp·.1); + let c1: u64 = super::bignum_base::bn_sub_eq_len_u64(len2, a1.1, a1.0, t1.0); + for i in 0u32..len2 { + let x: u64 = 0u64.wrapping_sub(c0) & t1.0[i as usize] + | !0u64.wrapping_sub(c0) & tmp·.1[i as usize]; + let os: (&mut [u64], &mut [u64]) = t1.0.split_at_mut(0usize); + os.1[i as usize] = x + } + lowstar::ignore::ignore::(c1); + let c00: u64 = c0; + let c01: u64 = super::bignum_base::bn_sub_eq_len_u64(len2, b1.0, b1.1, tmp·.1); + let c10: u64 = super::bignum_base::bn_sub_eq_len_u64(len2, b1.1, b1.0, tmp·.0); + for i in 0u32..len2 { + let x: u64 = 0u64.wrapping_sub(c01) & tmp·.0[i as usize] + | !0u64.wrapping_sub(c01) & tmp·.1[i as usize]; + let os: (&mut [u64], &mut [u64]) = tmp·.0.split_at_mut(0usize); + os.1[i as usize] = x + } + lowstar::ignore::ignore::(c10); + let c11: u64 = c01; + let t23: (&mut [u64], &mut [u64]) = tmp·.1.split_at_mut(0usize); + let tmp1: (&mut [u64], &mut [u64]) = t23 + .1 + .split_at_mut(aLen.wrapping_add(aLen) as usize - aLen as usize); + super::base::bn_karatsuba_mul_uint64(len2, t1.0, tmp·.0, tmp1.1, tmp1.0); + let r01: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + let r23: (&mut [u64], &mut [u64]) = r01.1.split_at_mut(aLen as usize); + super::base::bn_karatsuba_mul_uint64(len2, a1.0, b1.0, tmp1.1, r23.0); + super::base::bn_karatsuba_mul_uint64(len2, a1.1, b1.1, tmp1.1, r23.1); + lowstar::ignore::ignore::<&[u64]>(res); + lowstar::ignore::ignore::<&[u64]>(tmp); + let r011: (&[u64], &[u64]) = res.split_at(0usize); + let r231: (&[u64], &[u64]) = r011.1.split_at(aLen as usize); + let t01: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let t231: (&mut [u64], &mut [u64]) = t01.1.split_at_mut(aLen as usize); + let t45: (&mut [u64], &mut [u64]) = t231 + .1 + .split_at_mut(2u32.wrapping_mul(aLen) as usize - aLen as usize); + let t67: (&mut [u64], &mut [u64]) = t45 + .1 + .split_at_mut(3u32.wrapping_mul(aLen) as usize - 2u32.wrapping_mul(aLen) as usize); + let c2: u64 = super::bignum_base::bn_add_eq_len_u64(aLen, r231.0, r231.1, t231.0); + let c_sign: u64 = c00 ^ c11; + let c3: u64 = super::bignum_base::bn_sub_eq_len_u64(aLen, t231.0, t45.0, t67.1); + let c31: u64 = c2.wrapping_sub(c3); + let c4: u64 = super::bignum_base::bn_add_eq_len_u64(aLen, t231.0, t45.0, t67.0); + let c41: u64 = c2.wrapping_add(c4); + let mask: u64 = 0u64.wrapping_sub(c_sign); + for i in 0u32..aLen { + let x: u64 = mask & t67.0[i as usize] | !mask & t67.1[i as usize]; + let os: (&mut [u64], &mut [u64]) = t67.0.split_at_mut(0usize); + os.1[i as usize] = x + } + let c5: u64 = mask & c41 | !mask & c31; + let aLen2: u32 = aLen.wrapping_div(2u32); + lowstar::ignore::ignore::<&[u64]>(res); + let r: (&mut [u64], &mut [u64]) = res.split_at_mut(aLen2 as usize); + let mut a_copy: Box<[u64]> = vec![0u64; aLen as usize].into_boxed_slice(); + let mut b_copy: Box<[u64]> = vec![0u64; aLen as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..aLen as usize]).copy_from_slice(&r.1[0usize..aLen as usize]); + ((&mut b_copy)[0usize..aLen as usize]).copy_from_slice(&t67.0[0usize..aLen as usize]); + let r1: u64 = super::bignum_base::bn_add_eq_len_u64(aLen, &a_copy, &b_copy, r.1); + let r10: u64 = r1; + let c: u64 = r10; + let c6: u64 = c; + let c7: u64 = c5.wrapping_add(c6); + lowstar::ignore::ignore::<&[u64]>(res); + let r0: (&mut [u64], &mut [u64]) = res.split_at_mut(aLen.wrapping_add(aLen2) as usize); + let c010: u64 = + lib::inttypes_intrinsics::add_carry_u64(0u64, r0.1[0usize], c7, &mut r0.1[0usize..]); + let r11: u64 = if 1u32 + < aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + { + let res1: (&mut [u64], &mut [u64]) = r0.1.split_at_mut(1usize); + let mut c8: [u64; 1] = [c010; 1usize]; + for i in 0u32..aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + .wrapping_div(4u32) + { + let t11: u64 = res1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c8)[0usize], t11, 0u64, res_i.1); + let t110: u64 = res1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 1usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c8)[0usize], t110, 0u64, res_i0.1); + let t111: u64 = res1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 2usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c8)[0usize], t111, 0u64, res_i1.1); + let t112: u64 = res1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 3usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c8)[0usize], t112, 0u64, res_i2.1) + } + for i in aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + .wrapping_div(4u32) + .wrapping_mul(4u32) + ..aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + { + let t11: u64 = res1.1[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res1.1.split_at_mut(i as usize); + (&mut c8)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c8)[0usize], t11, 0u64, res_i.1) + } + let c110: u64 = (&c8)[0usize]; + c110 + } else { + c010 + }; + let c8: u64 = r11; + let c9: u64 = c8; + let c12: u64 = c9; + lowstar::ignore::ignore::(c12) + } +} + +pub(crate) fn bn_karatsuba_sqr_uint32(aLen: u32, a: &[u32], tmp: &mut [u32], res: &mut [u32]) { + if aLen < 32u32 || aLen.wrapping_rem(2u32) == 1u32 { + super::bignum_base::bn_sqr_u32(aLen, a, res) + } else { + let len2: u32 = aLen.wrapping_div(2u32); + let a0: (&[u32], &[u32]) = a.split_at(0usize); + let a1: (&[u32], &[u32]) = a0.1.split_at(len2 as usize); + let t0: (&mut [u32], &mut [u32]) = tmp.split_at_mut(0usize); + let tmp·: (&mut [u32], &mut [u32]) = t0.1.split_at_mut(aLen as usize); + let c0: u32 = super::bignum_base::bn_sub_eq_len_u32(len2, a1.0, a1.1, tmp·.1); + let c1: u32 = super::bignum_base::bn_sub_eq_len_u32(len2, a1.1, a1.0, tmp·.0); + for i in 0u32..len2 { + let x: u32 = 0u32.wrapping_sub(c0) & tmp·.0[i as usize] + | !0u32.wrapping_sub(c0) & tmp·.1[i as usize]; + let os: (&mut [u32], &mut [u32]) = tmp·.0.split_at_mut(0usize); + os.1[i as usize] = x + } + lowstar::ignore::ignore::(c1); + let c00: u32 = c0; + lowstar::ignore::ignore::(c00); + let t23: (&mut [u32], &mut [u32]) = tmp·.1.split_at_mut(0usize); + let tmp1: (&mut [u32], &mut [u32]) = t23 + .1 + .split_at_mut(aLen.wrapping_add(aLen) as usize - aLen as usize); + super::base::bn_karatsuba_sqr_uint32(len2, tmp·.0, tmp1.1, tmp1.0); + let r01: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + let r23: (&mut [u32], &mut [u32]) = r01.1.split_at_mut(aLen as usize); + super::base::bn_karatsuba_sqr_uint32(len2, a1.0, tmp1.1, r23.0); + super::base::bn_karatsuba_sqr_uint32(len2, a1.1, tmp1.1, r23.1); + lowstar::ignore::ignore::<&[u32]>(res); + lowstar::ignore::ignore::<&[u32]>(tmp); + let r011: (&[u32], &[u32]) = res.split_at(0usize); + let r231: (&[u32], &[u32]) = r011.1.split_at(aLen as usize); + let t01: (&mut [u32], &mut [u32]) = tmp.split_at_mut(0usize); + let t231: (&mut [u32], &mut [u32]) = t01.1.split_at_mut(aLen as usize); + let t45: (&mut [u32], &mut [u32]) = t231 + .1 + .split_at_mut(2u32.wrapping_mul(aLen) as usize - aLen as usize); + let c2: u32 = super::bignum_base::bn_add_eq_len_u32(aLen, r231.0, r231.1, t231.0); + let c3: u32 = super::bignum_base::bn_sub_eq_len_u32(aLen, t231.0, t45.0, t45.1); + let c5: u32 = c2.wrapping_sub(c3); + let aLen2: u32 = aLen.wrapping_div(2u32); + lowstar::ignore::ignore::<&[u32]>(res); + let r: (&mut [u32], &mut [u32]) = res.split_at_mut(aLen2 as usize); + let mut a_copy: Box<[u32]> = vec![0u32; aLen as usize].into_boxed_slice(); + let mut b_copy: Box<[u32]> = vec![0u32; aLen as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..aLen as usize]).copy_from_slice(&r.1[0usize..aLen as usize]); + ((&mut b_copy)[0usize..aLen as usize]).copy_from_slice(&t45.1[0usize..aLen as usize]); + let r1: u32 = super::bignum_base::bn_add_eq_len_u32(aLen, &a_copy, &b_copy, r.1); + let r10: u32 = r1; + let c: u32 = r10; + let c6: u32 = c; + let c7: u32 = c5.wrapping_add(c6); + lowstar::ignore::ignore::<&[u32]>(res); + let r0: (&mut [u32], &mut [u32]) = res.split_at_mut(aLen.wrapping_add(aLen2) as usize); + let c01: u32 = + lib::inttypes_intrinsics::add_carry_u32(0u32, r0.1[0usize], c7, &mut r0.1[0usize..]); + let r11: u32 = if 1u32 + < aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + { + let res1: (&mut [u32], &mut [u32]) = r0.1.split_at_mut(1usize); + let mut c4: [u32; 1] = [c01; 1usize]; + for i in 0u32..aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + .wrapping_div(4u32) + { + let t1: u32 = res1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c4)[0usize], t1, 0u32, res_i.1); + let t10: u32 = res1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 1usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c4)[0usize], t10, 0u32, res_i0.1); + let t11: u32 = res1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 2usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c4)[0usize], t11, 0u32, res_i1.1); + let t12: u32 = res1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 3usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c4)[0usize], t12, 0u32, res_i2.1) + } + for i in aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + .wrapping_div(4u32) + .wrapping_mul(4u32) + ..aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + { + let t1: u32 = res1.1[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res1.1.split_at_mut(i as usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c4)[0usize], t1, 0u32, res_i.1) + } + let c10: u32 = (&c4)[0usize]; + c10 + } else { + c01 + }; + let c8: u32 = r11; + let c4: u32 = c8; + let c9: u32 = c4; + lowstar::ignore::ignore::(c9) + } +} + +pub(crate) fn bn_karatsuba_sqr_uint64(aLen: u32, a: &[u64], tmp: &mut [u64], res: &mut [u64]) { + if aLen < 32u32 || aLen.wrapping_rem(2u32) == 1u32 { + super::bignum_base::bn_sqr_u64(aLen, a, res) + } else { + let len2: u32 = aLen.wrapping_div(2u32); + let a0: (&[u64], &[u64]) = a.split_at(0usize); + let a1: (&[u64], &[u64]) = a0.1.split_at(len2 as usize); + let t0: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let tmp·: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(aLen as usize); + let c0: u64 = super::bignum_base::bn_sub_eq_len_u64(len2, a1.0, a1.1, tmp·.1); + let c1: u64 = super::bignum_base::bn_sub_eq_len_u64(len2, a1.1, a1.0, tmp·.0); + for i in 0u32..len2 { + let x: u64 = 0u64.wrapping_sub(c0) & tmp·.0[i as usize] + | !0u64.wrapping_sub(c0) & tmp·.1[i as usize]; + let os: (&mut [u64], &mut [u64]) = tmp·.0.split_at_mut(0usize); + os.1[i as usize] = x + } + lowstar::ignore::ignore::(c1); + let c00: u64 = c0; + lowstar::ignore::ignore::(c00); + let t23: (&mut [u64], &mut [u64]) = tmp·.1.split_at_mut(0usize); + let tmp1: (&mut [u64], &mut [u64]) = t23 + .1 + .split_at_mut(aLen.wrapping_add(aLen) as usize - aLen as usize); + super::base::bn_karatsuba_sqr_uint64(len2, tmp·.0, tmp1.1, tmp1.0); + let r01: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + let r23: (&mut [u64], &mut [u64]) = r01.1.split_at_mut(aLen as usize); + super::base::bn_karatsuba_sqr_uint64(len2, a1.0, tmp1.1, r23.0); + super::base::bn_karatsuba_sqr_uint64(len2, a1.1, tmp1.1, r23.1); + lowstar::ignore::ignore::<&[u64]>(res); + lowstar::ignore::ignore::<&[u64]>(tmp); + let r011: (&[u64], &[u64]) = res.split_at(0usize); + let r231: (&[u64], &[u64]) = r011.1.split_at(aLen as usize); + let t01: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + let t231: (&mut [u64], &mut [u64]) = t01.1.split_at_mut(aLen as usize); + let t45: (&mut [u64], &mut [u64]) = t231 + .1 + .split_at_mut(2u32.wrapping_mul(aLen) as usize - aLen as usize); + let c2: u64 = super::bignum_base::bn_add_eq_len_u64(aLen, r231.0, r231.1, t231.0); + let c3: u64 = super::bignum_base::bn_sub_eq_len_u64(aLen, t231.0, t45.0, t45.1); + let c5: u64 = c2.wrapping_sub(c3); + let aLen2: u32 = aLen.wrapping_div(2u32); + lowstar::ignore::ignore::<&[u64]>(res); + let r: (&mut [u64], &mut [u64]) = res.split_at_mut(aLen2 as usize); + let mut a_copy: Box<[u64]> = vec![0u64; aLen as usize].into_boxed_slice(); + let mut b_copy: Box<[u64]> = vec![0u64; aLen as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..aLen as usize]).copy_from_slice(&r.1[0usize..aLen as usize]); + ((&mut b_copy)[0usize..aLen as usize]).copy_from_slice(&t45.1[0usize..aLen as usize]); + let r1: u64 = super::bignum_base::bn_add_eq_len_u64(aLen, &a_copy, &b_copy, r.1); + let r10: u64 = r1; + let c: u64 = r10; + let c6: u64 = c; + let c7: u64 = c5.wrapping_add(c6); + lowstar::ignore::ignore::<&[u64]>(res); + let r0: (&mut [u64], &mut [u64]) = res.split_at_mut(aLen.wrapping_add(aLen2) as usize); + let c01: u64 = + lib::inttypes_intrinsics::add_carry_u64(0u64, r0.1[0usize], c7, &mut r0.1[0usize..]); + let r11: u64 = if 1u32 + < aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + { + let res1: (&mut [u64], &mut [u64]) = r0.1.split_at_mut(1usize); + let mut c4: [u64; 1] = [c01; 1usize]; + for i in 0u32..aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + .wrapping_div(4u32) + { + let t1: u64 = res1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c4)[0usize], t1, 0u64, res_i.1); + let t10: u64 = res1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 1usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c4)[0usize], t10, 0u64, res_i0.1); + let t11: u64 = res1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 2usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c4)[0usize], t11, 0u64, res_i1.1); + let t12: u64 = res1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize + 3usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c4)[0usize], t12, 0u64, res_i2.1) + } + for i in aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + .wrapping_div(4u32) + .wrapping_mul(4u32) + ..aLen + .wrapping_add(aLen) + .wrapping_sub(aLen.wrapping_add(aLen2)) + .wrapping_sub(1u32) + { + let t1: u64 = res1.1[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res1.1.split_at_mut(i as usize); + (&mut c4)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c4)[0usize], t1, 0u64, res_i.1) + } + let c10: u64 = (&c4)[0usize]; + c10 + } else { + c01 + }; + let c8: u64 = r11; + let c4: u64 = c8; + let c9: u64 = c4; + lowstar::ignore::ignore::(c9) + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_add_mod_n_u32(len1: u32, n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) { + let mut c: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len1.wrapping_div(4u32) { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t12, t22, res_i2.1) + } + for i in len1.wrapping_div(4u32).wrapping_mul(4u32)..len1 { + let t1: u32 = a[i as usize]; + let t2: u32 = b[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t1, t2, res_i.1) + } + let c0: u32 = (&c)[0usize]; + let mut tmp: Box<[u32]> = vec![0u32; len1 as usize].into_boxed_slice(); + let mut c1: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len1.wrapping_div(4u32) { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t12, t22, res_i2.1) + } + for i in len1.wrapping_div(4u32).wrapping_mul(4u32)..len1 { + let t1: u32 = res[i as usize]; + let t2: u32 = n[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(i as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t1, t2, res_i.1) + } + let c10: u32 = (&c1)[0usize]; + let c2: u32 = c0.wrapping_sub(c10); + for i in 0u32..len1 { + let x: u32 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_add_mod_n_u64(len1: u32, n: &[u64], a: &[u64], b: &[u64], res: &mut [u64]) { + let mut c: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len1.wrapping_div(4u32) { + let t1: u64 = a[4u32.wrapping_mul(i) as usize]; + let t2: u64 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t12, t22, res_i2.1) + } + for i in len1.wrapping_div(4u32).wrapping_mul(4u32)..len1 { + let t1: u64 = a[i as usize]; + let t2: u64 = b[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t1, t2, res_i.1) + } + let c0: u64 = (&c)[0usize]; + let mut tmp: Box<[u64]> = vec![0u64; len1 as usize].into_boxed_slice(); + let mut c1: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len1.wrapping_div(4u32) { + let t1: u64 = res[4u32.wrapping_mul(i) as usize]; + let t2: u64 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t12, t22, res_i2.1) + } + for i in len1.wrapping_div(4u32).wrapping_mul(4u32)..len1 { + let t1: u64 = res[i as usize]; + let t2: u64 = n[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(i as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t1, t2, res_i.1) + } + let c10: u64 = (&c1)[0usize]; + let c2: u64 = c0.wrapping_sub(c10); + for i in 0u32..len1 { + let x: u64 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_sub_mod_n_u32(len1: u32, n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) { + let mut c: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len1.wrapping_div(4u32) { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, t22, res_i2.1) + } + for i in len1.wrapping_div(4u32).wrapping_mul(4u32)..len1 { + let t1: u32 = a[i as usize]; + let t2: u32 = b[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, t2, res_i.1) + } + let c0: u32 = (&c)[0usize]; + let mut tmp: Box<[u32]> = vec![0u32; len1 as usize].into_boxed_slice(); + let mut c1: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len1.wrapping_div(4u32) { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t12, t22, res_i2.1) + } + for i in len1.wrapping_div(4u32).wrapping_mul(4u32)..len1 { + let t1: u32 = res[i as usize]; + let t2: u32 = n[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(i as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t1, t2, res_i.1) + } + let c10: u32 = (&c1)[0usize]; + lowstar::ignore::ignore::(c10); + let c2: u32 = 0u32.wrapping_sub(c0); + for i in 0u32..len1 { + let x: u32 = c2 & (&tmp)[i as usize] | !c2 & res[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_sub_mod_n_u64(len1: u32, n: &[u64], a: &[u64], b: &[u64], res: &mut [u64]) { + let mut c: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len1.wrapping_div(4u32) { + let t1: u64 = a[4u32.wrapping_mul(i) as usize]; + let t2: u64 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, t22, res_i2.1) + } + for i in len1.wrapping_div(4u32).wrapping_mul(4u32)..len1 { + let t1: u64 = a[i as usize]; + let t2: u64 = b[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, t2, res_i.1) + } + let c0: u64 = (&c)[0usize]; + let mut tmp: Box<[u64]> = vec![0u64; len1 as usize].into_boxed_slice(); + let mut c1: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len1.wrapping_div(4u32) { + let t1: u64 = res[4u32.wrapping_mul(i) as usize]; + let t2: u64 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t12, t22, res_i2.1) + } + for i in len1.wrapping_div(4u32).wrapping_mul(4u32)..len1 { + let t1: u64 = res[i as usize]; + let t2: u64 = n[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(i as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t1, t2, res_i.1) + } + let c10: u64 = (&c1)[0usize]; + lowstar::ignore::ignore::(c10); + let c2: u64 = 0u64.wrapping_sub(c0); + for i in 0u32..len1 { + let x: u64 = c2 & (&tmp)[i as usize] | !c2 & res[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn mod_inv_uint32(n0: u32) -> u32 { + let alpha: u32 = 2147483648u32; + let beta: u32 = n0; + let mut ub: [u32; 1] = [0u32; 1usize]; + let mut vb: [u32; 1] = [0u32; 1usize]; + (&mut ub)[0usize] = 1u32; + (&mut vb)[0usize] = 0u32; + krml::unroll_for!(32, "_i", 0u32, 1u32, { + let us: u32 = (&ub)[0usize]; + let vs: u32 = (&vb)[0usize]; + let u_is_odd: u32 = 0u32.wrapping_sub(us & 1u32); + let beta_if_u_is_odd: u32 = beta & u_is_odd; + (&mut ub)[0usize] = (us ^ beta_if_u_is_odd) + .wrapping_shr(1u32) + .wrapping_add(us & beta_if_u_is_odd); + let alpha_if_u_is_odd: u32 = alpha & u_is_odd; + (&mut vb)[0usize] = vs.wrapping_shr(1u32).wrapping_add(alpha_if_u_is_odd) + }); + (&vb)[0usize] +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn mod_inv_uint64(n0: u64) -> u64 { + let alpha: u64 = 9223372036854775808u64; + let beta: u64 = n0; + let mut ub: [u64; 1] = [0u64; 1usize]; + let mut vb: [u64; 1] = [0u64; 1usize]; + (&mut ub)[0usize] = 1u64; + (&mut vb)[0usize] = 0u64; + for _i in 0u32..64u32 { + let us: u64 = (&ub)[0usize]; + let vs: u64 = (&vb)[0usize]; + let u_is_odd: u64 = 0u64.wrapping_sub(us & 1u64); + let beta_if_u_is_odd: u64 = beta & u_is_odd; + (&mut ub)[0usize] = (us ^ beta_if_u_is_odd) + .wrapping_shr(1u32) + .wrapping_add(us & beta_if_u_is_odd); + let alpha_if_u_is_odd: u64 = alpha & u_is_odd; + (&mut vb)[0usize] = vs.wrapping_shr(1u32).wrapping_add(alpha_if_u_is_odd) + } + (&vb)[0usize] +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_check_modulus_u32(len: u32, n: &[u32]) -> u32 { + let mut one: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut one)[0usize..len as usize]) + .copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u32 = (&acc)[0usize]; + m0 & m1 +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_precomp_r2_mod_n_u32(len: u32, nBits: u32, n: &[u32], res: &mut [u32]) { + (res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()); + let i: u32 = nBits.wrapping_div(32u32); + let j: u32 = nBits.wrapping_rem(32u32); + res[i as usize] |= 1u32.wrapping_shl(j); + for _i in 0u32..64u32.wrapping_mul(len).wrapping_sub(nBits) { + let mut a_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let mut b_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..len as usize]).copy_from_slice(&res[0usize..len as usize]); + ((&mut b_copy)[0usize..len as usize]).copy_from_slice(&res[0usize..len as usize]); + super::base::bn_add_mod_n_u32(len, n, &a_copy, &b_copy, res) + } +} + +fn bn_mont_reduction_u32(len: u32, n: &[u32], nInv: u32, c: &mut [u32], res: &mut [u32]) { + let mut c0: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let qj: u32 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize); + let mut c1: [u32; 1] = [0u32; 1usize]; + for i0 in 0u32..len.wrapping_div(4u32) { + let a_i: u32 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u32 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u32 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u32 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, qj, (&c1)[0usize], res_i2.1) + } + for i0 in len.wrapping_div(4u32).wrapping_mul(4u32)..len { + let a_i: u32 = n[i0 as usize]; + let res_i: (&mut [u32], &mut [u32]) = res_j.1.split_at_mut(i0 as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, qj, (&c1)[0usize], res_i.1) + } + let r: u32 = (&c1)[0usize]; + let c10: u32 = r; + let res_j0: u32 = c[len.wrapping_add(i) as usize]; + let resb: (&mut [u32], &mut [u32]) = c.split_at_mut(len.wrapping_add(i) as usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c0)[0usize], c10, res_j0, resb.1) + } + (res[0usize..len.wrapping_add(len).wrapping_sub(len) as usize]).copy_from_slice( + &(&c[len as usize..])[0usize..len.wrapping_add(len).wrapping_sub(len) as usize], + ); + let c00: u32 = (&c0)[0usize]; + let mut tmp: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let mut c1: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len.wrapping_div(4u32) { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t12, t22, res_i2.1) + } + for i in len.wrapping_div(4u32).wrapping_mul(4u32)..len { + let t1: u32 = res[i as usize]; + let t2: u32 = n[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(i as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t1, t2, res_i.1) + } + let c10: u32 = (&c1)[0usize]; + let c2: u32 = c00.wrapping_sub(c10); + for i in 0u32..len { + let x: u32 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_to_mont_u32(len: u32, n: &[u32], nInv: u32, r2: &[u32], a: &[u32], aM: &mut [u32]) { + let mut c: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_mul_uint32(len, a, r2, &mut tmp, &mut c); + super::base::bn_mont_reduction_u32(len, n, nInv, &mut c, aM) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_from_mont_u32(len: u32, n: &[u32], nInv_u64: u32, aM: &[u32], a: &mut [u32]) { + let mut tmp: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut tmp)[0usize..len as usize]).copy_from_slice(&aM[0usize..len as usize]); + super::base::bn_mont_reduction_u32(len, n, nInv_u64, &mut tmp, a) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_mont_mul_u32( + len: u32, + n: &[u32], + nInv_u64: u32, + aM: &[u32], + bM: &[u32], + resM: &mut [u32], +) { + let mut c: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_mul_uint32(len, aM, bM, &mut tmp, &mut c); + super::base::bn_mont_reduction_u32(len, n, nInv_u64, &mut c, resM) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_mont_sqr_u32(len: u32, n: &[u32], nInv_u64: u32, aM: &[u32], resM: &mut [u32]) { + let mut c: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_sqr_uint32(len, aM, &mut tmp, &mut c); + super::base::bn_mont_reduction_u32(len, n, nInv_u64, &mut c, resM) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_check_modulus_u64(len: u32, n: &[u64]) -> u64 { + let mut one: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut one)[0usize..len as usize]) + .copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u64 = (&acc)[0usize]; + m0 & m1 +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_precomp_r2_mod_n_u64(len: u32, nBits: u32, n: &[u64], res: &mut [u64]) { + (res[0usize..len as usize]).copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()); + let i: u32 = nBits.wrapping_div(64u32); + let j: u32 = nBits.wrapping_rem(64u32); + res[i as usize] |= 1u64.wrapping_shl(j); + for _i in 0u32..128u32.wrapping_mul(len).wrapping_sub(nBits) { + let mut a_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let mut b_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..len as usize]).copy_from_slice(&res[0usize..len as usize]); + ((&mut b_copy)[0usize..len as usize]).copy_from_slice(&res[0usize..len as usize]); + super::base::bn_add_mod_n_u64(len, n, &a_copy, &b_copy, res) + } +} + +fn bn_mont_reduction_u64(len: u32, n: &[u64], nInv: u64, c: &mut [u64], res: &mut [u64]) { + let mut c0: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let qj: u64 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize); + let mut c1: [u64; 1] = [0u64; 1usize]; + for i0 in 0u32..len.wrapping_div(4u32) { + let a_i: u64 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u64 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u64 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u64 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, qj, (&c1)[0usize], res_i2.1) + } + for i0 in len.wrapping_div(4u32).wrapping_mul(4u32)..len { + let a_i: u64 = n[i0 as usize]; + let res_i: (&mut [u64], &mut [u64]) = res_j.1.split_at_mut(i0 as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, qj, (&c1)[0usize], res_i.1) + } + let r: u64 = (&c1)[0usize]; + let c10: u64 = r; + let res_j0: u64 = c[len.wrapping_add(i) as usize]; + let resb: (&mut [u64], &mut [u64]) = c.split_at_mut(len.wrapping_add(i) as usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c0)[0usize], c10, res_j0, resb.1) + } + (res[0usize..len.wrapping_add(len).wrapping_sub(len) as usize]).copy_from_slice( + &(&c[len as usize..])[0usize..len.wrapping_add(len).wrapping_sub(len) as usize], + ); + let c00: u64 = (&c0)[0usize]; + let mut tmp: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let mut c1: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len.wrapping_div(4u32) { + let t1: u64 = res[4u32.wrapping_mul(i) as usize]; + let t2: u64 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t12, t22, res_i2.1) + } + for i in len.wrapping_div(4u32).wrapping_mul(4u32)..len { + let t1: u64 = res[i as usize]; + let t2: u64 = n[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(i as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t1, t2, res_i.1) + } + let c10: u64 = (&c1)[0usize]; + let c2: u64 = c00.wrapping_sub(c10); + for i in 0u32..len { + let x: u64 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_to_mont_u64(len: u32, n: &[u64], nInv: u64, r2: &[u64], a: &[u64], aM: &mut [u64]) { + let mut c: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u64]> = vec![0u64; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_mul_uint64(len, a, r2, &mut tmp, &mut c); + super::base::bn_mont_reduction_u64(len, n, nInv, &mut c, aM) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_from_mont_u64(len: u32, n: &[u64], nInv_u64: u64, aM: &[u64], a: &mut [u64]) { + let mut tmp: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut tmp)[0usize..len as usize]).copy_from_slice(&aM[0usize..len as usize]); + super::base::bn_mont_reduction_u64(len, n, nInv_u64, &mut tmp, a) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_mont_mul_u64( + len: u32, + n: &[u64], + nInv_u64: u64, + aM: &[u64], + bM: &[u64], + resM: &mut [u64], +) { + let mut c: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u64]> = vec![0u64; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_mul_uint64(len, aM, bM, &mut tmp, &mut c); + super::base::bn_mont_reduction_u64(len, n, nInv_u64, &mut c, resM) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_mont_sqr_u64(len: u32, n: &[u64], nInv_u64: u64, aM: &[u64], resM: &mut [u64]) { + let mut c: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u64]> = vec![0u64; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_sqr_uint64(len, aM, &mut tmp, &mut c); + super::base::bn_mont_reduction_u64(len, n, nInv_u64, &mut c, resM) +} + +pub(crate) fn bn_almost_mont_reduction_u32( + len: u32, + n: &[u32], + nInv: u32, + c: &mut [u32], + res: &mut [u32], +) { + let mut c0: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let qj: u32 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize); + let mut c1: [u32; 1] = [0u32; 1usize]; + for i0 in 0u32..len.wrapping_div(4u32) { + let a_i: u32 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u32 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u32 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u32 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, qj, (&c1)[0usize], res_i2.1) + } + for i0 in len.wrapping_div(4u32).wrapping_mul(4u32)..len { + let a_i: u32 = n[i0 as usize]; + let res_i: (&mut [u32], &mut [u32]) = res_j.1.split_at_mut(i0 as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, qj, (&c1)[0usize], res_i.1) + } + let r: u32 = (&c1)[0usize]; + let c10: u32 = r; + let res_j0: u32 = c[len.wrapping_add(i) as usize]; + let resb: (&mut [u32], &mut [u32]) = c.split_at_mut(len.wrapping_add(i) as usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c0)[0usize], c10, res_j0, resb.1) + } + (res[0usize..len.wrapping_add(len).wrapping_sub(len) as usize]).copy_from_slice( + &(&c[len as usize..])[0usize..len.wrapping_add(len).wrapping_sub(len) as usize], + ); + let c00: u32 = (&c0)[0usize]; + let mut tmp: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let c1: u32 = super::bignum_base::bn_sub_eq_len_u32(len, res, n, &mut tmp); + lowstar::ignore::ignore::(c1); + let m: u32 = 0u32.wrapping_sub(c00); + for i in 0u32..len { + let x: u32 = m & (&tmp)[i as usize] | !m & res[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +fn bn_almost_mont_mul_u32( + len: u32, + n: &[u32], + nInv_u64: u32, + aM: &[u32], + bM: &[u32], + resM: &mut [u32], +) { + let mut c: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_mul_uint32(len, aM, bM, &mut tmp, &mut c); + super::base::bn_almost_mont_reduction_u32(len, n, nInv_u64, &mut c, resM) +} + +fn bn_almost_mont_sqr_u32(len: u32, n: &[u32], nInv_u64: u32, aM: &[u32], resM: &mut [u32]) { + let mut c: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_sqr_uint32(len, aM, &mut tmp, &mut c); + super::base::bn_almost_mont_reduction_u32(len, n, nInv_u64, &mut c, resM) +} + +pub(crate) fn bn_almost_mont_reduction_u64( + len: u32, + n: &[u64], + nInv: u64, + c: &mut [u64], + res: &mut [u64], +) { + let mut c0: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let qj: u64 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize); + let mut c1: [u64; 1] = [0u64; 1usize]; + for i0 in 0u32..len.wrapping_div(4u32) { + let a_i: u64 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u64 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u64 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u64 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, qj, (&c1)[0usize], res_i2.1) + } + for i0 in len.wrapping_div(4u32).wrapping_mul(4u32)..len { + let a_i: u64 = n[i0 as usize]; + let res_i: (&mut [u64], &mut [u64]) = res_j.1.split_at_mut(i0 as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, qj, (&c1)[0usize], res_i.1) + } + let r: u64 = (&c1)[0usize]; + let c10: u64 = r; + let res_j0: u64 = c[len.wrapping_add(i) as usize]; + let resb: (&mut [u64], &mut [u64]) = c.split_at_mut(len.wrapping_add(i) as usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c0)[0usize], c10, res_j0, resb.1) + } + (res[0usize..len.wrapping_add(len).wrapping_sub(len) as usize]).copy_from_slice( + &(&c[len as usize..])[0usize..len.wrapping_add(len).wrapping_sub(len) as usize], + ); + let c00: u64 = (&c0)[0usize]; + let mut tmp: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let c1: u64 = super::bignum_base::bn_sub_eq_len_u64(len, res, n, &mut tmp); + lowstar::ignore::ignore::(c1); + let m: u64 = 0u64.wrapping_sub(c00); + for i in 0u32..len { + let x: u64 = m & (&tmp)[i as usize] | !m & res[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +fn bn_almost_mont_mul_u64( + len: u32, + n: &[u64], + nInv_u64: u64, + aM: &[u64], + bM: &[u64], + resM: &mut [u64], +) { + let mut c: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u64]> = vec![0u64; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_mul_uint64(len, aM, bM, &mut tmp, &mut c); + super::base::bn_almost_mont_reduction_u64(len, n, nInv_u64, &mut c, resM) +} + +fn bn_almost_mont_sqr_u64(len: u32, n: &[u64], nInv_u64: u64, aM: &[u64], resM: &mut [u64]) { + let mut c: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u64]> = vec![0u64; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_sqr_uint64(len, aM, &mut tmp, &mut c); + super::base::bn_almost_mont_reduction_u64(len, n, nInv_u64, &mut c, resM) +} + +pub(crate) fn bn_check_mod_exp_u32(len: u32, n: &[u32], a: &[u32], bBits: u32, b: &[u32]) -> u32 { + let mut one: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut one)[0usize..len as usize]) + .copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u32 = (&acc)[0usize]; + let m00: u32 = m0 & m1; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let m10: u32 = if bBits < 32u32.wrapping_mul(bLen) { + let mut b2: Box<[u32]> = vec![0u32; bLen as usize].into_boxed_slice(); + let i: u32 = bBits.wrapping_div(32u32); + let j: u32 = bBits.wrapping_rem(32u32); + (&mut b2)[i as usize] = (&b2)[i as usize] | 1u32.wrapping_shl(j); + let mut acc0: [u32; 1] = [0u32; 1usize]; + for i0 in 0u32..bLen { + let beq: u32 = fstar::uint32::eq_mask(b[i0 as usize], (&b2)[i0 as usize]); + let blt: u32 = !fstar::uint32::gte_mask(b[i0 as usize], (&b2)[i0 as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let res: u32 = (&acc0)[0usize]; + res + } else { + 0xFFFFFFFFu32 + }; + let mut acc0: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let m2: u32 = (&acc0)[0usize]; + let m: u32 = m10 & m2; + m00 & m +} + +pub(crate) fn bn_mod_exp_vartime_precomp_u32( + len: u32, + n: &[u32], + mu: u32, + r2: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + if bBits < 200u32 { + let mut aM: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + super::base::bn_to_mont_u32(len, n, mu, r2, a, &mut aM); + let mut resM: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let mut ctx: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut ctx)[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + ((&mut ctx)[len as usize..len as usize + len as usize]) + .copy_from_slice(&r2[0usize..len as usize]); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(len as usize); + super::base::bn_from_mont_u32(len, ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = i.wrapping_div(32u32); + let j: u32 = i.wrapping_rem(32u32); + let tmp: u32 = b[i1 as usize]; + let bit: u32 = tmp.wrapping_shr(j) & 1u32; + if bit != 0u32 { + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]) + .copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u32(len, ctx_n0.1, mu, &aM_copy, &aM, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u32(len, ctx_n0.1, mu, &aM_copy, &mut aM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::base::bn_from_mont_u32(len, n, mu, &resM, res) + } else { + let mut aM: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + super::base::bn_to_mont_u32(len, n, mu, r2, a, &mut aM); + let mut resM: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let mut ctx: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut ctx)[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + ((&mut ctx)[len as usize..len as usize + len as usize]) + .copy_from_slice(&r2[0usize..len as usize]); + let mut table: Box<[u32]> = vec![0u32; 16u32.wrapping_mul(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let t0: (&mut [u32], &mut [u32]) = table.split_at_mut(0usize); + let t1: (&mut [u32], &mut [u32]) = t0.1.split_at_mut(len as usize); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(len as usize); + super::base::bn_from_mont_u32(len, ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (t1.1[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + lowstar::ignore::ignore::<&[u32]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u32], &[u32]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(len) as usize); + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&t11.1[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u32(len, ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize + + len as usize]) + .copy_from_slice(&(&tmp)[0usize..len as usize]); + let t2: (&[u32], &[u32]) = + table.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize); + let mut aM_copy0: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy0)[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u32(len, ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(len) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(len) as usize + + len as usize]) + .copy_from_slice(&(&tmp)[0usize..len as usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, i, 4u32); + let bits_l32: u32 = bits_c; + let a_bits_l: (&[u32], &[u32]) = table.split_at(bits_l32.wrapping_mul(len) as usize); + ((&mut resM)[0usize..len as usize]).copy_from_slice(&a_bits_l.1[0usize..len as usize]) + } else { + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r20: (&[u32], &[u32]) = ctx_n0.1.split_at(len as usize); + super::base::bn_from_mont_u32(len, ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut tmp0: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]) + .copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u32(len, ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u32]>(&table); + let bits_l32: u32 = bits_l; + let a_bits_l: (&[u32], &[u32]) = table.split_at(bits_l32.wrapping_mul(len) as usize); + ((&mut tmp0)[0usize..len as usize]).copy_from_slice(&a_bits_l.1[0usize..len as usize]); + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u32(len, ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::base::bn_from_mont_u32(len, n, mu, &resM, res) + } +} + +pub(crate) fn bn_mod_exp_consttime_precomp_u32( + len: u32, + n: &[u32], + mu: u32, + r2: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + if bBits < 200u32 { + let mut aM: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + super::base::bn_to_mont_u32(len, n, mu, r2, a, &mut aM); + let mut resM: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let mut ctx: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut ctx)[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + ((&mut ctx)[len as usize..len as usize + len as usize]) + .copy_from_slice(&r2[0usize..len as usize]); + let mut sw: [u32; 1] = [0u32; 1usize]; + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(len as usize); + super::base::bn_from_mont_u32(len, ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_div(32u32); + let j: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_rem(32u32); + let tmp: u32 = b[i1 as usize]; + let bit: u32 = tmp.wrapping_shr(j) & 1u32; + let sw1: u32 = bit ^ (&sw)[0usize]; + for i0 in 0u32..len { + let dummy: u32 = + 0u32.wrapping_sub(sw1) & ((&resM)[i0 as usize] ^ (&aM)[i0 as usize]); + (&mut resM)[i0 as usize] = (&resM)[i0 as usize] ^ dummy; + (&mut aM)[i0 as usize] = (&aM)[i0 as usize] ^ dummy + } + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u32(len, ctx_n0.1, mu, &aM_copy, &resM, &mut aM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + let mut aM_copy0: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy0)[0usize..len as usize]).copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u32(len, ctx_n1.1, mu, &aM_copy0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (&mut sw)[0usize] = bit + } + let sw0: u32 = (&sw)[0usize]; + for i in 0u32..len { + let dummy: u32 = 0u32.wrapping_sub(sw0) & ((&resM)[i as usize] ^ (&aM)[i as usize]); + (&mut resM)[i as usize] = (&resM)[i as usize] ^ dummy; + (&mut aM)[i as usize] = (&aM)[i as usize] ^ dummy + } + super::base::bn_from_mont_u32(len, n, mu, &resM, res) + } else { + let mut aM: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + super::base::bn_to_mont_u32(len, n, mu, r2, a, &mut aM); + let mut resM: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let mut ctx: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut ctx)[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + ((&mut ctx)[len as usize..len as usize + len as usize]) + .copy_from_slice(&r2[0usize..len as usize]); + let mut table: Box<[u32]> = vec![0u32; 16u32.wrapping_mul(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let t0: (&mut [u32], &mut [u32]) = table.split_at_mut(0usize); + let t1: (&mut [u32], &mut [u32]) = t0.1.split_at_mut(len as usize); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(len as usize); + super::base::bn_from_mont_u32(len, ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (t1.1[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + lowstar::ignore::ignore::<&[u32]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u32], &[u32]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(len) as usize); + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&t11.1[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u32(len, ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize + + len as usize]) + .copy_from_slice(&(&tmp)[0usize..len as usize]); + let t2: (&[u32], &[u32]) = + table.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize); + let mut aM_copy0: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy0)[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u32(len, ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(len) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(len) as usize + + len as usize]) + .copy_from_slice(&(&tmp)[0usize..len as usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, i, 4u32); + ((&mut resM)[0usize..len as usize]).copy_from_slice( + &(&(&table)[0u32.wrapping_mul(len) as usize..] as &[u32])[0usize..len as usize], + ); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u32 = fstar::uint32::eq_mask(bits_c, i0.wrapping_add(1u32)); + let res_j: (&[u32], &[u32]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(len) as usize); + for i1 in 0u32..len { + let x: u32 = c & res_j.1[i1 as usize] | !c & (&resM)[i1 as usize]; + let os: (&mut [u32], &mut [u32]) = resM.split_at_mut(0usize); + os.1[i1 as usize] = x + } + }) + } else { + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r20: (&[u32], &[u32]) = ctx_n0.1.split_at(len as usize); + super::base::bn_from_mont_u32(len, ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut tmp0: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]) + .copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u32(len, ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u32]>(&table); + ((&mut tmp0)[0usize..len as usize]).copy_from_slice( + &(&(&table)[0u32.wrapping_mul(len) as usize..] as &[u32])[0usize..len as usize], + ); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u32 = fstar::uint32::eq_mask(bits_l, i0.wrapping_add(1u32)); + let res_j: (&[u32], &[u32]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(len) as usize); + for i1 in 0u32..len { + let x: u32 = c & res_j.1[i1 as usize] | !c & (&tmp0)[i1 as usize]; + let os: (&mut [u32], &mut [u32]) = tmp0.split_at_mut(0usize); + os.1[i1 as usize] = x + } + }); + let mut aM_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u32(len, ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::base::bn_from_mont_u32(len, n, mu, &resM, res) + } +} + +pub(crate) fn bn_mod_exp_vartime_u32( + len: u32, + nBits: u32, + n: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + let mut r2: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + super::base::bn_precomp_r2_mod_n_u32(len, nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::base::bn_mod_exp_vartime_precomp_u32(len, n, mu, &r2, a, bBits, b, res) +} + +pub(crate) fn bn_mod_exp_consttime_u32( + len: u32, + nBits: u32, + n: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + let mut r2: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + super::base::bn_precomp_r2_mod_n_u32(len, nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::base::bn_mod_exp_consttime_precomp_u32(len, n, mu, &r2, a, bBits, b, res) +} + +pub(crate) fn bn_check_mod_exp_u64(len: u32, n: &[u64], a: &[u64], bBits: u32, b: &[u64]) -> u64 { + let mut one: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut one)[0usize..len as usize]) + .copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u64 = (&acc)[0usize]; + let m00: u64 = m0 & m1; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let m10: u64 = if bBits < 64u32.wrapping_mul(bLen) { + let mut b2: Box<[u64]> = vec![0u64; bLen as usize].into_boxed_slice(); + let i: u32 = bBits.wrapping_div(64u32); + let j: u32 = bBits.wrapping_rem(64u32); + (&mut b2)[i as usize] = (&b2)[i as usize] | 1u64.wrapping_shl(j); + let mut acc0: [u64; 1] = [0u64; 1usize]; + for i0 in 0u32..bLen { + let beq: u64 = fstar::uint64::eq_mask(b[i0 as usize], (&b2)[i0 as usize]); + let blt: u64 = !fstar::uint64::gte_mask(b[i0 as usize], (&b2)[i0 as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let res: u64 = (&acc0)[0usize]; + res + } else { + 0xFFFFFFFFFFFFFFFFu64 + }; + let mut acc0: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let m2: u64 = (&acc0)[0usize]; + let m: u64 = m10 & m2; + m00 & m +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_mod_exp_vartime_precomp_u64( + len: u32, + n: &[u64], + mu: u64, + r2: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + if bBits < 200u32 { + let mut aM: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + super::base::bn_to_mont_u64(len, n, mu, r2, a, &mut aM); + let mut resM: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let mut ctx: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut ctx)[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + ((&mut ctx)[len as usize..len as usize + len as usize]) + .copy_from_slice(&r2[0usize..len as usize]); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(len as usize); + super::base::bn_from_mont_u64(len, ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = i.wrapping_div(64u32); + let j: u32 = i.wrapping_rem(64u32); + let tmp: u64 = b[i1 as usize]; + let bit: u64 = tmp.wrapping_shr(j) & 1u64; + if bit != 0u64 { + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]) + .copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u64(len, ctx_n0.1, mu, &aM_copy, &aM, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u64(len, ctx_n0.1, mu, &aM_copy, &mut aM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::base::bn_from_mont_u64(len, n, mu, &resM, res) + } else { + let mut aM: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + super::base::bn_to_mont_u64(len, n, mu, r2, a, &mut aM); + let mut resM: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let mut ctx: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut ctx)[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + ((&mut ctx)[len as usize..len as usize + len as usize]) + .copy_from_slice(&r2[0usize..len as usize]); + let mut table: Box<[u64]> = vec![0u64; 16u32.wrapping_mul(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let t0: (&mut [u64], &mut [u64]) = table.split_at_mut(0usize); + let t1: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(len as usize); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(len as usize); + super::base::bn_from_mont_u64(len, ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (t1.1[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + lowstar::ignore::ignore::<&[u64]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u64], &[u64]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(len) as usize); + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&t11.1[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u64(len, ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize + + len as usize]) + .copy_from_slice(&(&tmp)[0usize..len as usize]); + let t2: (&[u64], &[u64]) = + table.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize); + let mut aM_copy0: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy0)[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u64(len, ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(len) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(len) as usize + + len as usize]) + .copy_from_slice(&(&tmp)[0usize..len as usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, i, 4u32); + let bits_l32: u32 = bits_c as u32; + let a_bits_l: (&[u64], &[u64]) = table.split_at(bits_l32.wrapping_mul(len) as usize); + ((&mut resM)[0usize..len as usize]).copy_from_slice(&a_bits_l.1[0usize..len as usize]) + } else { + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r20: (&[u64], &[u64]) = ctx_n0.1.split_at(len as usize); + super::base::bn_from_mont_u64(len, ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut tmp0: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]) + .copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u64(len, ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u64]>(&table); + let bits_l32: u32 = bits_l as u32; + let a_bits_l: (&[u64], &[u64]) = table.split_at(bits_l32.wrapping_mul(len) as usize); + ((&mut tmp0)[0usize..len as usize]).copy_from_slice(&a_bits_l.1[0usize..len as usize]); + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u64(len, ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::base::bn_from_mont_u64(len, n, mu, &resM, res) + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_mod_exp_consttime_precomp_u64( + len: u32, + n: &[u64], + mu: u64, + r2: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + if bBits < 200u32 { + let mut aM: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + super::base::bn_to_mont_u64(len, n, mu, r2, a, &mut aM); + let mut resM: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let mut ctx: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut ctx)[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + ((&mut ctx)[len as usize..len as usize + len as usize]) + .copy_from_slice(&r2[0usize..len as usize]); + let mut sw: [u64; 1] = [0u64; 1usize]; + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(len as usize); + super::base::bn_from_mont_u64(len, ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_div(64u32); + let j: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_rem(64u32); + let tmp: u64 = b[i1 as usize]; + let bit: u64 = tmp.wrapping_shr(j) & 1u64; + let sw1: u64 = bit ^ (&sw)[0usize]; + for i0 in 0u32..len { + let dummy: u64 = + 0u64.wrapping_sub(sw1) & ((&resM)[i0 as usize] ^ (&aM)[i0 as usize]); + (&mut resM)[i0 as usize] = (&resM)[i0 as usize] ^ dummy; + (&mut aM)[i0 as usize] = (&aM)[i0 as usize] ^ dummy + } + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u64(len, ctx_n0.1, mu, &aM_copy, &resM, &mut aM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + let mut aM_copy0: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy0)[0usize..len as usize]).copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u64(len, ctx_n1.1, mu, &aM_copy0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (&mut sw)[0usize] = bit + } + let sw0: u64 = (&sw)[0usize]; + for i in 0u32..len { + let dummy: u64 = 0u64.wrapping_sub(sw0) & ((&resM)[i as usize] ^ (&aM)[i as usize]); + (&mut resM)[i as usize] = (&resM)[i as usize] ^ dummy; + (&mut aM)[i as usize] = (&aM)[i as usize] ^ dummy + } + super::base::bn_from_mont_u64(len, n, mu, &resM, res) + } else { + let mut aM: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + super::base::bn_to_mont_u64(len, n, mu, r2, a, &mut aM); + let mut resM: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let mut ctx: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut ctx)[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + ((&mut ctx)[len as usize..len as usize + len as usize]) + .copy_from_slice(&r2[0usize..len as usize]); + let mut table: Box<[u64]> = vec![0u64; 16u32.wrapping_mul(len) as usize].into_boxed_slice(); + let mut tmp: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let t0: (&mut [u64], &mut [u64]) = table.split_at_mut(0usize); + let t1: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(len as usize); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(len as usize); + super::base::bn_from_mont_u64(len, ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (t1.1[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + lowstar::ignore::ignore::<&[u64]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u64], &[u64]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(len) as usize); + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&t11.1[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u64(len, ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize + + len as usize]) + .copy_from_slice(&(&tmp)[0usize..len as usize]); + let t2: (&[u64], &[u64]) = + table.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(len) as usize); + let mut aM_copy0: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy0)[0usize..len as usize]).copy_from_slice(&(&aM)[0usize..len as usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u64(len, ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(len) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(len) as usize + + len as usize]) + .copy_from_slice(&(&tmp)[0usize..len as usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, i, 4u32); + ((&mut resM)[0usize..len as usize]).copy_from_slice( + &(&(&table)[0u32.wrapping_mul(len) as usize..] as &[u64])[0usize..len as usize], + ); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u64 = fstar::uint64::eq_mask(bits_c, i0.wrapping_add(1u32) as u64); + let res_j: (&[u64], &[u64]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(len) as usize); + for i1 in 0u32..len { + let x: u64 = c & res_j.1[i1 as usize] | !c & (&resM)[i1 as usize]; + let os: (&mut [u64], &mut [u64]) = resM.split_at_mut(0usize); + os.1[i1 as usize] = x + } + }) + } else { + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r20: (&[u64], &[u64]) = ctx_n0.1.split_at(len as usize); + super::base::bn_from_mont_u64(len, ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut tmp0: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]) + .copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_sqr_u64(len, ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u64]>(&table); + ((&mut tmp0)[0usize..len as usize]).copy_from_slice( + &(&(&table)[0u32.wrapping_mul(len) as usize..] as &[u64])[0usize..len as usize], + ); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u64 = fstar::uint64::eq_mask(bits_l, i0.wrapping_add(1u32) as u64); + let res_j: (&[u64], &[u64]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(len) as usize); + for i1 in 0u32..len { + let x: u64 = c & res_j.1[i1 as usize] | !c & (&tmp0)[i1 as usize]; + let os: (&mut [u64], &mut [u64]) = tmp0.split_at_mut(0usize); + os.1[i1 as usize] = x + } + }); + let mut aM_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut aM_copy)[0usize..len as usize]).copy_from_slice(&(&resM)[0usize..len as usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::base::bn_almost_mont_mul_u64(len, ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::base::bn_from_mont_u64(len, n, mu, &resM, res) + } +} + +pub(crate) fn bn_mod_exp_vartime_u64( + len: u32, + nBits: u32, + n: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + let mut r2: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + super::base::bn_precomp_r2_mod_n_u64(len, nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::base::bn_mod_exp_vartime_precomp_u64(len, n, mu, &r2, a, bBits, b, res) +} + +pub(crate) fn bn_mod_exp_consttime_u64( + len: u32, + nBits: u32, + n: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + let mut r2: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + super::base::bn_precomp_r2_mod_n_u64(len, nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::base::bn_mod_exp_consttime_precomp_u64(len, n, mu, &r2, a, bBits, b, res) +} + +#[derive(PartialEq, Clone)] +pub struct bn_mont_ctx_u32 { + pub len: u32, + pub n: Box<[u32]>, + pub mu: u32, + pub r2: Box<[u32]>, +} + +#[derive(PartialEq, Clone)] +pub struct bn_mont_ctx_u64 { + pub len: u32, + pub n: Box<[u64]>, + pub mu: u64, + pub r2: Box<[u64]>, +} diff --git a/hacl-rs/src/bignum/bignum256.rs b/hacl-rs/src/bignum/bignum256.rs new file mode 100644 index 000000000..d89bdc64c --- /dev/null +++ b/hacl-rs/src/bignum/bignum256.rs @@ -0,0 +1,1297 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_macros as krml; + +use crate::fstar; +use crate::lowstar; +use crate::util as lib; + +/** +Write `a + b mod 2^256` in `res`. + + This functions returns the carry. + + The arguments a, b and res are meant to be 256-bit bignums, i.e. uint64_t[4] +*/ +pub fn add(a: &[u64], b: &[u64], res: &mut [u64]) -> u64 { + let mut c: [u64; 1] = [0u64; 1usize]; + { + let t1: u64 = a[4u32.wrapping_mul(0u32) as usize]; + let t2: u64 = b[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t12, t22, res_i2.1) + }; + (&c)[0usize] +} + +/** +Write `a - b mod 2^256` in `res`. + + This functions returns the carry. + + The arguments a, b and res are meant to be 256-bit bignums, i.e. uint64_t[4] +*/ +pub fn sub(a: &[u64], b: &[u64], res: &mut [u64]) -> u64 { + let mut c: [u64; 1] = [0u64; 1usize]; + { + let t1: u64 = a[4u32.wrapping_mul(0u32) as usize]; + let t2: u64 = b[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, t22, res_i2.1) + }; + (&c)[0usize] +} + +/** +Write `(a + b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn add_mod(n: &[u64], a: &[u64], b: &[u64], res: &mut [u64]) { + let mut c: [u64; 1] = [0u64; 1usize]; + { + let t1: u64 = a[4u32.wrapping_mul(0u32) as usize]; + let t2: u64 = b[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t12, t22, res_i2.1) + }; + let c0: u64 = (&c)[0usize]; + let mut tmp: [u64; 4] = [0u64; 4usize]; + let mut c1: [u64; 1] = [0u64; 1usize]; + { + let t1: u64 = res[4u32.wrapping_mul(0u32) as usize]; + let t2: u64 = n[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t12, t22, res_i2.1) + }; + let c10: u64 = (&c1)[0usize]; + let c2: u64 = c0.wrapping_sub(c10); + krml::unroll_for!(4, "i", 0u32, 1u32, { + let x: u64 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +/** +Write `(a - b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn sub_mod(n: &[u64], a: &[u64], b: &[u64], res: &mut [u64]) { + let mut c: [u64; 1] = [0u64; 1usize]; + { + let t1: u64 = a[4u32.wrapping_mul(0u32) as usize]; + let t2: u64 = b[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, t22, res_i2.1) + }; + let c0: u64 = (&c)[0usize]; + let mut tmp: [u64; 4] = [0u64; 4usize]; + let mut c1: [u64; 1] = [0u64; 1usize]; + { + let t1: u64 = res[4u32.wrapping_mul(0u32) as usize]; + let t2: u64 = n[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t12, t22, res_i2.1) + }; + let c10: u64 = (&c1)[0usize]; + lowstar::ignore::ignore::(c10); + let c2: u64 = 0u64.wrapping_sub(c0); + krml::unroll_for!(4, "i", 0u32, 1u32, { + let x: u64 = c2 & (&tmp)[i as usize] | !c2 & res[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +/** +Write `a * b` in `res`. + + The arguments a and b are meant to be 256-bit bignums, i.e. uint64_t[4]. + The outparam res is meant to be a 512-bit bignum, i.e. uint64_t[8]. +*/ +pub fn mul(a: &[u64], b: &[u64], res: &mut [u64]) { + (res[0usize..8usize]).copy_from_slice(&[0u64; 8usize]); + krml::unroll_for!(4, "i", 0u32, 1u32, { + let bj: u64 = b[i as usize]; + let res_j: (&mut [u64], &mut [u64]) = res.split_at_mut(i as usize); + let mut c: [u64; 1] = [0u64; 1usize]; + { + let a_i: u64 = a[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, bj, (&c)[0usize], res_i.1); + let a_i0: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, bj, (&c)[0usize], res_i0.1); + let a_i1: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, bj, (&c)[0usize], res_i1.1); + let a_i2: u64 = a[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, bj, (&c)[0usize], res_i2.1) + }; + let r: u64 = (&c)[0usize]; + res[4u32.wrapping_add(i) as usize] = r + }) +} + +/** +Write `a * a` in `res`. + + The argument a is meant to be a 256-bit bignum, i.e. uint64_t[4]. + The outparam res is meant to be a 512-bit bignum, i.e. uint64_t[8]. +*/ +pub fn sqr(a: &[u64], res: &mut [u64]) { + (res[0usize..8usize]).copy_from_slice(&[0u64; 8usize]); + krml::unroll_for!(4, "i", 0u32, 1u32, { + let a_j: u64 = a[i as usize]; + let ab: (&[u64], &[u64]) = a.split_at(0usize); + let res_j: (&mut [u64], &mut [u64]) = res.split_at_mut(i as usize); + let mut c: [u64; 1] = [0u64; 1usize]; + for i0 in 0u32..i.wrapping_div(4u32) { + let a_i: u64 = ab.1[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, a_j, (&c)[0usize], res_i.1); + let a_i0: u64 = ab.1[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, a_j, (&c)[0usize], res_i0.1); + let a_i1: u64 = ab.1[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, a_j, (&c)[0usize], res_i1.1); + let a_i2: u64 = ab.1[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, a_j, (&c)[0usize], res_i2.1) + } + for i0 in i.wrapping_div(4u32).wrapping_mul(4u32)..i { + let a_i: u64 = ab.1[i0 as usize]; + let res_i: (&mut [u64], &mut [u64]) = res_j.1.split_at_mut(i0 as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, a_j, (&c)[0usize], res_i.1) + } + let r: u64 = (&c)[0usize]; + res[i.wrapping_add(i) as usize] = r + }); + let mut a_copy: [u64; 8] = [0u64; 8usize]; + let mut b_copy: [u64; 8] = [0u64; 8usize]; + ((&mut a_copy)[0usize..8usize]).copy_from_slice(&res[0usize..8usize]); + ((&mut b_copy)[0usize..8usize]).copy_from_slice(&res[0usize..8usize]); + let r: u64 = super::bignum_base::bn_add_eq_len_u64(8u32, &a_copy, &b_copy, res); + let c0: u64 = r; + lowstar::ignore::ignore::(c0); + let mut tmp: [u64; 8] = [0u64; 8usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let res1: fstar::uint128::uint128 = fstar::uint128::mul_wide(a[i as usize], a[i as usize]); + let hi: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(res1, 64u32)); + let lo: u64 = fstar::uint128::uint128_to_uint64(res1); + (&mut tmp)[2u32.wrapping_mul(i) as usize] = lo; + (&mut tmp)[2u32.wrapping_mul(i).wrapping_add(1u32) as usize] = hi + }); + let mut a_copy0: [u64; 8] = [0u64; 8usize]; + let mut b_copy0: [u64; 8] = [0u64; 8usize]; + ((&mut a_copy0)[0usize..8usize]).copy_from_slice(&res[0usize..8usize]); + ((&mut b_copy0)[0usize..8usize]).copy_from_slice(&(&tmp)[0usize..8usize]); + let r0: u64 = super::bignum_base::bn_add_eq_len_u64(8u32, &a_copy0, &b_copy0, res); + let c1: u64 = r0; + lowstar::ignore::ignore::(c1) +} + +#[inline] +fn precompr2(nBits: u32, n: &[u64], res: &mut [u64]) { + (res[0usize..4usize]).copy_from_slice(&[0u64; 4usize]); + let i: u32 = nBits.wrapping_div(64u32); + let j: u32 = nBits.wrapping_rem(64u32); + res[i as usize] |= 1u64.wrapping_shl(j); + for _i in 0u32..512u32.wrapping_sub(nBits) { + let mut a_copy: [u64; 4] = [0u64; 4usize]; + let mut b_copy: [u64; 4] = [0u64; 4usize]; + ((&mut a_copy)[0usize..4usize]).copy_from_slice(&res[0usize..4usize]); + ((&mut b_copy)[0usize..4usize]).copy_from_slice(&res[0usize..4usize]); + super::bignum256::add_mod(n, &a_copy, &b_copy, res) + } +} + +#[inline] +fn reduction(n: &[u64], nInv: u64, c: &mut [u64], res: &mut [u64]) { + let mut c0: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let qj: u64 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize); + let mut c1: [u64; 1] = [0u64; 1usize]; + { + let a_i: u64 = n[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, qj, (&c1)[0usize], res_i2.1) + }; + let r: u64 = (&c1)[0usize]; + let c10: u64 = r; + let res_j0: u64 = c[4u32.wrapping_add(i) as usize]; + let resb: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize + 4usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c0)[0usize], c10, res_j0, resb.1) + }); + (res[0usize..4usize]).copy_from_slice(&(&c[4usize..])[0usize..4usize]); + let c00: u64 = (&c0)[0usize]; + let mut tmp: [u64; 4] = [0u64; 4usize]; + let mut c1: [u64; 1] = [0u64; 1usize]; + { + let t1: u64 = res[4u32.wrapping_mul(0u32) as usize]; + let t2: u64 = n[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t12, t22, res_i2.1) + }; + let c10: u64 = (&c1)[0usize]; + let c2: u64 = c00.wrapping_sub(c10); + krml::unroll_for!(4, "i", 0u32, 1u32, { + let x: u64 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +#[inline] +fn to(n: &[u64], nInv: u64, r2: &[u64], a: &[u64], aM: &mut [u64]) { + let mut c: [u64; 8] = [0u64; 8usize]; + super::bignum256::mul(a, r2, &mut c); + super::bignum256::reduction(n, nInv, &mut c, aM) +} + +#[inline] +fn from(n: &[u64], nInv_u64: u64, aM: &[u64], a: &mut [u64]) { + let mut tmp: [u64; 8] = [0u64; 8usize]; + ((&mut tmp)[0usize..4usize]).copy_from_slice(&aM[0usize..4usize]); + super::bignum256::reduction(n, nInv_u64, &mut tmp, a) +} + +#[inline] +fn areduction(n: &[u64], nInv: u64, c: &mut [u64], res: &mut [u64]) { + let mut c0: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let qj: u64 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize); + let mut c1: [u64; 1] = [0u64; 1usize]; + { + let a_i: u64 = n[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u64 = n[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, qj, (&c1)[0usize], res_i2.1) + }; + let r: u64 = (&c1)[0usize]; + let c10: u64 = r; + let res_j0: u64 = c[4u32.wrapping_add(i) as usize]; + let resb: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize + 4usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c0)[0usize], c10, res_j0, resb.1) + }); + (res[0usize..4usize]).copy_from_slice(&(&c[4usize..])[0usize..4usize]); + let c00: u64 = (&c0)[0usize]; + let mut tmp: [u64; 4] = [0u64; 4usize]; + let c1: u64 = super::bignum256::sub(res, n, &mut tmp); + lowstar::ignore::ignore::(c1); + let m: u64 = 0u64.wrapping_sub(c00); + krml::unroll_for!(4, "i", 0u32, 1u32, { + let x: u64 = m & (&tmp)[i as usize] | !m & res[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +#[inline] +fn amont_mul(n: &[u64], nInv_u64: u64, aM: &[u64], bM: &[u64], resM: &mut [u64]) { + let mut c: [u64; 8] = [0u64; 8usize]; + super::bignum256::mul(aM, bM, &mut c); + super::bignum256::areduction(n, nInv_u64, &mut c, resM) +} + +#[inline] +fn amont_sqr(n: &[u64], nInv_u64: u64, aM: &[u64], resM: &mut [u64]) { + let mut c: [u64; 8] = [0u64; 8usize]; + super::bignum256::sqr(aM, &mut c); + super::bignum256::areduction(n, nInv_u64, &mut c, resM) +} + +#[inline] +fn bn_slow_precomp(n: &[u64], mu: u64, r2: &[u64], a: &[u64], res: &mut [u64]) { + let mut a_mod: [u64; 4] = [0u64; 4usize]; + let mut a1: [u64; 8] = [0u64; 8usize]; + ((&mut a1)[0usize..8usize]).copy_from_slice(&a[0usize..8usize]); + super::bignum256::areduction(n, mu, &mut a1, &mut a_mod); + super::bignum256::to(n, mu, r2, &a_mod, res) +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be a 512-bit bignum, i.e. uint64_t[8]. + The argument n and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • 1 < n + • n % 2 = 1 +*/ +pub fn r#mod(n: &[u64], a: &[u64], res: &mut [u64]) -> bool { + let mut one: [u64; 4] = [0u64; 4usize]; + ((&mut one)[0usize..4usize]).copy_from_slice(&[0u64; 4usize]); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + }); + let m1: u64 = (&acc)[0usize]; + let is_valid_m: u64 = m0 & m1; + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(4u32, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + let mut r2: [u64; 4] = [0u64; 4usize]; + super::bignum256::precompr2(nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::bignum256::bn_slow_precomp(n, mu, &r2, a, res) + } else { + (res[0usize..4usize]).copy_from_slice(&[0u64; 4usize]) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +fn exp_check(n: &[u64], a: &[u64], bBits: u32, b: &[u64]) -> u64 { + let mut one: [u64; 4] = [0u64; 4usize]; + ((&mut one)[0usize..4usize]).copy_from_slice(&[0u64; 4usize]); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + }); + let m1: u64 = (&acc)[0usize]; + let m00: u64 = m0 & m1; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let m10: u64 = if bBits < 64u32.wrapping_mul(bLen) { + let mut b2: Box<[u64]> = vec![0u64; bLen as usize].into_boxed_slice(); + let i: u32 = bBits.wrapping_div(64u32); + let j: u32 = bBits.wrapping_rem(64u32); + (&mut b2)[i as usize] = (&b2)[i as usize] | 1u64.wrapping_shl(j); + let mut acc0: [u64; 1] = [0u64; 1usize]; + for i0 in 0u32..bLen { + let beq: u64 = fstar::uint64::eq_mask(b[i0 as usize], (&b2)[i0 as usize]); + let blt: u64 = !fstar::uint64::gte_mask(b[i0 as usize], (&b2)[i0 as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let res: u64 = (&acc0)[0usize]; + res + } else { + 0xFFFFFFFFFFFFFFFFu64 + }; + let mut acc0: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + }); + let m2: u64 = (&acc0)[0usize]; + let m: u64 = m10 & m2; + m00 & m +} + +#[inline] +fn exp_vartime_precomp( + n: &[u64], + mu: u64, + r2: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + if bBits < 200u32 { + let mut aM: [u64; 4] = [0u64; 4usize]; + super::bignum256::to(n, mu, r2, a, &mut aM); + let mut resM: [u64; 4] = [0u64; 4usize]; + let mut ctx: [u64; 8] = [0u64; 8usize]; + ((&mut ctx)[0usize..4usize]).copy_from_slice(&n[0usize..4usize]); + ((&mut ctx)[4usize..4usize + 4usize]).copy_from_slice(&r2[0usize..4usize]); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(4usize); + super::bignum256::from(ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = i.wrapping_div(64u32); + let j: u32 = i.wrapping_rem(64u32); + let tmp: u64 = b[i1 as usize]; + let bit: u64 = tmp.wrapping_shr(j) & 1u64; + if bit != 0u64 { + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&(&resM)[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_mul(ctx_n0.1, mu, &aM_copy, &aM, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&(&aM)[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut aM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::bignum256::from(n, mu, &resM, res) + } else { + let mut aM: [u64; 4] = [0u64; 4usize]; + super::bignum256::to(n, mu, r2, a, &mut aM); + let mut resM: [u64; 4] = [0u64; 4usize]; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let mut ctx: [u64; 8] = [0u64; 8usize]; + ((&mut ctx)[0usize..4usize]).copy_from_slice(&n[0usize..4usize]); + ((&mut ctx)[4usize..4usize + 4usize]).copy_from_slice(&r2[0usize..4usize]); + let mut table: [u64; 64] = [0u64; 64usize]; + let mut tmp: [u64; 4] = [0u64; 4usize]; + let t0: (&mut [u64], &mut [u64]) = table.split_at_mut(0usize); + let t1: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(4usize); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(4usize); + super::bignum256::from(ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (t1.1[0usize..4usize]).copy_from_slice(&(&aM)[0usize..4usize]); + lowstar::ignore::ignore::<&[u64]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u64], &[u64]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(4u32) as usize); + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&t11.1[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(4u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(4u32) as usize + 4usize]) + .copy_from_slice(&(&tmp)[0usize..4usize]); + let t2: (&[u64], &[u64]) = + table.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(4u32) as usize); + let mut aM_copy0: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy0)[0usize..4usize]).copy_from_slice(&(&aM)[0usize..4usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_mul(ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(4u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(4u32) as usize + 4usize]) + .copy_from_slice(&(&tmp)[0usize..4usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, i, 4u32); + let bits_l32: u32 = bits_c as u32; + let a_bits_l: (&[u64], &[u64]) = table.split_at(bits_l32.wrapping_mul(4u32) as usize); + ((&mut resM)[0usize..4usize]).copy_from_slice(&a_bits_l.1[0usize..4usize]) + } else { + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r20: (&[u64], &[u64]) = ctx_n0.1.split_at(4usize); + super::bignum256::from(ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut tmp0: [u64; 4] = [0u64; 4usize]; + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&(&resM)[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u64]>(&table); + let bits_l32: u32 = bits_l as u32; + let a_bits_l: (&[u64], &[u64]) = table.split_at(bits_l32.wrapping_mul(4u32) as usize); + ((&mut tmp0)[0usize..4usize]).copy_from_slice(&a_bits_l.1[0usize..4usize]); + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&(&resM)[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_mul(ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::bignum256::from(n, mu, &resM, res) + } +} + +#[inline] +fn exp_consttime_precomp( + n: &[u64], + mu: u64, + r2: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + if bBits < 200u32 { + let mut aM: [u64; 4] = [0u64; 4usize]; + super::bignum256::to(n, mu, r2, a, &mut aM); + let mut resM: [u64; 4] = [0u64; 4usize]; + let mut ctx: [u64; 8] = [0u64; 8usize]; + ((&mut ctx)[0usize..4usize]).copy_from_slice(&n[0usize..4usize]); + ((&mut ctx)[4usize..4usize + 4usize]).copy_from_slice(&r2[0usize..4usize]); + let mut sw: [u64; 1] = [0u64; 1usize]; + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(4usize); + super::bignum256::from(ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_div(64u32); + let j: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_rem(64u32); + let tmp: u64 = b[i1 as usize]; + let bit: u64 = tmp.wrapping_shr(j) & 1u64; + let sw1: u64 = bit ^ (&sw)[0usize]; + krml::unroll_for!(4, "i0", 0u32, 1u32, { + let dummy: u64 = + 0u64.wrapping_sub(sw1) & ((&resM)[i0 as usize] ^ (&aM)[i0 as usize]); + (&mut resM)[i0 as usize] = (&resM)[i0 as usize] ^ dummy; + (&mut aM)[i0 as usize] = (&aM)[i0 as usize] ^ dummy + }); + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&(&aM)[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_mul(ctx_n0.1, mu, &aM_copy, &resM, &mut aM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + let mut aM_copy0: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy0)[0usize..4usize]).copy_from_slice(&(&resM)[0usize..4usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_sqr(ctx_n1.1, mu, &aM_copy0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (&mut sw)[0usize] = bit + } + let sw0: u64 = (&sw)[0usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let dummy: u64 = 0u64.wrapping_sub(sw0) & ((&resM)[i as usize] ^ (&aM)[i as usize]); + (&mut resM)[i as usize] = (&resM)[i as usize] ^ dummy; + (&mut aM)[i as usize] = (&aM)[i as usize] ^ dummy + }); + super::bignum256::from(n, mu, &resM, res) + } else { + let mut aM: [u64; 4] = [0u64; 4usize]; + super::bignum256::to(n, mu, r2, a, &mut aM); + let mut resM: [u64; 4] = [0u64; 4usize]; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let mut ctx: [u64; 8] = [0u64; 8usize]; + ((&mut ctx)[0usize..4usize]).copy_from_slice(&n[0usize..4usize]); + ((&mut ctx)[4usize..4usize + 4usize]).copy_from_slice(&r2[0usize..4usize]); + let mut table: [u64; 64] = [0u64; 64usize]; + let mut tmp: [u64; 4] = [0u64; 4usize]; + let t0: (&mut [u64], &mut [u64]) = table.split_at_mut(0usize); + let t1: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(4usize); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(4usize); + super::bignum256::from(ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (t1.1[0usize..4usize]).copy_from_slice(&(&aM)[0usize..4usize]); + lowstar::ignore::ignore::<&[u64]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u64], &[u64]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(4u32) as usize); + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&t11.1[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(4u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(4u32) as usize + 4usize]) + .copy_from_slice(&(&tmp)[0usize..4usize]); + let t2: (&[u64], &[u64]) = + table.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(4u32) as usize); + let mut aM_copy0: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy0)[0usize..4usize]).copy_from_slice(&(&aM)[0usize..4usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_mul(ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(4u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(4u32) as usize + 4usize]) + .copy_from_slice(&(&tmp)[0usize..4usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, i, 4u32); + ((&mut resM)[0usize..4usize]) + .copy_from_slice(&(&(&table)[0usize..] as &[u64])[0usize..4usize]); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u64 = fstar::uint64::eq_mask(bits_c, i0.wrapping_add(1u32) as u64); + let res_j: (&[u64], &[u64]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(4u32) as usize); + krml::unroll_for!(4, "i1", 0u32, 1u32, { + let x: u64 = c & res_j.1[i1 as usize] | !c & (&resM)[i1 as usize]; + let os: (&mut [u64], &mut [u64]) = resM.split_at_mut(0usize); + os.1[i1 as usize] = x + }) + }) + } else { + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r20: (&[u64], &[u64]) = ctx_n0.1.split_at(4usize); + super::bignum256::from(ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut tmp0: [u64; 4] = [0u64; 4usize]; + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&(&resM)[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u64]>(&table); + ((&mut tmp0)[0usize..4usize]) + .copy_from_slice(&(&(&table)[0usize..] as &[u64])[0usize..4usize]); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u64 = fstar::uint64::eq_mask(bits_l, i0.wrapping_add(1u32) as u64); + let res_j: (&[u64], &[u64]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(4u32) as usize); + krml::unroll_for!(4, "i1", 0u32, 1u32, { + let x: u64 = c & res_j.1[i1 as usize] | !c & (&tmp0)[i1 as usize]; + let os: (&mut [u64], &mut [u64]) = tmp0.split_at_mut(0usize); + os.1[i1 as usize] = x + }) + }); + let mut aM_copy: [u64; 4] = [0u64; 4usize]; + ((&mut aM_copy)[0usize..4usize]).copy_from_slice(&(&resM)[0usize..4usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum256::amont_mul(ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::bignum256::from(n, mu, &resM, res) + } +} + +#[inline] +fn exp_vartime(nBits: u32, n: &[u64], a: &[u64], bBits: u32, b: &[u64], res: &mut [u64]) { + let mut r2: [u64; 4] = [0u64; 4usize]; + super::bignum256::precompr2(nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::bignum256::exp_vartime_precomp(n, mu, &r2, a, bBits, b, res) +} + +#[inline] +fn exp_consttime(nBits: u32, n: &[u64], a: &[u64], bBits: u32, b: &[u64], res: &mut [u64]) { + let mut r2: [u64; 4] = [0u64; 4usize]; + super::bignum256::precompr2(nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::bignum256::exp_consttime_precomp(n, mu, &r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 256-bit bignum, bBits should be 256. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime(n: &[u64], a: &[u64], bBits: u32, b: &[u64], res: &mut [u64]) -> bool { + let is_valid_m: u64 = super::bignum256::exp_check(n, a, bBits, b); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(4u32, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + super::bignum256::exp_vartime(nBits, n, a, bBits, b, res) + } else { + (res[0usize..4usize]).copy_from_slice(&[0u64; 4usize]) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 256-bit bignum, bBits should be 256. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime(n: &[u64], a: &[u64], bBits: u32, b: &[u64], res: &mut [u64]) -> bool { + let is_valid_m: u64 = super::bignum256::exp_check(n, a, bBits, b); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(4u32, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + super::bignum256::exp_consttime(nBits, n, a, bBits, b, res) + } else { + (res[0usize..4usize]).copy_from_slice(&[0u64; 4usize]) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + + The function returns false if any of the following preconditions are violated, true otherwise. + • n % 2 = 1 + • 1 < n + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime(n: &[u64], a: &[u64], res: &mut [u64]) -> bool { + let mut one: [u64; 4] = [0u64; 4usize]; + ((&mut one)[0usize..4usize]).copy_from_slice(&[0u64; 4usize]); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + }); + let m1: u64 = (&acc)[0usize]; + let m00: u64 = m0 & m1; + let bn_zero: [u64; 4] = [0u64; 4usize]; + let mut mask: [u64; 1] = [0xFFFFFFFFFFFFFFFFu64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let uu____0: u64 = fstar::uint64::eq_mask(a[i as usize], (&bn_zero)[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + }); + let mask1: u64 = (&mask)[0usize]; + let res1: u64 = mask1; + let m10: u64 = res1; + let mut acc0: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + }); + let m2: u64 = (&acc0)[0usize]; + let is_valid_m: u64 = m00 & !m10 & m2; + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(4u32, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + let mut n2: [u64; 4] = [0u64; 4usize]; + let c0: u64 = lib::inttypes_intrinsics::sub_borrow_u64( + 0u64, + n[0usize], + 2u64, + &mut (&mut n2)[0usize..], + ); + let a1: (&[u64], &[u64]) = n.split_at(1usize); + let res10: (&mut [u64], &mut [u64]) = n2.split_at_mut(1usize); + let mut c: [u64; 1] = [c0; 1usize]; + krml::unroll_for!(3, "i", 0u32, 1u32, { + let t1: u64 = a1.1[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res10.1.split_at_mut(i as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1) + }); + let c1: u64 = (&c)[0usize]; + let c2: u64 = c1; + lowstar::ignore::ignore::(c2); + super::bignum256::exp_vartime(nBits, n, a, 256u32, &n2, res) + } else { + (res[0usize..4usize]).copy_from_slice(&[0u64; 4usize]) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Heap-allocate and initialize a montgomery context. + + The argument n is meant to be a 256-bit bignum, i.e. uint64_t[4]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n % 2 = 1 + • 1 < n + + The caller will need to call Hacl_Bignum256_mont_ctx_free on the return value + to avoid memory leaks. +*/ +pub fn mont_ctx_init(n: &[u64]) -> Box<[super::base::bn_mont_ctx_u64]> { + let mut r2: Box<[u64]> = vec![0u64; 4usize].into_boxed_slice(); + let mut n1: Box<[u64]> = vec![0u64; 4usize].into_boxed_slice(); + let r21: &mut [u64] = &mut r2; + let n11: &mut [u64] = &mut n1; + (n11[0usize..4usize]).copy_from_slice(&n[0usize..4usize]); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(4u32, n) as u32); + super::bignum256::precompr2(nBits, n, r21); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + let res: super::base::bn_mont_ctx_u64 = super::base::bn_mont_ctx_u64 { + len: 4u32, + n: (*n11).into(), + mu, + r2: (*r21).into(), + }; + let buf: Box<[super::base::bn_mont_ctx_u64]> = vec![res].into_boxed_slice(); + buf +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be a 512-bit bignum, i.e. uint64_t[8]. + The outparam res is meant to be a 256-bit bignum, i.e. uint64_t[4]. + The argument k is a montgomery context obtained through Hacl_Bignum256_mont_ctx_init. +*/ +pub fn mod_precomp(k: &[super::base::bn_mont_ctx_u64], a: &[u64], res: &mut [u64]) { + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::bignum256::bn_slow_precomp(n, mu, r2, a, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + The argument k is a montgomery context obtained through Hacl_Bignum256_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 256-bit bignum, bBits should be 256. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::bignum256::exp_vartime_precomp(n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + The argument k is a montgomery context obtained through Hacl_Bignum256_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 256-bit bignum, bBits should be 256. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime_*. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::bignum256::exp_consttime_precomp(n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The argument a and the outparam res are meant to be 256-bit bignums, i.e. uint64_t[4]. + The argument k is a montgomery context obtained through Hacl_Bignum256_mont_ctx_init. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + res: &mut [u64], +) { + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + let mut n2: [u64; 4] = [0u64; 4usize]; + let c0: u64 = + lib::inttypes_intrinsics::sub_borrow_u64(0u64, n[0usize], 2u64, &mut (&mut n2)[0usize..]); + let a1: (&[u64], &[u64]) = n.split_at(1usize); + let res1: (&mut [u64], &mut [u64]) = n2.split_at_mut(1usize); + let mut c: [u64; 1] = [c0; 1usize]; + krml::unroll_for!(3, "i", 0u32, 1u32, { + let t1: u64 = a1.1[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res1.1.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1) + }); + let c1: u64 = (&c)[0usize]; + let c2: u64 = c1; + lowstar::ignore::ignore::(c2); + super::bignum256::exp_vartime_precomp(n, mu, r2, a, 256u32, &n2, res) +} + +/** +Load a bid-endian bignum from memory. + + The argument b points to len bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_be(len: u32, b: &[u8]) -> Box<[u64]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) > 536870911u32 { + [].into() + } else { + let mut res: Box<[u64]> = + vec![0u64; len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u64] = &mut res; + let res2: &mut [u64] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[tmpLen.wrapping_sub(len) as usize + ..tmpLen.wrapping_sub(len) as usize + len as usize]) + .copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..bnLen { + let u: u64 = lowstar::endianness::load64_be( + &(&tmp)[bnLen.wrapping_sub(i).wrapping_sub(1u32).wrapping_mul(8u32) as usize..], + ); + let x: u64 = u; + let os: (&mut [u64], &mut [u64]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Load a little-endian bignum from memory. + + The argument b points to len bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_le(len: u32, b: &[u8]) -> Box<[u64]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) > 536870911u32 { + [].into() + } else { + let mut res: Box<[u64]> = + vec![0u64; len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u64] = &mut res; + let res2: &mut [u64] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) { + let bj: (&[u8], &[u8]) = tmp.split_at(i.wrapping_mul(8u32) as usize); + let u: u64 = lowstar::endianness::load64_le(bj.1); + let r1: u64 = u; + let x: u64 = r1; + let os: (&mut [u64], &mut [u64]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Serialize a bignum into big-endian memory. + + The argument b points to a 256-bit bignum. + The outparam res points to 32 bytes of valid memory. +*/ +pub fn bn_to_bytes_be(b: &[u64], res: &mut [u8]) { + let tmp: [u8; 32] = [0u8; 32usize]; + lowstar::ignore::ignore::<&[u8]>(&tmp); + krml::unroll_for!( + 4, + "i", + 0u32, + 1u32, + lowstar::endianness::store64_be( + &mut res[i.wrapping_mul(8u32) as usize..], + b[4u32.wrapping_sub(i).wrapping_sub(1u32) as usize] + ) + ) +} + +/** +Serialize a bignum into little-endian memory. + + The argument b points to a 256-bit bignum. + The outparam res points to 32 bytes of valid memory. +*/ +pub fn bn_to_bytes_le(b: &[u64], res: &mut [u8]) { + let tmp: [u8; 32] = [0u8; 32usize]; + lowstar::ignore::ignore::<&[u8]>(&tmp); + krml::unroll_for!( + 4, + "i", + 0u32, + 1u32, + lowstar::endianness::store64_le(&mut res[i.wrapping_mul(8u32) as usize..], b[i as usize]) + ) +} + +/** +Returns 2^64 - 1 if a < b, otherwise returns 0. + + The arguments a and b are meant to be 256-bit bignums, i.e. uint64_t[4]. +*/ +pub fn lt_mask(a: &[u64], b: &[u64]) -> u64 { + let mut acc: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], b[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], b[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + }); + (&acc)[0usize] +} + +/** +Returns 2^64 - 1 if a = b, otherwise returns 0. + + The arguments a and b are meant to be 256-bit bignums, i.e. uint64_t[4]. +*/ +pub fn eq_mask(a: &[u64], b: &[u64]) -> u64 { + let mut mask: [u64; 1] = [0xFFFFFFFFFFFFFFFFu64; 1usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let uu____0: u64 = fstar::uint64::eq_mask(a[i as usize], b[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + }); + let mask1: u64 = (&mask)[0usize]; + mask1 +} diff --git a/hacl-rs/src/bignum/bignum256_32.rs b/hacl-rs/src/bignum/bignum256_32.rs new file mode 100644 index 000000000..1d5ecd95d --- /dev/null +++ b/hacl-rs/src/bignum/bignum256_32.rs @@ -0,0 +1,1334 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_macros as krml; + +use crate::fstar; +use crate::lowstar; +use crate::util as lib; + +/** +Write `a + b mod 2^256` in `res`. + + This functions returns the carry. + + The arguments a, b and res are meant to be 256-bit bignums, i.e. uint32_t[8] +*/ +pub fn add(a: &[u32], b: &[u32], res: &mut [u32]) -> u32 { + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i", 0u32, 1u32, { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t12, t22, res_i2.1) + }); + (&c)[0usize] +} + +/** +Write `a - b mod 2^256` in `res`. + + This functions returns the carry. + + The arguments a, b and res are meant to be 256-bit bignums, i.e. uint32_t[8] +*/ +pub fn sub(a: &[u32], b: &[u32], res: &mut [u32]) -> u32 { + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i", 0u32, 1u32, { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, t22, res_i2.1) + }); + (&c)[0usize] +} + +/** +Write `(a + b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn add_mod(n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) { + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i", 0u32, 1u32, { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t12, t22, res_i2.1) + }); + let c0: u32 = (&c)[0usize]; + let mut tmp: [u32; 8] = [0u32; 8usize]; + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i", 0u32, 1u32, { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u32 = (&c1)[0usize]; + let c2: u32 = c0.wrapping_sub(c10); + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u32 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +/** +Write `(a - b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn sub_mod(n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) { + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i", 0u32, 1u32, { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, t22, res_i2.1) + }); + let c0: u32 = (&c)[0usize]; + let mut tmp: [u32; 8] = [0u32; 8usize]; + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i", 0u32, 1u32, { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u32 = (&c1)[0usize]; + lowstar::ignore::ignore::(c10); + let c2: u32 = 0u32.wrapping_sub(c0); + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u32 = c2 & (&tmp)[i as usize] | !c2 & res[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +/** +Write `a * b` in `res`. + + The arguments a and b are meant to be 256-bit bignums, i.e. uint32_t[8]. + The outparam res is meant to be a 512-bit bignum, i.e. uint32_t[16]. +*/ +pub fn mul(a: &[u32], b: &[u32], res: &mut [u32]) { + (res[0usize..16usize]).copy_from_slice(&[0u32; 16usize]); + krml::unroll_for!(8, "i", 0u32, 1u32, { + let bj: u32 = b[i as usize]; + let res_j: (&mut [u32], &mut [u32]) = res.split_at_mut(i as usize); + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i0", 0u32, 1u32, { + let a_i: u32 = a[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, bj, (&c)[0usize], res_i.1); + let a_i0: u32 = a[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, bj, (&c)[0usize], res_i0.1); + let a_i1: u32 = a[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, bj, (&c)[0usize], res_i1.1); + let a_i2: u32 = a[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, bj, (&c)[0usize], res_i2.1) + }); + let r: u32 = (&c)[0usize]; + res[8u32.wrapping_add(i) as usize] = r + }) +} + +/** +Write `a * a` in `res`. + + The argument a is meant to be a 256-bit bignum, i.e. uint32_t[8]. + The outparam res is meant to be a 512-bit bignum, i.e. uint32_t[16]. +*/ +pub fn sqr(a: &[u32], res: &mut [u32]) { + (res[0usize..16usize]).copy_from_slice(&[0u32; 16usize]); + krml::unroll_for!(8, "i", 0u32, 1u32, { + let a_j: u32 = a[i as usize]; + let ab: (&[u32], &[u32]) = a.split_at(0usize); + let res_j: (&mut [u32], &mut [u32]) = res.split_at_mut(i as usize); + let mut c: [u32; 1] = [0u32; 1usize]; + for i0 in 0u32..i.wrapping_div(4u32) { + let a_i: u32 = ab.1[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, a_j, (&c)[0usize], res_i.1); + let a_i0: u32 = ab.1[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, a_j, (&c)[0usize], res_i0.1); + let a_i1: u32 = ab.1[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, a_j, (&c)[0usize], res_i1.1); + let a_i2: u32 = ab.1[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, a_j, (&c)[0usize], res_i2.1) + } + for i0 in i.wrapping_div(4u32).wrapping_mul(4u32)..i { + let a_i: u32 = ab.1[i0 as usize]; + let res_i: (&mut [u32], &mut [u32]) = res_j.1.split_at_mut(i0 as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, a_j, (&c)[0usize], res_i.1) + } + let r: u32 = (&c)[0usize]; + res[i.wrapping_add(i) as usize] = r + }); + let mut a_copy: [u32; 16] = [0u32; 16usize]; + let mut b_copy: [u32; 16] = [0u32; 16usize]; + ((&mut a_copy)[0usize..16usize]).copy_from_slice(&res[0usize..16usize]); + ((&mut b_copy)[0usize..16usize]).copy_from_slice(&res[0usize..16usize]); + let r: u32 = super::bignum_base::bn_add_eq_len_u32(16u32, &a_copy, &b_copy, res); + let c0: u32 = r; + lowstar::ignore::ignore::(c0); + let mut tmp: [u32; 16] = [0u32; 16usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let res1: u64 = (a[i as usize] as u64).wrapping_mul(a[i as usize] as u64); + let hi: u32 = res1.wrapping_shr(32u32) as u32; + let lo: u32 = res1 as u32; + (&mut tmp)[2u32.wrapping_mul(i) as usize] = lo; + (&mut tmp)[2u32.wrapping_mul(i).wrapping_add(1u32) as usize] = hi + }); + let mut a_copy0: [u32; 16] = [0u32; 16usize]; + let mut b_copy0: [u32; 16] = [0u32; 16usize]; + ((&mut a_copy0)[0usize..16usize]).copy_from_slice(&res[0usize..16usize]); + ((&mut b_copy0)[0usize..16usize]).copy_from_slice(&(&tmp)[0usize..16usize]); + let r0: u32 = super::bignum_base::bn_add_eq_len_u32(16u32, &a_copy0, &b_copy0, res); + let c1: u32 = r0; + lowstar::ignore::ignore::(c1) +} + +#[inline] +fn precompr2(nBits: u32, n: &[u32], res: &mut [u32]) { + (res[0usize..8usize]).copy_from_slice(&[0u32; 8usize]); + let i: u32 = nBits.wrapping_div(32u32); + let j: u32 = nBits.wrapping_rem(32u32); + res[i as usize] |= 1u32.wrapping_shl(j); + for _i in 0u32..512u32.wrapping_sub(nBits) { + let mut a_copy: [u32; 8] = [0u32; 8usize]; + let mut b_copy: [u32; 8] = [0u32; 8usize]; + ((&mut a_copy)[0usize..8usize]).copy_from_slice(&res[0usize..8usize]); + ((&mut b_copy)[0usize..8usize]).copy_from_slice(&res[0usize..8usize]); + super::bignum256_32::add_mod(n, &a_copy, &b_copy, res) + } +} + +#[inline] +fn reduction(n: &[u32], nInv: u32, c: &mut [u32], res: &mut [u32]) { + let mut c0: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let qj: u32 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize); + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i0", 0u32, 1u32, { + let a_i: u32 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u32 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u32 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u32 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, qj, (&c1)[0usize], res_i2.1) + }); + let r: u32 = (&c1)[0usize]; + let c10: u32 = r; + let res_j0: u32 = c[8u32.wrapping_add(i) as usize]; + let resb: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize + 8usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c0)[0usize], c10, res_j0, resb.1) + }); + (res[0usize..8usize]).copy_from_slice(&(&c[8usize..])[0usize..8usize]); + let c00: u32 = (&c0)[0usize]; + let mut tmp: [u32; 8] = [0u32; 8usize]; + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i", 0u32, 1u32, { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u32 = (&c1)[0usize]; + let c2: u32 = c00.wrapping_sub(c10); + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u32 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +#[inline] +fn to(n: &[u32], nInv: u32, r2: &[u32], a: &[u32], aM: &mut [u32]) { + let mut c: [u32; 16] = [0u32; 16usize]; + super::bignum256_32::mul(a, r2, &mut c); + super::bignum256_32::reduction(n, nInv, &mut c, aM) +} + +#[inline] +fn from(n: &[u32], nInv_u64: u32, aM: &[u32], a: &mut [u32]) { + let mut tmp: [u32; 16] = [0u32; 16usize]; + ((&mut tmp)[0usize..8usize]).copy_from_slice(&aM[0usize..8usize]); + super::bignum256_32::reduction(n, nInv_u64, &mut tmp, a) +} + +#[inline] +fn areduction(n: &[u32], nInv: u32, c: &mut [u32], res: &mut [u32]) { + let mut c0: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let qj: u32 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize); + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(2, "i0", 0u32, 1u32, { + let a_i: u32 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u32 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u32 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u32 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, qj, (&c1)[0usize], res_i2.1) + }); + let r: u32 = (&c1)[0usize]; + let c10: u32 = r; + let res_j0: u32 = c[8u32.wrapping_add(i) as usize]; + let resb: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize + 8usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c0)[0usize], c10, res_j0, resb.1) + }); + (res[0usize..8usize]).copy_from_slice(&(&c[8usize..])[0usize..8usize]); + let c00: u32 = (&c0)[0usize]; + let mut tmp: [u32; 8] = [0u32; 8usize]; + let c1: u32 = super::bignum256_32::sub(res, n, &mut tmp); + lowstar::ignore::ignore::(c1); + let m: u32 = 0u32.wrapping_sub(c00); + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u32 = m & (&tmp)[i as usize] | !m & res[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +#[inline] +fn amont_mul(n: &[u32], nInv_u64: u32, aM: &[u32], bM: &[u32], resM: &mut [u32]) { + let mut c: [u32; 16] = [0u32; 16usize]; + super::bignum256_32::mul(aM, bM, &mut c); + super::bignum256_32::areduction(n, nInv_u64, &mut c, resM) +} + +#[inline] +fn amont_sqr(n: &[u32], nInv_u64: u32, aM: &[u32], resM: &mut [u32]) { + let mut c: [u32; 16] = [0u32; 16usize]; + super::bignum256_32::sqr(aM, &mut c); + super::bignum256_32::areduction(n, nInv_u64, &mut c, resM) +} + +#[inline] +fn bn_slow_precomp(n: &[u32], mu: u32, r2: &[u32], a: &[u32], res: &mut [u32]) { + let mut a_mod: [u32; 8] = [0u32; 8usize]; + let mut a1: [u32; 16] = [0u32; 16usize]; + ((&mut a1)[0usize..16usize]).copy_from_slice(&a[0usize..16usize]); + super::bignum256_32::areduction(n, mu, &mut a1, &mut a_mod); + super::bignum256_32::to(n, mu, r2, &a_mod, res) +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be a 512-bit bignum, i.e. uint32_t[16]. + The argument n and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • 1 < n + • n % 2 = 1 +*/ +pub fn r#mod(n: &[u32], a: &[u32], res: &mut [u32]) -> bool { + let mut one: [u32; 8] = [0u32; 8usize]; + ((&mut one)[0usize..8usize]).copy_from_slice(&[0u32; 8usize]); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + }); + let m1: u32 = (&acc)[0usize]; + let is_valid_m: u32 = m0 & m1; + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(8u32, n)); + if is_valid_m == 0xFFFFFFFFu32 { + let mut r2: [u32; 8] = [0u32; 8usize]; + super::bignum256_32::precompr2(nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::bignum256_32::bn_slow_precomp(n, mu, &r2, a, res) + } else { + (res[0usize..8usize]).copy_from_slice(&[0u32; 8usize]) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +fn exp_check(n: &[u32], a: &[u32], bBits: u32, b: &[u32]) -> u32 { + let mut one: [u32; 8] = [0u32; 8usize]; + ((&mut one)[0usize..8usize]).copy_from_slice(&[0u32; 8usize]); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + }); + let m1: u32 = (&acc)[0usize]; + let m00: u32 = m0 & m1; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let m10: u32 = if bBits < 32u32.wrapping_mul(bLen) { + let mut b2: Box<[u32]> = vec![0u32; bLen as usize].into_boxed_slice(); + let i: u32 = bBits.wrapping_div(32u32); + let j: u32 = bBits.wrapping_rem(32u32); + (&mut b2)[i as usize] = (&b2)[i as usize] | 1u32.wrapping_shl(j); + let mut acc0: [u32; 1] = [0u32; 1usize]; + for i0 in 0u32..bLen { + let beq: u32 = fstar::uint32::eq_mask(b[i0 as usize], (&b2)[i0 as usize]); + let blt: u32 = !fstar::uint32::gte_mask(b[i0 as usize], (&b2)[i0 as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let res: u32 = (&acc0)[0usize]; + res + } else { + 0xFFFFFFFFu32 + }; + let mut acc0: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + }); + let m2: u32 = (&acc0)[0usize]; + let m: u32 = m10 & m2; + m00 & m +} + +#[inline] +fn exp_vartime_precomp( + n: &[u32], + mu: u32, + r2: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + if bBits < 200u32 { + let mut aM: [u32; 8] = [0u32; 8usize]; + super::bignum256_32::to(n, mu, r2, a, &mut aM); + let mut resM: [u32; 8] = [0u32; 8usize]; + let mut ctx: [u32; 16] = [0u32; 16usize]; + ((&mut ctx)[0usize..8usize]).copy_from_slice(&n[0usize..8usize]); + ((&mut ctx)[8usize..8usize + 8usize]).copy_from_slice(&r2[0usize..8usize]); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(8usize); + super::bignum256_32::from(ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = i.wrapping_div(32u32); + let j: u32 = i.wrapping_rem(32u32); + let tmp: u32 = b[i1 as usize]; + let bit: u32 = tmp.wrapping_shr(j) & 1u32; + if bit != 0u32 { + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&(&resM)[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_mul(ctx_n0.1, mu, &aM_copy, &aM, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&(&aM)[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut aM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::bignum256_32::from(n, mu, &resM, res) + } else { + let mut aM: [u32; 8] = [0u32; 8usize]; + super::bignum256_32::to(n, mu, r2, a, &mut aM); + let mut resM: [u32; 8] = [0u32; 8usize]; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let mut ctx: [u32; 16] = [0u32; 16usize]; + ((&mut ctx)[0usize..8usize]).copy_from_slice(&n[0usize..8usize]); + ((&mut ctx)[8usize..8usize + 8usize]).copy_from_slice(&r2[0usize..8usize]); + let mut table: [u32; 128] = [0u32; 128usize]; + let mut tmp: [u32; 8] = [0u32; 8usize]; + let t0: (&mut [u32], &mut [u32]) = table.split_at_mut(0usize); + let t1: (&mut [u32], &mut [u32]) = t0.1.split_at_mut(8usize); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(8usize); + super::bignum256_32::from(ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (t1.1[0usize..8usize]).copy_from_slice(&(&aM)[0usize..8usize]); + lowstar::ignore::ignore::<&[u32]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u32], &[u32]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(8u32) as usize); + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&t11.1[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(8u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(8u32) as usize + 8usize]) + .copy_from_slice(&(&tmp)[0usize..8usize]); + let t2: (&[u32], &[u32]) = + table.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(8u32) as usize); + let mut aM_copy0: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy0)[0usize..8usize]).copy_from_slice(&(&aM)[0usize..8usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_mul(ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(8u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(8u32) as usize + 8usize]) + .copy_from_slice(&(&tmp)[0usize..8usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, i, 4u32); + let bits_l32: u32 = bits_c; + let a_bits_l: (&[u32], &[u32]) = table.split_at(bits_l32.wrapping_mul(8u32) as usize); + ((&mut resM)[0usize..8usize]).copy_from_slice(&a_bits_l.1[0usize..8usize]) + } else { + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r20: (&[u32], &[u32]) = ctx_n0.1.split_at(8usize); + super::bignum256_32::from(ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut tmp0: [u32; 8] = [0u32; 8usize]; + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&(&resM)[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u32]>(&table); + let bits_l32: u32 = bits_l; + let a_bits_l: (&[u32], &[u32]) = table.split_at(bits_l32.wrapping_mul(8u32) as usize); + ((&mut tmp0)[0usize..8usize]).copy_from_slice(&a_bits_l.1[0usize..8usize]); + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&(&resM)[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_mul(ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::bignum256_32::from(n, mu, &resM, res) + } +} + +#[inline] +fn exp_consttime_precomp( + n: &[u32], + mu: u32, + r2: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + if bBits < 200u32 { + let mut aM: [u32; 8] = [0u32; 8usize]; + super::bignum256_32::to(n, mu, r2, a, &mut aM); + let mut resM: [u32; 8] = [0u32; 8usize]; + let mut ctx: [u32; 16] = [0u32; 16usize]; + ((&mut ctx)[0usize..8usize]).copy_from_slice(&n[0usize..8usize]); + ((&mut ctx)[8usize..8usize + 8usize]).copy_from_slice(&r2[0usize..8usize]); + let mut sw: [u32; 1] = [0u32; 1usize]; + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(8usize); + super::bignum256_32::from(ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_div(32u32); + let j: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_rem(32u32); + let tmp: u32 = b[i1 as usize]; + let bit: u32 = tmp.wrapping_shr(j) & 1u32; + let sw1: u32 = bit ^ (&sw)[0usize]; + krml::unroll_for!(8, "i0", 0u32, 1u32, { + let dummy: u32 = + 0u32.wrapping_sub(sw1) & ((&resM)[i0 as usize] ^ (&aM)[i0 as usize]); + (&mut resM)[i0 as usize] = (&resM)[i0 as usize] ^ dummy; + (&mut aM)[i0 as usize] = (&aM)[i0 as usize] ^ dummy + }); + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&(&aM)[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_mul(ctx_n0.1, mu, &aM_copy, &resM, &mut aM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + let mut aM_copy0: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy0)[0usize..8usize]).copy_from_slice(&(&resM)[0usize..8usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_sqr(ctx_n1.1, mu, &aM_copy0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (&mut sw)[0usize] = bit + } + let sw0: u32 = (&sw)[0usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let dummy: u32 = 0u32.wrapping_sub(sw0) & ((&resM)[i as usize] ^ (&aM)[i as usize]); + (&mut resM)[i as usize] = (&resM)[i as usize] ^ dummy; + (&mut aM)[i as usize] = (&aM)[i as usize] ^ dummy + }); + super::bignum256_32::from(n, mu, &resM, res) + } else { + let mut aM: [u32; 8] = [0u32; 8usize]; + super::bignum256_32::to(n, mu, r2, a, &mut aM); + let mut resM: [u32; 8] = [0u32; 8usize]; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let mut ctx: [u32; 16] = [0u32; 16usize]; + ((&mut ctx)[0usize..8usize]).copy_from_slice(&n[0usize..8usize]); + ((&mut ctx)[8usize..8usize + 8usize]).copy_from_slice(&r2[0usize..8usize]); + let mut table: [u32; 128] = [0u32; 128usize]; + let mut tmp: [u32; 8] = [0u32; 8usize]; + let t0: (&mut [u32], &mut [u32]) = table.split_at_mut(0usize); + let t1: (&mut [u32], &mut [u32]) = t0.1.split_at_mut(8usize); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(8usize); + super::bignum256_32::from(ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (t1.1[0usize..8usize]).copy_from_slice(&(&aM)[0usize..8usize]); + lowstar::ignore::ignore::<&[u32]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u32], &[u32]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(8u32) as usize); + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&t11.1[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(8u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(8u32) as usize + 8usize]) + .copy_from_slice(&(&tmp)[0usize..8usize]); + let t2: (&[u32], &[u32]) = + table.split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(8u32) as usize); + let mut aM_copy0: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy0)[0usize..8usize]).copy_from_slice(&(&aM)[0usize..8usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_mul(ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(8u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(8u32) as usize + 8usize]) + .copy_from_slice(&(&tmp)[0usize..8usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, i, 4u32); + ((&mut resM)[0usize..8usize]) + .copy_from_slice(&(&(&table)[0usize..] as &[u32])[0usize..8usize]); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u32 = fstar::uint32::eq_mask(bits_c, i0.wrapping_add(1u32)); + let res_j: (&[u32], &[u32]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(8u32) as usize); + krml::unroll_for!(8, "i1", 0u32, 1u32, { + let x: u32 = c & res_j.1[i1 as usize] | !c & (&resM)[i1 as usize]; + let os: (&mut [u32], &mut [u32]) = resM.split_at_mut(0usize); + os.1[i1 as usize] = x + }) + }) + } else { + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r20: (&[u32], &[u32]) = ctx_n0.1.split_at(8usize); + super::bignum256_32::from(ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut tmp0: [u32; 8] = [0u32; 8usize]; + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&(&resM)[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u32]>(&table); + ((&mut tmp0)[0usize..8usize]) + .copy_from_slice(&(&(&table)[0usize..] as &[u32])[0usize..8usize]); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u32 = fstar::uint32::eq_mask(bits_l, i0.wrapping_add(1u32)); + let res_j: (&[u32], &[u32]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(8u32) as usize); + krml::unroll_for!(8, "i1", 0u32, 1u32, { + let x: u32 = c & res_j.1[i1 as usize] | !c & (&tmp0)[i1 as usize]; + let os: (&mut [u32], &mut [u32]) = tmp0.split_at_mut(0usize); + os.1[i1 as usize] = x + }) + }); + let mut aM_copy: [u32; 8] = [0u32; 8usize]; + ((&mut aM_copy)[0usize..8usize]).copy_from_slice(&(&resM)[0usize..8usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum256_32::amont_mul(ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::bignum256_32::from(n, mu, &resM, res) + } +} + +#[inline] +fn exp_vartime(nBits: u32, n: &[u32], a: &[u32], bBits: u32, b: &[u32], res: &mut [u32]) { + let mut r2: [u32; 8] = [0u32; 8usize]; + super::bignum256_32::precompr2(nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::bignum256_32::exp_vartime_precomp(n, mu, &r2, a, bBits, b, res) +} + +#[inline] +fn exp_consttime(nBits: u32, n: &[u32], a: &[u32], bBits: u32, b: &[u32], res: &mut [u32]) { + let mut r2: [u32; 8] = [0u32; 8usize]; + super::bignum256_32::precompr2(nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::bignum256_32::exp_consttime_precomp(n, mu, &r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 256-bit bignum, bBits should be 256. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime(n: &[u32], a: &[u32], bBits: u32, b: &[u32], res: &mut [u32]) -> bool { + let is_valid_m: u32 = super::bignum256_32::exp_check(n, a, bBits, b); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(8u32, n)); + if is_valid_m == 0xFFFFFFFFu32 { + super::bignum256_32::exp_vartime(nBits, n, a, bBits, b, res) + } else { + (res[0usize..8usize]).copy_from_slice(&[0u32; 8usize]) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 256-bit bignum, bBits should be 256. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime(n: &[u32], a: &[u32], bBits: u32, b: &[u32], res: &mut [u32]) -> bool { + let is_valid_m: u32 = super::bignum256_32::exp_check(n, a, bBits, b); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(8u32, n)); + if is_valid_m == 0xFFFFFFFFu32 { + super::bignum256_32::exp_consttime(nBits, n, a, bBits, b, res) + } else { + (res[0usize..8usize]).copy_from_slice(&[0u32; 8usize]) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + + The function returns false if any of the following preconditions are violated, true otherwise. + • n % 2 = 1 + • 1 < n + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime(n: &[u32], a: &[u32], res: &mut [u32]) -> bool { + let mut one: [u32; 8] = [0u32; 8usize]; + ((&mut one)[0usize..8usize]).copy_from_slice(&[0u32; 8usize]); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + }); + let m1: u32 = (&acc)[0usize]; + let m00: u32 = m0 & m1; + let bn_zero: [u32; 8] = [0u32; 8usize]; + let mut mask: [u32; 1] = [0xFFFFFFFFu32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let uu____0: u32 = fstar::uint32::eq_mask(a[i as usize], (&bn_zero)[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + }); + let mask1: u32 = (&mask)[0usize]; + let res1: u32 = mask1; + let m10: u32 = res1; + let mut acc0: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + }); + let m2: u32 = (&acc0)[0usize]; + let is_valid_m: u32 = m00 & !m10 & m2; + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(8u32, n)); + if is_valid_m == 0xFFFFFFFFu32 { + let mut n2: [u32; 8] = [0u32; 8usize]; + let c0: u32 = lib::inttypes_intrinsics::sub_borrow_u32( + 0u32, + n[0usize], + 2u32, + &mut (&mut n2)[0usize..], + ); + let a1: (&[u32], &[u32]) = n.split_at(1usize); + let res10: (&mut [u32], &mut [u32]) = n2.split_at_mut(1usize); + let mut c: [u32; 1] = [c0; 1usize]; + { + let t1: u32 = a1.1[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res10.1.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1); + let t10: u32 = a1.1[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, 0u32, res_i0.1); + let t11: u32 = a1.1[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, 0u32, res_i1.1); + let t12: u32 = a1.1[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, 0u32, res_i2.1) + }; + krml::unroll_for!(3, "i", 4u32, 1u32, { + let t1: u32 = a1.1[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res10.1.split_at_mut(i as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1) + }); + let c1: u32 = (&c)[0usize]; + let c2: u32 = c1; + lowstar::ignore::ignore::(c2); + super::bignum256_32::exp_vartime(nBits, n, a, 256u32, &n2, res) + } else { + (res[0usize..8usize]).copy_from_slice(&[0u32; 8usize]) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Heap-allocate and initialize a montgomery context. + + The argument n is meant to be a 256-bit bignum, i.e. uint32_t[8]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n % 2 = 1 + • 1 < n + + The caller will need to call Hacl_Bignum256_mont_ctx_free on the return value + to avoid memory leaks. +*/ +pub fn mont_ctx_init(n: &[u32]) -> Box<[super::base::bn_mont_ctx_u32]> { + let mut r2: Box<[u32]> = vec![0u32; 8usize].into_boxed_slice(); + let mut n1: Box<[u32]> = vec![0u32; 8usize].into_boxed_slice(); + let r21: &mut [u32] = &mut r2; + let n11: &mut [u32] = &mut n1; + (n11[0usize..8usize]).copy_from_slice(&n[0usize..8usize]); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(8u32, n)); + super::bignum256_32::precompr2(nBits, n, r21); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + let res: super::base::bn_mont_ctx_u32 = super::base::bn_mont_ctx_u32 { + len: 8u32, + n: (*n11).into(), + mu, + r2: (*r21).into(), + }; + let buf: Box<[super::base::bn_mont_ctx_u32]> = vec![res].into_boxed_slice(); + buf +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be a 512-bit bignum, i.e. uint32_t[16]. + The outparam res is meant to be a 256-bit bignum, i.e. uint32_t[8]. + The argument k is a montgomery context obtained through Hacl_Bignum256_mont_ctx_init. +*/ +pub fn mod_precomp(k: &[super::base::bn_mont_ctx_u32], a: &[u32], res: &mut [u32]) { + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::bignum256_32::bn_slow_precomp(n, mu, r2, a, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + The argument k is a montgomery context obtained through Hacl_Bignum256_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 256-bit bignum, bBits should be 256. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::bignum256_32::exp_vartime_precomp(n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + The argument k is a montgomery context obtained through Hacl_Bignum256_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 256-bit bignum, bBits should be 256. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime_*. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::bignum256_32::exp_consttime_precomp(n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The argument a and the outparam res are meant to be 256-bit bignums, i.e. uint32_t[8]. + The argument k is a montgomery context obtained through Hacl_Bignum256_mont_ctx_init. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + res: &mut [u32], +) { + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + let mut n2: [u32; 8] = [0u32; 8usize]; + let c0: u32 = + lib::inttypes_intrinsics::sub_borrow_u32(0u32, n[0usize], 2u32, &mut (&mut n2)[0usize..]); + let a1: (&[u32], &[u32]) = n.split_at(1usize); + let res1: (&mut [u32], &mut [u32]) = n2.split_at_mut(1usize); + let mut c: [u32; 1] = [c0; 1usize]; + { + let t1: u32 = a1.1[4u32.wrapping_mul(0u32) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res1.1.split_at_mut(4u32.wrapping_mul(0u32) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1); + let t10: u32 = a1.1[4u32.wrapping_mul(0u32).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, 0u32, res_i0.1); + let t11: u32 = a1.1[4u32.wrapping_mul(0u32).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, 0u32, res_i1.1); + let t12: u32 = a1.1[4u32.wrapping_mul(0u32).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, 0u32, res_i2.1) + }; + krml::unroll_for!(3, "i", 4u32, 1u32, { + let t1: u32 = a1.1[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res1.1.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1) + }); + let c1: u32 = (&c)[0usize]; + let c2: u32 = c1; + lowstar::ignore::ignore::(c2); + super::bignum256_32::exp_vartime_precomp(n, mu, r2, a, 256u32, &n2, res) +} + +/** +Load a bid-endian bignum from memory. + + The argument b points to len bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_be(len: u32, b: &[u8]) -> Box<[u32]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) > 1073741823u32 { + [].into() + } else { + let mut res: Box<[u32]> = + vec![0u32; len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u32] = &mut res; + let res2: &mut [u32] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32); + let tmpLen: u32 = 4u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[tmpLen.wrapping_sub(len) as usize + ..tmpLen.wrapping_sub(len) as usize + len as usize]) + .copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..bnLen { + let u: u32 = lowstar::endianness::load32_be( + &(&tmp)[bnLen.wrapping_sub(i).wrapping_sub(1u32).wrapping_mul(4u32) as usize..], + ); + let x: u32 = u; + let os: (&mut [u32], &mut [u32]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Load a little-endian bignum from memory. + + The argument b points to len bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_le(len: u32, b: &[u8]) -> Box<[u32]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) > 1073741823u32 { + [].into() + } else { + let mut res: Box<[u32]> = + vec![0u32; len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u32] = &mut res; + let res2: &mut [u32] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32); + let tmpLen: u32 = 4u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) { + let bj: (&[u8], &[u8]) = tmp.split_at(i.wrapping_mul(4u32) as usize); + let u: u32 = lowstar::endianness::load32_le(bj.1); + let r1: u32 = u; + let x: u32 = r1; + let os: (&mut [u32], &mut [u32]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Serialize a bignum into big-endian memory. + + The argument b points to a 256-bit bignum. + The outparam res points to 32 bytes of valid memory. +*/ +pub fn bn_to_bytes_be(b: &[u32], res: &mut [u8]) { + let tmp: [u8; 32] = [0u8; 32usize]; + lowstar::ignore::ignore::<&[u8]>(&tmp); + krml::unroll_for!( + 8, + "i", + 0u32, + 1u32, + lowstar::endianness::store32_be( + &mut res[i.wrapping_mul(4u32) as usize..], + b[8u32.wrapping_sub(i).wrapping_sub(1u32) as usize] + ) + ) +} + +/** +Serialize a bignum into little-endian memory. + + The argument b points to a 256-bit bignum. + The outparam res points to 32 bytes of valid memory. +*/ +pub fn bn_to_bytes_le(b: &[u32], res: &mut [u8]) { + let tmp: [u8; 32] = [0u8; 32usize]; + lowstar::ignore::ignore::<&[u8]>(&tmp); + krml::unroll_for!( + 8, + "i", + 0u32, + 1u32, + lowstar::endianness::store32_le(&mut res[i.wrapping_mul(4u32) as usize..], b[i as usize]) + ) +} + +/** +Returns 2^32 - 1 if a < b, otherwise returns 0. + + The arguments a and b are meant to be 256-bit bignums, i.e. uint32_t[8]. +*/ +pub fn lt_mask(a: &[u32], b: &[u32]) -> u32 { + let mut acc: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], b[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], b[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + }); + (&acc)[0usize] +} + +/** +Returns 2^32 - 1 if a = b, otherwise returns 0. + + The arguments a and b are meant to be 256-bit bignums, i.e. uint32_t[8]. +*/ +pub fn eq_mask(a: &[u32], b: &[u32]) -> u32 { + let mut mask: [u32; 1] = [0xFFFFFFFFu32; 1usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let uu____0: u32 = fstar::uint32::eq_mask(a[i as usize], b[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + }); + let mask1: u32 = (&mask)[0usize]; + mask1 +} diff --git a/hacl-rs/src/bignum/bignum32.rs b/hacl-rs/src/bignum/bignum32.rs new file mode 100644 index 000000000..d6102384d --- /dev/null +++ b/hacl-rs/src/bignum/bignum32.rs @@ -0,0 +1,753 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use crate::fstar; +use crate::lowstar; +use crate::util as lib; + +pub type pbn_mont_ctx_u32<'a> = &'a [super::base::bn_mont_ctx_u32]; + +/** +Write `a + b mod 2 ^ (32 * len)` in `res`. + + This function returns the carry. + + @param[in] len Number of limbs. + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not + partially overlap the memory locations of `b` or `res`. May have exactly equal memory + location to `b` or `res`. + @param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not + partially overlap the memory locations of `a` or `res`. May have exactly + equal memory location to `a` or `res`. + @param[out] res Points to `len` number of limbs where the carry is written, i.e. `uint32_t[len]`. + Must not partially overlap the memory locations of `a` or `b`. May have + exactly equal memory location to `a` or `b`. +*/ +pub fn add(len: u32, a: &[u32], b: &[u32], res: &mut [u32]) -> u32 { + super::bignum_base::bn_add_eq_len_u32(len, a, b, res) +} + +/** +Write `a - b mod 2 ^ (32 * len)` in `res`. + + This functions returns the carry. + + @param[in] len Number of limbs. + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not + partially overlap the memory locations of `b` or `res`. May have exactly + equal memory location to `b` or `res`. + @param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not + partially overlap the memory locations of `a` or `res`. May have exactly + equal memory location to `a` or `res`. + @param[out] res Points to `len` number of limbs where the carry is written, i.e. `uint32_t[len]`. + Must not partially overlap the memory locations of `a` or `b`. May have + exactly equal memory location to `a` or `b`. +*/ +pub fn sub(len: u32, a: &[u32], b: &[u32], res: &mut [u32]) -> u32 { + super::bignum_base::bn_sub_eq_len_u32(len, a, b, res) +} + +/** +Write `(a + b) mod n` in `res`. + + @param[in] len Number of limbs. + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not + partially overlap the memory locations of `b` or `res`. May have exactly + equal memory location to `b` or `res`. + @param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not + partially overlap the memory locations of `a` or `res`. May have exactly + equal memory location to `a` or `res`. + @param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a`, `b`, and `res`. + @param[out] res Points to `len` number of limbs where the result is written, i.e. `uint32_t[len]`. + Must not partially overlap the memory locations of `a` or `b`. May have + exactly equal memory location to `a` or `b`. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `a < n` + - `b < n` +*/ +pub fn add_mod(len: u32, n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) { + let mut a_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let mut b_copy: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..len as usize]).copy_from_slice(&a[0usize..len as usize]); + ((&mut b_copy)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]); + super::base::bn_add_mod_n_u32(len, n, &a_copy, &b_copy, res) +} + +/** +Write `(a - b) mod n` in `res`. + + @param[in] len Number of limbs. + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not + partially overlap the memory locations of `b` or `res`. May have exactly + equal memory location to `b` or `res`. + @param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must not + partially overlap the memory locations of `a` or `res`. May have exactly + equal memory location to `a` or `res`. + @param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a`, `b`, and `res`. + @param[out] res Points to `len` number of limbs where the result is written, i.e. `uint32_t[len]`. + Must not partially overlap the memory locations of `a` or `b`. May have + exactly equal memory location to `a` or `b`. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `a < n` + - `b < n` +*/ +pub fn sub_mod(len: u32, n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) { + super::base::bn_sub_mod_n_u32(len, n, a, b, res) +} + +/** +Write `a * b` in `res`. + + @param[in] len Number of limbs. + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `b` and `res`. + @param[in] b Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `a` and `res`. + @param[out] res Points to `2*len` number of limbs where the result is written, i.e. `uint32_t[2*len]`. + Must be disjoint from the memory locations of `a` and `b`. +*/ +pub fn mul(len: u32, a: &[u32], b: &[u32], res: &mut [u32]) { + let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_mul_uint32(len, a, b, &mut tmp, res) +} + +/** +Write `a * a` in `res`. + + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `res`. + @param[out] res Points to `2*len` number of limbs where the result is written, i.e. `uint32_t[2*len]`. + Must be disjoint from the memory location of `a`. +*/ +pub fn sqr(len: u32, a: &[u32], res: &mut [u32]) { + let mut tmp: Box<[u32]> = vec![0u32; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_sqr_uint32(len, a, &mut tmp, res) +} + +#[inline] +fn bn_slow_precomp(len: u32, n: &[u32], mu: u32, r2: &[u32], a: &[u32], res: &mut [u32]) { + let mut a_mod: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let mut a1: Box<[u32]> = vec![0u32; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut a1)[0usize..len.wrapping_add(len) as usize]) + .copy_from_slice(&a[0usize..len.wrapping_add(len) as usize]); + super::base::bn_almost_mont_reduction_u32(len, n, mu, &mut a1, &mut a_mod); + super::base::bn_to_mont_u32(len, n, mu, r2, &a_mod, res) +} + +/** +Write `a mod n` in `res`. + + @param[in] a Points to `2*len` number of limbs, i.e. `uint32_t[2*len]`. Must be + disjoint from the memory location of `res`. + @param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `res`. + @param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a` and `n`. + + @return `false` if any precondition is violated, `true` otherwise. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `1 < n` + - `n % 2 = 1` +*/ +pub fn r#mod(len: u32, n: &[u32], a: &[u32], res: &mut [u32]) -> bool { + let mut one: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut one)[0usize..len as usize]) + .copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u32 = (&acc)[0usize]; + let is_valid_m: u32 = m0 & m1; + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n)); + if is_valid_m == 0xFFFFFFFFu32 { + let mut r2: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + super::base::bn_precomp_r2_mod_n_u32(len, nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::bignum32::bn_slow_precomp(len, n, mu, &r2, a, res) + } else { + (res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Write `a ^ b mod n` in `res`. + + This function is *NOT* constant-time on the argument `b`. See the + `mod_exp_consttime_*` functions for constant-time variants. + + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `n` and `res`. + @param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a` and `res`. + @param[in] b Points to a bignum of any size, with an upper bound of `bBits` number of + significant bits. Must be disjoint from the memory location of `res`. + @param[in] bBits An upper bound on the number of significant bits of `b`. + A tighter bound results in faster execution time. When in doubt, the number + of bits for the bignum size is always a safe default, e.g. if `b` is a 4096-bit + bignum, `bBits` should be `4096`. + @param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a`, `b`, and `n`. + + @return `false` if any preconditions are violated, `true` otherwise. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `n % 2 = 1` + - `1 < n` + - `b < pow2 bBits` + - `a < n` +*/ +pub fn mod_exp_vartime( + len: u32, + n: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) -> bool { + let is_valid_m: u32 = super::base::bn_check_mod_exp_u32(len, n, a, bBits, b); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n)); + if is_valid_m == 0xFFFFFFFFu32 { + super::base::bn_mod_exp_vartime_u32(len, nBits, n, a, bBits, b, res) + } else { + (res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Write `a ^ b mod n` in `res`. + + This function is constant-time over its argument `b`, at the cost of a slower + execution time than `mod_exp_vartime_*`. + + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `n` and `res`. + @param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a` and `res`. + @param[in] b Points to a bignum of any size, with an upper bound of `bBits` number of + significant bits. Must be disjoint from the memory location of `res`. + @param[in] bBits An upper bound on the number of significant bits of `b`. + A tighter bound results in faster execution time. When in doubt, the number + of bits for the bignum size is always a safe default, e.g. if `b` is a 4096-bit + bignum, `bBits` should be `4096`. + @param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a`, `b`, and `n`. + + @return `false` if any preconditions are violated, `true` otherwise. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `n % 2 = 1` + - `1 < n` + - `b < pow2 bBits` + - `a < n` +*/ +pub fn mod_exp_consttime( + len: u32, + n: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) -> bool { + let is_valid_m: u32 = super::base::bn_check_mod_exp_u32(len, n, a, bBits, b); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n)); + if is_valid_m == 0xFFFFFFFFu32 { + super::base::bn_mod_exp_consttime_u32(len, nBits, n, a, bBits, b, res) + } else { + (res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Write `a ^ (-1) mod n` in `res`. + + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `n` and `res`. + @param[in] n Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a` and `res`. + @param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `a` and `n`. + + @return `false` if any preconditions (except the precondition: `n` is a prime) + are violated, `true` otherwise. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `n` is a prime + - `n % 2 = 1` + - `1 < n` + - `0 < a` + - `a < n` +*/ +pub fn mod_inv_prime_vartime(len: u32, n: &[u32], a: &[u32], res: &mut [u32]) -> bool { + let mut one: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + ((&mut one)[0usize..len as usize]) + .copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u32 = (&acc)[0usize]; + let m00: u32 = m0 & m1; + let bn_zero: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let mut mask: [u32; 1] = [0xFFFFFFFFu32; 1usize]; + for i in 0u32..len { + let uu____0: u32 = fstar::uint32::eq_mask(a[i as usize], (&bn_zero)[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + } + let mask1: u32 = (&mask)[0usize]; + let res1: u32 = mask1; + let m10: u32 = res1; + let mut acc0: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let m2: u32 = (&acc0)[0usize]; + let is_valid_m: u32 = m00 & !m10 & m2; + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n)); + if is_valid_m == 0xFFFFFFFFu32 { + let mut n2: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let c0: u32 = lib::inttypes_intrinsics::sub_borrow_u32( + 0u32, + n[0usize], + 2u32, + &mut (&mut n2)[0usize..], + ); + let c: u32 = if 1u32 < len { + let a1: (&[u32], &[u32]) = n.split_at(1usize); + let res10: (&mut [u32], &mut [u32]) = n2.split_at_mut(1usize); + let mut c: [u32; 1] = [c0; 1usize]; + for i in 0u32..len.wrapping_sub(1u32).wrapping_div(4u32) { + let t1: u32 = a1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res10.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1); + let t10: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, 0u32, res_i0.1); + let t11: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, 0u32, res_i1.1); + let t12: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, 0u32, res_i2.1) + } + for i in + len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_mul(4u32)..len.wrapping_sub(1u32) + { + let t1: u32 = a1.1[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res10.1.split_at_mut(i as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1) + } + let c1: u32 = (&c)[0usize]; + c1 + } else { + c0 + }; + lowstar::ignore::ignore::(c); + super::base::bn_mod_exp_vartime_u32(len, nBits, n, a, 32u32.wrapping_mul(len), &n2, res) + } else { + (res[0usize..len as usize]).copy_from_slice(&vec![0u32; len as usize].into_boxed_slice()) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Heap-allocate and initialize a montgomery context. + + @param n Points to `len` number of limbs, i.e. `uint32_t[len]`. + + @return A pointer to an allocated and initialized Montgomery context is returned. + Clients will need to call `Hacl_Bignum32_mont_ctx_free` on the return value to + avoid memory leaks. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `n % 2 = 1` + - `1 < n` +*/ +pub fn mont_ctx_init(len: u32, n: &[u32]) -> Box<[super::base::bn_mont_ctx_u32]> { + let mut r2: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let mut n1: Box<[u32]> = vec![0u32; len as usize].into_boxed_slice(); + let r21: &mut [u32] = &mut r2; + let n11: &mut [u32] = &mut n1; + (n11[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(len, n)); + super::base::bn_precomp_r2_mod_n_u32(len, nBits, n, r21); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + let res: super::base::bn_mont_ctx_u32 = super::base::bn_mont_ctx_u32 { + len, + n: (*n11).into(), + mu, + r2: (*r21).into(), + }; + let buf: Box<[super::base::bn_mont_ctx_u32]> = vec![res].into_boxed_slice(); + buf +} + +/** +Write `a mod n` in `res`. + + @param[in] k Points to a Montgomery context obtained from `Hacl_Bignum32_mont_ctx_init`. + @param[in] a Points to `2*len` number of limbs, i.e. `uint32_t[2*len]`. Must be + disjoint from the memory location of `res`. + @param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `a`. +*/ +pub fn mod_precomp(k: &[super::base::bn_mont_ctx_u32], a: &[u32], res: &mut [u32]) { + let len1: u32 = (k[0usize]).len; + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::bignum32::bn_slow_precomp(len1, n, mu, r2, a, res) +} + +/** +Write `a ^ b mod n` in `res`. + + This function is *NOT* constant-time on the argument `b`. See the + `mod_exp_consttime_*` functions for constant-time variants. + + @param[in] k Points to a Montgomery context obtained from `Hacl_Bignum32_mont_ctx_init`. + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `res`. + @param[in] b Points to a bignum of any size, with an upper bound of `bBits` number of + significant bits. Must be disjoint from the memory location of `res`. + @param[in] bBits An upper bound on the number of significant bits of `b`. + A tighter bound results in faster execution time. When in doubt, the number + of bits for the bignum size is always a safe default, e.g. if `b` is a 4096-bit + bignum, `bBits` should be `4096`. + @param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a` and `b`. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `b < pow2 bBits` + - `a < n` +*/ +pub fn mod_exp_vartime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + let len1: u32 = (k[0usize]).len; + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::base::bn_mod_exp_vartime_precomp_u32(len1, n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + This function is constant-time over its argument b, at the cost of a slower + execution time than `mod_exp_vartime_*`. + + @param[in] k Points to a Montgomery context obtained from `Hacl_Bignum32_mont_ctx_init`. + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `res`. + @param[in] b Points to a bignum of any size, with an upper bound of `bBits` number of + significant bits. Must be disjoint from the memory location of `res`. + @param[in] bBits An upper bound on the number of significant bits of `b`. + A tighter bound results in faster execution time. When in doubt, the number + of bits for the bignum size is always a safe default, e.g. if `b` is a 4096-bit + bignum, `bBits` should be `4096`. + @param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory locations of `a` and `b`. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `b < pow2 bBits` + - `a < n` +*/ +pub fn mod_exp_consttime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + let len1: u32 = (k[0usize]).len; + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::base::bn_mod_exp_consttime_precomp_u32(len1, n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ (-1) mod n` in `res`. + + @param[in] k Points to a Montgomery context obtained through `Hacl_Bignum32_mont_ctx_init`. + @param[in] a Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `res`. + @param[out] res Points to `len` number of limbs, i.e. `uint32_t[len]`. Must be + disjoint from the memory location of `a`. + + @pre Before calling this function, the caller will need to ensure that the following + preconditions are observed: + - `n` is a prime + - `0 < a` + - `a < n` +*/ +pub fn mod_inv_prime_vartime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + res: &mut [u32], +) { + let len1: u32 = (k[0usize]).len; + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + let mut n2: Box<[u32]> = vec![0u32; len1 as usize].into_boxed_slice(); + let c0: u32 = + lib::inttypes_intrinsics::sub_borrow_u32(0u32, n[0usize], 2u32, &mut (&mut n2)[0usize..]); + let c: u32 = if 1u32 < len1 { + let a1: (&[u32], &[u32]) = n.split_at(1usize); + let res1: (&mut [u32], &mut [u32]) = n2.split_at_mut(1usize); + let mut c: [u32; 1] = [c0; 1usize]; + for i in 0u32..len1.wrapping_sub(1u32).wrapping_div(4u32) { + let t1: u32 = a1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1); + let t10: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, 0u32, res_i0.1); + let t11: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, 0u32, res_i1.1); + let t12: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, 0u32, res_i2.1) + } + for i in len1 + .wrapping_sub(1u32) + .wrapping_div(4u32) + .wrapping_mul(4u32)..len1.wrapping_sub(1u32) + { + let t1: u32 = a1.1[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res1.1.split_at_mut(i as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1) + } + let c1: u32 = (&c)[0usize]; + c1 + } else { + c0 + }; + lowstar::ignore::ignore::(c); + super::base::bn_mod_exp_vartime_precomp_u32( + len1, + n, + mu, + r2, + a, + 32u32.wrapping_mul(len1), + &n2, + res, + ) +} + +/** +Load a bid-endian bignum from memory. + + @param len Size of `b` as number of bytes. + @param b Points to `len` number of bytes, i.e. `uint8_t[len]`. + + @return A heap-allocated bignum of size sufficient to hold the result of + loading `b`. Otherwise, `NULL`, if either the allocation failed, or the amount + of required memory would exceed 4GB. Clients must `free(3)` any non-null return + value to avoid memory leaks. +*/ +pub fn new_bn_from_bytes_be(len: u32, b: &[u8]) -> Box<[u32]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) > 1073741823u32 { + [].into() + } else { + let mut res: Box<[u32]> = + vec![0u32; len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u32] = &mut res; + let res2: &mut [u32] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32); + let tmpLen: u32 = 4u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[tmpLen.wrapping_sub(len) as usize + ..tmpLen.wrapping_sub(len) as usize + len as usize]) + .copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..bnLen { + let u: u32 = lowstar::endianness::load32_be( + &(&tmp)[bnLen.wrapping_sub(i).wrapping_sub(1u32).wrapping_mul(4u32) as usize..], + ); + let x: u32 = u; + let os: (&mut [u32], &mut [u32]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Load a little-endian bignum from memory. + + @param len Size of `b` as number of bytes. + @param b Points to `len` number of bytes, i.e. `uint8_t[len]`. + + @return A heap-allocated bignum of size sufficient to hold the result of + loading `b`. Otherwise, `NULL`, if either the allocation failed, or the amount + of required memory would exceed 4GB. Clients must `free(3)` any non-null return + value to avoid memory leaks. +*/ +pub fn new_bn_from_bytes_le(len: u32, b: &[u8]) -> Box<[u32]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) > 1073741823u32 { + [].into() + } else { + let mut res: Box<[u32]> = + vec![0u32; len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u32] = &mut res; + let res2: &mut [u32] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32); + let tmpLen: u32 = 4u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) { + let bj: (&[u8], &[u8]) = tmp.split_at(i.wrapping_mul(4u32) as usize); + let u: u32 = lowstar::endianness::load32_le(bj.1); + let r1: u32 = u; + let x: u32 = r1; + let os: (&mut [u32], &mut [u32]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Serialize a bignum into big-endian memory. + + @param[in] len Size of `b` as number of bytes. + @param[in] b Points to a bignum of `ceil(len/4)` size. Must be disjoint from + the memory location of `res`. + @param[out] res Points to `len` number of bytes, i.e. `uint8_t[len]`. Must be + disjoint from the memory location of `b`. +*/ +pub fn bn_to_bytes_be(len: u32, b: &[u32], res: &mut [u8]) { + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32); + let tmpLen: u32 = 4u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + for i in 0u32..bnLen { + lowstar::endianness::store32_be( + &mut (&mut tmp)[i.wrapping_mul(4u32) as usize..], + b[bnLen.wrapping_sub(i).wrapping_sub(1u32) as usize], + ) + } + (res[0usize..len as usize]) + .copy_from_slice(&(&(&tmp)[tmpLen.wrapping_sub(len) as usize..])[0usize..len as usize]) +} + +/** +Serialize a bignum into little-endian memory. + + @param[in] len Size of `b` as number of bytes. + @param[in] b Points to a bignum of `ceil(len/4)` size. Must be disjoint from + the memory location of `res`. + @param[out] res Points to `len` number of bytes, i.e. `uint8_t[len]`. Must be + disjoint from the memory location of `b`. +*/ +pub fn bn_to_bytes_le(len: u32, b: &[u32], res: &mut [u8]) { + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32); + let tmpLen: u32 = 4u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + for i in 0u32..bnLen { + lowstar::endianness::store32_le( + &mut (&mut tmp)[i.wrapping_mul(4u32) as usize..], + b[i as usize], + ) + } + (res[0usize..len as usize]).copy_from_slice(&(&(&tmp)[0usize..])[0usize..len as usize]) +} + +/** +Returns 2^32 - 1 if a < b, otherwise returns 0. + + @param len Number of limbs. + @param a Points to `len` number of limbs, i.e. `uint32_t[len]`. + @param b Points to `len` number of limbs, i.e. `uint32_t[len]`. + + @return `2^32 - 1` if `a < b`, otherwise, `0`. +*/ +pub fn lt_mask(len: u32, a: &[u32], b: &[u32]) -> u32 { + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], b[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], b[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + (&acc)[0usize] +} + +/** +Returns 2^32 - 1 if a = b, otherwise returns 0. + + @param len Number of limbs. + @param a Points to `len` number of limbs, i.e. `uint32_t[len]`. + @param b Points to `len` number of limbs, i.e. `uint32_t[len]`. + + @return `2^32 - 1` if a = b, otherwise, `0`. +*/ +pub fn eq_mask(len: u32, a: &[u32], b: &[u32]) -> u32 { + let mut mask: [u32; 1] = [0xFFFFFFFFu32; 1usize]; + for i in 0u32..len { + let uu____0: u32 = fstar::uint32::eq_mask(a[i as usize], b[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + } + let mask1: u32 = (&mask)[0usize]; + mask1 +} diff --git a/hacl-rs/src/bignum/bignum4096.rs b/hacl-rs/src/bignum/bignum4096.rs new file mode 100644 index 000000000..d15943d5c --- /dev/null +++ b/hacl-rs/src/bignum/bignum4096.rs @@ -0,0 +1,1247 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_macros as krml; + +use crate::fstar; +use crate::lowstar; +use crate::util as lib; + +/** +Write `a + b mod 2^4096` in `res`. + + This functions returns the carry. + + The arguments a, b and res are meant to be 4096-bit bignums, i.e. uint64_t[64] +*/ +pub fn add(a: &[u64], b: &[u64], res: &mut [u64]) -> u64 { + let mut c: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i", 0u32, 1u32, { + let t1: u64 = a[4u32.wrapping_mul(i) as usize]; + let t2: u64 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t12, t22, res_i2.1) + }); + (&c)[0usize] +} + +/** +Write `a - b mod 2^4096` in `res`. + + This functions returns the carry. + + The arguments a, b and res are meant to be 4096-bit bignums, i.e. uint64_t[64] +*/ +pub fn sub(a: &[u64], b: &[u64], res: &mut [u64]) -> u64 { + let mut c: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i", 0u32, 1u32, { + let t1: u64 = a[4u32.wrapping_mul(i) as usize]; + let t2: u64 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, t22, res_i2.1) + }); + (&c)[0usize] +} + +/** +Write `(a + b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn add_mod(n: &[u64], a: &[u64], b: &[u64], res: &mut [u64]) { + let mut c: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i", 0u32, 1u32, { + let t1: u64 = a[4u32.wrapping_mul(i) as usize]; + let t2: u64 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t12, t22, res_i2.1) + }); + let c0: u64 = (&c)[0usize]; + let mut tmp: [u64; 64] = [0u64; 64usize]; + let mut c1: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i", 0u32, 1u32, { + let t1: u64 = res[4u32.wrapping_mul(i) as usize]; + let t2: u64 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u64 = (&c1)[0usize]; + let c2: u64 = c0.wrapping_sub(c10); + for i in 0u32..64u32 { + let x: u64 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +Write `(a - b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn sub_mod(n: &[u64], a: &[u64], b: &[u64], res: &mut [u64]) { + let mut c: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i", 0u32, 1u32, { + let t1: u64 = a[4u32.wrapping_mul(i) as usize]; + let t2: u64 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, t22, res_i2.1) + }); + let c0: u64 = (&c)[0usize]; + let mut tmp: [u64; 64] = [0u64; 64usize]; + let mut c1: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i", 0u32, 1u32, { + let t1: u64 = res[4u32.wrapping_mul(i) as usize]; + let t2: u64 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u64 = (&c1)[0usize]; + lowstar::ignore::ignore::(c10); + let c2: u64 = 0u64.wrapping_sub(c0); + for i in 0u32..64u32 { + let x: u64 = c2 & (&tmp)[i as usize] | !c2 & res[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +Write `a * b` in `res`. + + The arguments a and b are meant to be 4096-bit bignums, i.e. uint64_t[64]. + The outparam res is meant to be a 8192-bit bignum, i.e. uint64_t[128]. +*/ +pub fn mul(a: &[u64], b: &[u64], res: &mut [u64]) { + let mut tmp: [u64; 256] = [0u64; 256usize]; + super::base::bn_karatsuba_mul_uint64(64u32, a, b, &mut tmp, res) +} + +/** +Write `a * a` in `res`. + + The argument a is meant to be a 4096-bit bignum, i.e. uint64_t[64]. + The outparam res is meant to be a 8192-bit bignum, i.e. uint64_t[128]. +*/ +pub fn sqr(a: &[u64], res: &mut [u64]) { + let mut tmp: [u64; 256] = [0u64; 256usize]; + super::base::bn_karatsuba_sqr_uint64(64u32, a, &mut tmp, res) +} + +#[inline] +fn precompr2(nBits: u32, n: &[u64], res: &mut [u64]) { + (res[0usize..64usize]).copy_from_slice(&[0u64; 64usize]); + let i: u32 = nBits.wrapping_div(64u32); + let j: u32 = nBits.wrapping_rem(64u32); + res[i as usize] |= 1u64.wrapping_shl(j); + for _i in 0u32..8192u32.wrapping_sub(nBits) { + let mut a_copy: [u64; 64] = [0u64; 64usize]; + let mut b_copy: [u64; 64] = [0u64; 64usize]; + ((&mut a_copy)[0usize..64usize]).copy_from_slice(&res[0usize..64usize]); + ((&mut b_copy)[0usize..64usize]).copy_from_slice(&res[0usize..64usize]); + super::bignum4096::add_mod(n, &a_copy, &b_copy, res) + } +} + +#[inline] +fn reduction(n: &[u64], nInv: u64, c: &mut [u64], res: &mut [u64]) { + let mut c0: [u64; 1] = [0u64; 1usize]; + for i in 0u32..64u32 { + let qj: u64 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize); + let mut c1: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i0", 0u32, 1u32, { + let a_i: u64 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u64 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u64 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u64 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, qj, (&c1)[0usize], res_i2.1) + }); + let r: u64 = (&c1)[0usize]; + let c10: u64 = r; + let res_j0: u64 = c[64u32.wrapping_add(i) as usize]; + let resb: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize + 64usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c0)[0usize], c10, res_j0, resb.1) + } + (res[0usize..64usize]).copy_from_slice(&(&c[64usize..])[0usize..64usize]); + let c00: u64 = (&c0)[0usize]; + let mut tmp: [u64; 64] = [0u64; 64usize]; + let mut c1: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i", 0u32, 1u32, { + let t1: u64 = res[4u32.wrapping_mul(i) as usize]; + let t2: u64 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t1, t2, res_i.1); + let t10: u64 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t10, t20, res_i0.1); + let t11: u64 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t11, t21, res_i1.1); + let t12: u64 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u64 = (&c1)[0usize]; + let c2: u64 = c00.wrapping_sub(c10); + for i in 0u32..64u32 { + let x: u64 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +#[inline] +fn to(n: &[u64], nInv: u64, r2: &[u64], a: &[u64], aM: &mut [u64]) { + let mut c: [u64; 128] = [0u64; 128usize]; + super::bignum4096::mul(a, r2, &mut c); + super::bignum4096::reduction(n, nInv, &mut c, aM) +} + +#[inline] +fn from(n: &[u64], nInv_u64: u64, aM: &[u64], a: &mut [u64]) { + let mut tmp: [u64; 128] = [0u64; 128usize]; + ((&mut tmp)[0usize..64usize]).copy_from_slice(&aM[0usize..64usize]); + super::bignum4096::reduction(n, nInv_u64, &mut tmp, a) +} + +#[inline] +fn areduction(n: &[u64], nInv: u64, c: &mut [u64], res: &mut [u64]) { + let mut c0: [u64; 1] = [0u64; 1usize]; + for i in 0u32..64u32 { + let qj: u64 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize); + let mut c1: [u64; 1] = [0u64; 1usize]; + krml::unroll_for!(16, "i0", 0u32, 1u32, { + let a_i: u64 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u64 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u64 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u64 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, qj, (&c1)[0usize], res_i2.1) + }); + let r: u64 = (&c1)[0usize]; + let c10: u64 = r; + let res_j0: u64 = c[64u32.wrapping_add(i) as usize]; + let resb: (&mut [u64], &mut [u64]) = c.split_at_mut(i as usize + 64usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c0)[0usize], c10, res_j0, resb.1) + } + (res[0usize..64usize]).copy_from_slice(&(&c[64usize..])[0usize..64usize]); + let c00: u64 = (&c0)[0usize]; + let mut tmp: [u64; 64] = [0u64; 64usize]; + let c1: u64 = super::bignum4096::sub(res, n, &mut tmp); + lowstar::ignore::ignore::(c1); + let m: u64 = 0u64.wrapping_sub(c00); + for i in 0u32..64u32 { + let x: u64 = m & (&tmp)[i as usize] | !m & res[i as usize]; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +#[inline] +fn amont_mul(n: &[u64], nInv_u64: u64, aM: &[u64], bM: &[u64], resM: &mut [u64]) { + let mut c: [u64; 128] = [0u64; 128usize]; + super::bignum4096::mul(aM, bM, &mut c); + super::bignum4096::areduction(n, nInv_u64, &mut c, resM) +} + +#[inline] +fn amont_sqr(n: &[u64], nInv_u64: u64, aM: &[u64], resM: &mut [u64]) { + let mut c: [u64; 128] = [0u64; 128usize]; + super::bignum4096::sqr(aM, &mut c); + super::bignum4096::areduction(n, nInv_u64, &mut c, resM) +} + +#[inline] +fn bn_slow_precomp(n: &[u64], mu: u64, r2: &[u64], a: &[u64], res: &mut [u64]) { + let mut a_mod: [u64; 64] = [0u64; 64usize]; + let mut a1: [u64; 128] = [0u64; 128usize]; + ((&mut a1)[0usize..128usize]).copy_from_slice(&a[0usize..128usize]); + super::bignum4096::areduction(n, mu, &mut a1, &mut a_mod); + super::bignum4096::to(n, mu, r2, &a_mod, res) +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be a 8192-bit bignum, i.e. uint64_t[128]. + The argument n and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • 1 < n + • n % 2 = 1 +*/ +pub fn r#mod(n: &[u64], a: &[u64], res: &mut [u64]) -> bool { + let mut one: [u64; 64] = [0u64; 64usize]; + ((&mut one)[0usize..64usize]).copy_from_slice(&[0u64; 64usize]); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..64u32 { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u64 = (&acc)[0usize]; + let is_valid_m: u64 = m0 & m1; + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(64u32, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + let mut r2: [u64; 64] = [0u64; 64usize]; + super::bignum4096::precompr2(nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::bignum4096::bn_slow_precomp(n, mu, &r2, a, res) + } else { + (res[0usize..64usize]).copy_from_slice(&[0u64; 64usize]) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +fn exp_check(n: &[u64], a: &[u64], bBits: u32, b: &[u64]) -> u64 { + let mut one: [u64; 64] = [0u64; 64usize]; + ((&mut one)[0usize..64usize]).copy_from_slice(&[0u64; 64usize]); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..64u32 { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u64 = (&acc)[0usize]; + let m00: u64 = m0 & m1; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let m10: u64 = if bBits < 64u32.wrapping_mul(bLen) { + let mut b2: Box<[u64]> = vec![0u64; bLen as usize].into_boxed_slice(); + let i: u32 = bBits.wrapping_div(64u32); + let j: u32 = bBits.wrapping_rem(64u32); + (&mut b2)[i as usize] = (&b2)[i as usize] | 1u64.wrapping_shl(j); + let mut acc0: [u64; 1] = [0u64; 1usize]; + for i0 in 0u32..bLen { + let beq: u64 = fstar::uint64::eq_mask(b[i0 as usize], (&b2)[i0 as usize]); + let blt: u64 = !fstar::uint64::gte_mask(b[i0 as usize], (&b2)[i0 as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let res: u64 = (&acc0)[0usize]; + res + } else { + 0xFFFFFFFFFFFFFFFFu64 + }; + let mut acc0: [u64; 1] = [0u64; 1usize]; + for i in 0u32..64u32 { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let m2: u64 = (&acc0)[0usize]; + let m: u64 = m10 & m2; + m00 & m +} + +#[inline] +fn exp_vartime_precomp( + n: &[u64], + mu: u64, + r2: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + if bBits < 200u32 { + let mut aM: [u64; 64] = [0u64; 64usize]; + super::bignum4096::to(n, mu, r2, a, &mut aM); + let mut resM: [u64; 64] = [0u64; 64usize]; + let mut ctx: [u64; 128] = [0u64; 128usize]; + ((&mut ctx)[0usize..64usize]).copy_from_slice(&n[0usize..64usize]); + ((&mut ctx)[64usize..64usize + 64usize]).copy_from_slice(&r2[0usize..64usize]); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(64usize); + super::bignum4096::from(ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = i.wrapping_div(64u32); + let j: u32 = i.wrapping_rem(64u32); + let tmp: u64 = b[i1 as usize]; + let bit: u64 = tmp.wrapping_shr(j) & 1u64; + if bit != 0u64 { + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&(&resM)[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_mul(ctx_n0.1, mu, &aM_copy, &aM, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&(&aM)[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut aM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::bignum4096::from(n, mu, &resM, res) + } else { + let mut aM: [u64; 64] = [0u64; 64usize]; + super::bignum4096::to(n, mu, r2, a, &mut aM); + let mut resM: [u64; 64] = [0u64; 64usize]; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let mut ctx: [u64; 128] = [0u64; 128usize]; + ((&mut ctx)[0usize..64usize]).copy_from_slice(&n[0usize..64usize]); + ((&mut ctx)[64usize..64usize + 64usize]).copy_from_slice(&r2[0usize..64usize]); + let mut table: [u64; 1024] = [0u64; 1024usize]; + let mut tmp: [u64; 64] = [0u64; 64usize]; + let t0: (&mut [u64], &mut [u64]) = table.split_at_mut(0usize); + let t1: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(64usize); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(64usize); + super::bignum4096::from(ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (t1.1[0usize..64usize]).copy_from_slice(&(&aM)[0usize..64usize]); + lowstar::ignore::ignore::<&[u64]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u64], &[u64]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(64u32) as usize); + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&t11.1[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(64u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(64u32) as usize + 64usize]) + .copy_from_slice(&(&tmp)[0usize..64usize]); + let t2: (&[u64], &[u64]) = table + .split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(64u32) as usize); + let mut aM_copy0: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy0)[0usize..64usize]).copy_from_slice(&(&aM)[0usize..64usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_mul(ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(64u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(64u32) as usize + 64usize]) + .copy_from_slice(&(&tmp)[0usize..64usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, i, 4u32); + let bits_l32: u32 = bits_c as u32; + let a_bits_l: (&[u64], &[u64]) = table.split_at(bits_l32.wrapping_mul(64u32) as usize); + ((&mut resM)[0usize..64usize]).copy_from_slice(&a_bits_l.1[0usize..64usize]) + } else { + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r20: (&[u64], &[u64]) = ctx_n0.1.split_at(64usize); + super::bignum4096::from(ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut tmp0: [u64; 64] = [0u64; 64usize]; + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&(&resM)[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u64]>(&table); + let bits_l32: u32 = bits_l as u32; + let a_bits_l: (&[u64], &[u64]) = table.split_at(bits_l32.wrapping_mul(64u32) as usize); + ((&mut tmp0)[0usize..64usize]).copy_from_slice(&a_bits_l.1[0usize..64usize]); + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&(&resM)[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_mul(ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::bignum4096::from(n, mu, &resM, res) + } +} + +#[inline] +fn exp_consttime_precomp( + n: &[u64], + mu: u64, + r2: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + if bBits < 200u32 { + let mut aM: [u64; 64] = [0u64; 64usize]; + super::bignum4096::to(n, mu, r2, a, &mut aM); + let mut resM: [u64; 64] = [0u64; 64usize]; + let mut ctx: [u64; 128] = [0u64; 128usize]; + ((&mut ctx)[0usize..64usize]).copy_from_slice(&n[0usize..64usize]); + ((&mut ctx)[64usize..64usize + 64usize]).copy_from_slice(&r2[0usize..64usize]); + let mut sw: [u64; 1] = [0u64; 1usize]; + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(64usize); + super::bignum4096::from(ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_div(64u32); + let j: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_rem(64u32); + let tmp: u64 = b[i1 as usize]; + let bit: u64 = tmp.wrapping_shr(j) & 1u64; + let sw1: u64 = bit ^ (&sw)[0usize]; + for i0 in 0u32..64u32 { + let dummy: u64 = + 0u64.wrapping_sub(sw1) & ((&resM)[i0 as usize] ^ (&aM)[i0 as usize]); + (&mut resM)[i0 as usize] = (&resM)[i0 as usize] ^ dummy; + (&mut aM)[i0 as usize] = (&aM)[i0 as usize] ^ dummy + } + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&(&aM)[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_mul(ctx_n0.1, mu, &aM_copy, &resM, &mut aM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + let mut aM_copy0: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy0)[0usize..64usize]).copy_from_slice(&(&resM)[0usize..64usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_sqr(ctx_n1.1, mu, &aM_copy0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (&mut sw)[0usize] = bit + } + let sw0: u64 = (&sw)[0usize]; + for i in 0u32..64u32 { + let dummy: u64 = 0u64.wrapping_sub(sw0) & ((&resM)[i as usize] ^ (&aM)[i as usize]); + (&mut resM)[i as usize] = (&resM)[i as usize] ^ dummy; + (&mut aM)[i as usize] = (&aM)[i as usize] ^ dummy + } + super::bignum4096::from(n, mu, &resM, res) + } else { + let mut aM: [u64; 64] = [0u64; 64usize]; + super::bignum4096::to(n, mu, r2, a, &mut aM); + let mut resM: [u64; 64] = [0u64; 64usize]; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(64u32) + .wrapping_add(1u32) + }; + let mut ctx: [u64; 128] = [0u64; 128usize]; + ((&mut ctx)[0usize..64usize]).copy_from_slice(&n[0usize..64usize]); + ((&mut ctx)[64usize..64usize + 64usize]).copy_from_slice(&r2[0usize..64usize]); + let mut table: [u64; 1024] = [0u64; 1024usize]; + let mut tmp: [u64; 64] = [0u64; 64usize]; + let t0: (&mut [u64], &mut [u64]) = table.split_at_mut(0usize); + let t1: (&mut [u64], &mut [u64]) = t0.1.split_at_mut(64usize); + let ctx_n: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r2: (&[u64], &[u64]) = ctx_n.1.split_at(64usize); + super::bignum4096::from(ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u64]>(&ctx); + (t1.1[0usize..64usize]).copy_from_slice(&(&aM)[0usize..64usize]); + lowstar::ignore::ignore::<&[u64]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u64], &[u64]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(64u32) as usize); + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&t11.1[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(64u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(64u32) as usize + 64usize]) + .copy_from_slice(&(&tmp)[0usize..64usize]); + let t2: (&[u64], &[u64]) = table + .split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(64u32) as usize); + let mut aM_copy0: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy0)[0usize..64usize]).copy_from_slice(&(&aM)[0usize..64usize]); + let ctx_n1: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_mul(ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u64]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(64u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(64u32) as usize + 64usize]) + .copy_from_slice(&(&tmp)[0usize..64usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, i, 4u32); + ((&mut resM)[0usize..64usize]) + .copy_from_slice(&(&(&table)[0usize..] as &[u64])[0usize..64usize]); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u64 = fstar::uint64::eq_mask(bits_c, i0.wrapping_add(1u32) as u64); + let res_j: (&[u64], &[u64]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(64u32) as usize); + for i1 in 0u32..64u32 { + let x: u64 = c & res_j.1[i1 as usize] | !c & (&resM)[i1 as usize]; + let os: (&mut [u64], &mut [u64]) = resM.split_at_mut(0usize); + os.1[i1 as usize] = x + } + }) + } else { + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + let ctx_r20: (&[u64], &[u64]) = ctx_n0.1.split_at(64usize); + super::bignum4096::from(ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }; + let mut tmp0: [u64; 64] = [0u64; 64usize]; + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&(&resM)[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u64 = super::bignum_base::bn_get_bits_u64(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u64]>(&table); + ((&mut tmp0)[0usize..64usize]) + .copy_from_slice(&(&(&table)[0usize..] as &[u64])[0usize..64usize]); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u64 = fstar::uint64::eq_mask(bits_l, i0.wrapping_add(1u32) as u64); + let res_j: (&[u64], &[u64]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(64u32) as usize); + for i1 in 0u32..64u32 { + let x: u64 = c & res_j.1[i1 as usize] | !c & (&tmp0)[i1 as usize]; + let os: (&mut [u64], &mut [u64]) = tmp0.split_at_mut(0usize); + os.1[i1 as usize] = x + } + }); + let mut aM_copy: [u64; 64] = [0u64; 64usize]; + ((&mut aM_copy)[0usize..64usize]).copy_from_slice(&(&resM)[0usize..64usize]); + let ctx_n0: (&[u64], &[u64]) = ctx.split_at(0usize); + super::bignum4096::amont_mul(ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u64]>(&ctx) + } + super::bignum4096::from(n, mu, &resM, res) + } +} + +#[inline] +fn exp_vartime(nBits: u32, n: &[u64], a: &[u64], bBits: u32, b: &[u64], res: &mut [u64]) { + let mut r2: [u64; 64] = [0u64; 64usize]; + super::bignum4096::precompr2(nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::bignum4096::exp_vartime_precomp(n, mu, &r2, a, bBits, b, res) +} + +#[inline] +fn exp_consttime(nBits: u32, n: &[u64], a: &[u64], bBits: u32, b: &[u64], res: &mut [u64]) { + let mut r2: [u64; 64] = [0u64; 64usize]; + super::bignum4096::precompr2(nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::bignum4096::exp_consttime_precomp(n, mu, &r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime(n: &[u64], a: &[u64], bBits: u32, b: &[u64], res: &mut [u64]) -> bool { + let is_valid_m: u64 = super::bignum4096::exp_check(n, a, bBits, b); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(64u32, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + super::bignum4096::exp_vartime(nBits, n, a, bBits, b, res) + } else { + (res[0usize..64usize]).copy_from_slice(&[0u64; 64usize]) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime(n: &[u64], a: &[u64], bBits: u32, b: &[u64], res: &mut [u64]) -> bool { + let is_valid_m: u64 = super::bignum4096::exp_check(n, a, bBits, b); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(64u32, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + super::bignum4096::exp_consttime(nBits, n, a, bBits, b, res) + } else { + (res[0usize..64usize]).copy_from_slice(&[0u64; 64usize]) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + + The function returns false if any of the following preconditions are violated, true otherwise. + • n % 2 = 1 + • 1 < n + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime(n: &[u64], a: &[u64], res: &mut [u64]) -> bool { + let mut one: [u64; 64] = [0u64; 64usize]; + ((&mut one)[0usize..64usize]).copy_from_slice(&[0u64; 64usize]); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..64u32 { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u64 = (&acc)[0usize]; + let m00: u64 = m0 & m1; + let bn_zero: [u64; 64] = [0u64; 64usize]; + let mut mask: [u64; 1] = [0xFFFFFFFFFFFFFFFFu64; 1usize]; + for i in 0u32..64u32 { + let uu____0: u64 = fstar::uint64::eq_mask(a[i as usize], (&bn_zero)[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + } + let mask1: u64 = (&mask)[0usize]; + let res1: u64 = mask1; + let m10: u64 = res1; + let mut acc0: [u64; 1] = [0u64; 1usize]; + for i in 0u32..64u32 { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let m2: u64 = (&acc0)[0usize]; + let is_valid_m: u64 = m00 & !m10 & m2; + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(64u32, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + let mut n2: [u64; 64] = [0u64; 64usize]; + let c0: u64 = lib::inttypes_intrinsics::sub_borrow_u64( + 0u64, + n[0usize], + 2u64, + &mut (&mut n2)[0usize..], + ); + let a1: (&[u64], &[u64]) = n.split_at(1usize); + let res10: (&mut [u64], &mut [u64]) = n2.split_at_mut(1usize); + let mut c: [u64; 1] = [c0; 1usize]; + krml::unroll_for!(15, "i", 0u32, 1u32, { + let t1: u64 = a1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res10.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1); + let t10: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, 0u64, res_i0.1); + let t11: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, 0u64, res_i1.1); + let t12: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, 0u64, res_i2.1) + }); + krml::unroll_for!(3, "i", 60u32, 1u32, { + let t1: u64 = a1.1[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res10.1.split_at_mut(i as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1) + }); + let c1: u64 = (&c)[0usize]; + let c2: u64 = c1; + lowstar::ignore::ignore::(c2); + super::bignum4096::exp_vartime(nBits, n, a, 4096u32, &n2, res) + } else { + (res[0usize..64usize]).copy_from_slice(&[0u64; 64usize]) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Heap-allocate and initialize a montgomery context. + + The argument n is meant to be a 4096-bit bignum, i.e. uint64_t[64]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n % 2 = 1 + • 1 < n + + The caller will need to call Hacl_Bignum4096_mont_ctx_free on the return value + to avoid memory leaks. +*/ +pub fn mont_ctx_init(n: &[u64]) -> Box<[super::base::bn_mont_ctx_u64]> { + let mut r2: Box<[u64]> = vec![0u64; 64usize].into_boxed_slice(); + let mut n1: Box<[u64]> = vec![0u64; 64usize].into_boxed_slice(); + let r21: &mut [u64] = &mut r2; + let n11: &mut [u64] = &mut n1; + (n11[0usize..64usize]).copy_from_slice(&n[0usize..64usize]); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(64u32, n) as u32); + super::bignum4096::precompr2(nBits, n, r21); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + let res: super::base::bn_mont_ctx_u64 = super::base::bn_mont_ctx_u64 { + len: 64u32, + n: (*n11).into(), + mu, + r2: (*r21).into(), + }; + let buf: Box<[super::base::bn_mont_ctx_u64]> = vec![res].into_boxed_slice(); + buf +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be a 8192-bit bignum, i.e. uint64_t[128]. + The outparam res is meant to be a 4096-bit bignum, i.e. uint64_t[64]. + The argument k is a montgomery context obtained through Hacl_Bignum4096_mont_ctx_init. +*/ +pub fn mod_precomp(k: &[super::base::bn_mont_ctx_u64], a: &[u64], res: &mut [u64]) { + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::bignum4096::bn_slow_precomp(n, mu, r2, a, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + The argument k is a montgomery context obtained through Hacl_Bignum4096_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::bignum4096::exp_vartime_precomp(n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + The argument k is a montgomery context obtained through Hacl_Bignum4096_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime_*. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::bignum4096::exp_consttime_precomp(n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The argument a and the outparam res are meant to be 4096-bit bignums, i.e. uint64_t[64]. + The argument k is a montgomery context obtained through Hacl_Bignum4096_mont_ctx_init. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + res: &mut [u64], +) { + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + let mut n2: [u64; 64] = [0u64; 64usize]; + let c0: u64 = + lib::inttypes_intrinsics::sub_borrow_u64(0u64, n[0usize], 2u64, &mut (&mut n2)[0usize..]); + let a1: (&[u64], &[u64]) = n.split_at(1usize); + let res1: (&mut [u64], &mut [u64]) = n2.split_at_mut(1usize); + let mut c: [u64; 1] = [c0; 1usize]; + krml::unroll_for!(15, "i", 0u32, 1u32, { + let t1: u64 = a1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res1.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1); + let t10: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, 0u64, res_i0.1); + let t11: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, 0u64, res_i1.1); + let t12: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, 0u64, res_i2.1) + }); + krml::unroll_for!(3, "i", 60u32, 1u32, { + let t1: u64 = a1.1[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res1.1.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1) + }); + let c1: u64 = (&c)[0usize]; + let c2: u64 = c1; + lowstar::ignore::ignore::(c2); + super::bignum4096::exp_vartime_precomp(n, mu, r2, a, 4096u32, &n2, res) +} + +/** +Load a bid-endian bignum from memory. + + The argument b points to len bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_be(len: u32, b: &[u8]) -> Box<[u64]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) > 536870911u32 { + [].into() + } else { + let mut res: Box<[u64]> = + vec![0u64; len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u64] = &mut res; + let res2: &mut [u64] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[tmpLen.wrapping_sub(len) as usize + ..tmpLen.wrapping_sub(len) as usize + len as usize]) + .copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..bnLen { + let u: u64 = lowstar::endianness::load64_be( + &(&tmp)[bnLen.wrapping_sub(i).wrapping_sub(1u32).wrapping_mul(8u32) as usize..], + ); + let x: u64 = u; + let os: (&mut [u64], &mut [u64]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Load a little-endian bignum from memory. + + The argument b points to len bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_le(len: u32, b: &[u8]) -> Box<[u64]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) > 536870911u32 { + [].into() + } else { + let mut res: Box<[u64]> = + vec![0u64; len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u64] = &mut res; + let res2: &mut [u64] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) { + let bj: (&[u8], &[u8]) = tmp.split_at(i.wrapping_mul(8u32) as usize); + let u: u64 = lowstar::endianness::load64_le(bj.1); + let r1: u64 = u; + let x: u64 = r1; + let os: (&mut [u64], &mut [u64]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Serialize a bignum into big-endian memory. + + The argument b points to a 4096-bit bignum. + The outparam res points to 512 bytes of valid memory. +*/ +pub fn bn_to_bytes_be(b: &[u64], res: &mut [u8]) { + let tmp: [u8; 512] = [0u8; 512usize]; + lowstar::ignore::ignore::<&[u8]>(&tmp); + for i in 0u32..64u32 { + lowstar::endianness::store64_be( + &mut res[i.wrapping_mul(8u32) as usize..], + b[64u32.wrapping_sub(i).wrapping_sub(1u32) as usize], + ) + } +} + +/** +Serialize a bignum into little-endian memory. + + The argument b points to a 4096-bit bignum. + The outparam res points to 512 bytes of valid memory. +*/ +pub fn bn_to_bytes_le(b: &[u64], res: &mut [u8]) { + let tmp: [u8; 512] = [0u8; 512usize]; + lowstar::ignore::ignore::<&[u8]>(&tmp); + for i in 0u32..64u32 { + lowstar::endianness::store64_le(&mut res[i.wrapping_mul(8u32) as usize..], b[i as usize]) + } +} + +/** +Returns 2^64 - 1 if a < b, otherwise returns 0. + + The arguments a and b are meant to be 4096-bit bignums, i.e. uint64_t[64]. +*/ +pub fn lt_mask(a: &[u64], b: &[u64]) -> u64 { + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..64u32 { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], b[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], b[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + (&acc)[0usize] +} + +/** +Returns 2^64 - 1 if a = b, otherwise returns 0. + + The arguments a and b are meant to be 4096-bit bignums, i.e. uint64_t[64]. +*/ +pub fn eq_mask(a: &[u64], b: &[u64]) -> u64 { + let mut mask: [u64; 1] = [0xFFFFFFFFFFFFFFFFu64; 1usize]; + for i in 0u32..64u32 { + let uu____0: u64 = fstar::uint64::eq_mask(a[i as usize], b[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + } + let mask1: u64 = (&mask)[0usize]; + mask1 +} diff --git a/hacl-rs/src/bignum/bignum4096_32.rs b/hacl-rs/src/bignum/bignum4096_32.rs new file mode 100644 index 000000000..eb67241be --- /dev/null +++ b/hacl-rs/src/bignum/bignum4096_32.rs @@ -0,0 +1,1249 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_macros as krml; + +use crate::fstar; +use crate::lowstar; +use crate::util as lib; + +/** +Write `a + b mod 2^4096` in `res`. + + This functions returns the carry. + + The arguments a, b and res are meant to be 4096-bit bignums, i.e. uint32_t[128] +*/ +pub fn add(a: &[u32], b: &[u32], res: &mut [u32]) -> u32 { + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t12, t22, res_i2.1) + }); + (&c)[0usize] +} + +/** +Write `a - b mod 2^4096` in `res`. + + This functions returns the carry. + + The arguments a, b and res are meant to be 4096-bit bignums, i.e. uint32_t[128] +*/ +pub fn sub(a: &[u32], b: &[u32], res: &mut [u32]) -> u32 { + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, t22, res_i2.1) + }); + (&c)[0usize] +} + +/** +Write `(a + b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn add_mod(n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) { + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t12, t22, res_i2.1) + }); + let c0: u32 = (&c)[0usize]; + let mut tmp: [u32; 128] = [0u32; 128usize]; + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u32 = (&c1)[0usize]; + let c2: u32 = c0.wrapping_sub(c10); + for i in 0u32..128u32 { + let x: u32 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +Write `(a - b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn sub_mod(n: &[u32], a: &[u32], b: &[u32], res: &mut [u32]) { + let mut c: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, t22, res_i2.1) + }); + let c0: u32 = (&c)[0usize]; + let mut tmp: [u32; 128] = [0u32; 128usize]; + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u32 = (&c1)[0usize]; + lowstar::ignore::ignore::(c10); + let c2: u32 = 0u32.wrapping_sub(c0); + for i in 0u32..128u32 { + let x: u32 = c2 & (&tmp)[i as usize] | !c2 & res[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +Write `a * b` in `res`. + + The arguments a and b are meant to be 4096-bit bignums, i.e. uint32_t[128]. + The outparam res is meant to be a 8192-bit bignum, i.e. uint32_t[256]. +*/ +pub fn mul(a: &[u32], b: &[u32], res: &mut [u32]) { + let mut tmp: [u32; 512] = [0u32; 512usize]; + super::base::bn_karatsuba_mul_uint32(128u32, a, b, &mut tmp, res) +} + +/** +Write `a * a` in `res`. + + The argument a is meant to be a 4096-bit bignum, i.e. uint32_t[128]. + The outparam res is meant to be a 8192-bit bignum, i.e. uint32_t[256]. +*/ +pub fn sqr(a: &[u32], res: &mut [u32]) { + let mut tmp: [u32; 512] = [0u32; 512usize]; + super::base::bn_karatsuba_sqr_uint32(128u32, a, &mut tmp, res) +} + +#[inline] +fn precompr2(nBits: u32, n: &[u32], res: &mut [u32]) { + (res[0usize..128usize]).copy_from_slice(&[0u32; 128usize]); + let i: u32 = nBits.wrapping_div(32u32); + let j: u32 = nBits.wrapping_rem(32u32); + res[i as usize] |= 1u32.wrapping_shl(j); + for _i in 0u32..8192u32.wrapping_sub(nBits) { + let mut a_copy: [u32; 128] = [0u32; 128usize]; + let mut b_copy: [u32; 128] = [0u32; 128usize]; + ((&mut a_copy)[0usize..128usize]).copy_from_slice(&res[0usize..128usize]); + ((&mut b_copy)[0usize..128usize]).copy_from_slice(&res[0usize..128usize]); + super::bignum4096_32::add_mod(n, &a_copy, &b_copy, res) + } +} + +#[inline] +fn reduction(n: &[u32], nInv: u32, c: &mut [u32], res: &mut [u32]) { + let mut c0: [u32; 1] = [0u32; 1usize]; + for i in 0u32..128u32 { + let qj: u32 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize); + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i0", 0u32, 1u32, { + let a_i: u32 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u32 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u32 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u32 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, qj, (&c1)[0usize], res_i2.1) + }); + let r: u32 = (&c1)[0usize]; + let c10: u32 = r; + let res_j0: u32 = c[128u32.wrapping_add(i) as usize]; + let resb: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize + 128usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c0)[0usize], c10, res_j0, resb.1) + } + (res[0usize..128usize]).copy_from_slice(&(&c[128usize..])[0usize..128usize]); + let c00: u32 = (&c0)[0usize]; + let mut tmp: [u32; 128] = [0u32; 128usize]; + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let t1: u32 = res[4u32.wrapping_mul(i) as usize]; + let t2: u32 = n[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = tmp.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t1, t2, res_i.1); + let t10: u32 = res[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = n[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t10, t20, res_i0.1); + let t11: u32 = res[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = n[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t11, t21, res_i1.1); + let t12: u32 = res[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = n[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c1)[0usize], t12, t22, res_i2.1) + }); + let c10: u32 = (&c1)[0usize]; + let c2: u32 = c00.wrapping_sub(c10); + for i in 0u32..128u32 { + let x: u32 = c2 & res[i as usize] | !c2 & (&tmp)[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +#[inline] +fn to(n: &[u32], nInv: u32, r2: &[u32], a: &[u32], aM: &mut [u32]) { + let mut c: [u32; 256] = [0u32; 256usize]; + super::bignum4096_32::mul(a, r2, &mut c); + super::bignum4096_32::reduction(n, nInv, &mut c, aM) +} + +#[inline] +fn from(n: &[u32], nInv_u64: u32, aM: &[u32], a: &mut [u32]) { + let mut tmp: [u32; 256] = [0u32; 256usize]; + ((&mut tmp)[0usize..128usize]).copy_from_slice(&aM[0usize..128usize]); + super::bignum4096_32::reduction(n, nInv_u64, &mut tmp, a) +} + +#[inline] +fn areduction(n: &[u32], nInv: u32, c: &mut [u32], res: &mut [u32]) { + let mut c0: [u32; 1] = [0u32; 1usize]; + for i in 0u32..128u32 { + let qj: u32 = nInv.wrapping_mul(c[i as usize]); + let res_j: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize); + let mut c1: [u32; 1] = [0u32; 1usize]; + krml::unroll_for!(32, "i0", 0u32, 1u32, { + let a_i: u32 = n[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, qj, (&c1)[0usize], res_i.1); + let a_i0: u32 = n[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, qj, (&c1)[0usize], res_i0.1); + let a_i1: u32 = n[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, qj, (&c1)[0usize], res_i1.1); + let a_i2: u32 = n[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c1)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, qj, (&c1)[0usize], res_i2.1) + }); + let r: u32 = (&c1)[0usize]; + let c10: u32 = r; + let res_j0: u32 = c[128u32.wrapping_add(i) as usize]; + let resb: (&mut [u32], &mut [u32]) = c.split_at_mut(i as usize + 128usize); + (&mut c0)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c0)[0usize], c10, res_j0, resb.1) + } + (res[0usize..128usize]).copy_from_slice(&(&c[128usize..])[0usize..128usize]); + let c00: u32 = (&c0)[0usize]; + let mut tmp: [u32; 128] = [0u32; 128usize]; + let c1: u32 = super::bignum4096_32::sub(res, n, &mut tmp); + lowstar::ignore::ignore::(c1); + let m: u32 = 0u32.wrapping_sub(c00); + for i in 0u32..128u32 { + let x: u32 = m & (&tmp)[i as usize] | !m & res[i as usize]; + let os: (&mut [u32], &mut [u32]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +#[inline] +fn amont_mul(n: &[u32], nInv_u64: u32, aM: &[u32], bM: &[u32], resM: &mut [u32]) { + let mut c: [u32; 256] = [0u32; 256usize]; + super::bignum4096_32::mul(aM, bM, &mut c); + super::bignum4096_32::areduction(n, nInv_u64, &mut c, resM) +} + +#[inline] +fn amont_sqr(n: &[u32], nInv_u64: u32, aM: &[u32], resM: &mut [u32]) { + let mut c: [u32; 256] = [0u32; 256usize]; + super::bignum4096_32::sqr(aM, &mut c); + super::bignum4096_32::areduction(n, nInv_u64, &mut c, resM) +} + +#[inline] +fn bn_slow_precomp(n: &[u32], mu: u32, r2: &[u32], a: &[u32], res: &mut [u32]) { + let mut a_mod: [u32; 128] = [0u32; 128usize]; + let mut a1: [u32; 256] = [0u32; 256usize]; + ((&mut a1)[0usize..256usize]).copy_from_slice(&a[0usize..256usize]); + super::bignum4096_32::areduction(n, mu, &mut a1, &mut a_mod); + super::bignum4096_32::to(n, mu, r2, &a_mod, res) +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be a 8192-bit bignum, i.e. uint32_t[256]. + The argument n and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • 1 < n + • n % 2 = 1 +*/ +pub fn r#mod(n: &[u32], a: &[u32], res: &mut [u32]) -> bool { + let mut one: [u32; 128] = [0u32; 128usize]; + ((&mut one)[0usize..128usize]).copy_from_slice(&[0u32; 128usize]); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..128u32 { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u32 = (&acc)[0usize]; + let is_valid_m: u32 = m0 & m1; + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(128u32, n)); + if is_valid_m == 0xFFFFFFFFu32 { + let mut r2: [u32; 128] = [0u32; 128usize]; + super::bignum4096_32::precompr2(nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::bignum4096_32::bn_slow_precomp(n, mu, &r2, a, res) + } else { + (res[0usize..128usize]).copy_from_slice(&[0u32; 128usize]) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +fn exp_check(n: &[u32], a: &[u32], bBits: u32, b: &[u32]) -> u32 { + let mut one: [u32; 128] = [0u32; 128usize]; + ((&mut one)[0usize..128usize]).copy_from_slice(&[0u32; 128usize]); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..128u32 { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u32 = (&acc)[0usize]; + let m00: u32 = m0 & m1; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let m10: u32 = if bBits < 32u32.wrapping_mul(bLen) { + let mut b2: Box<[u32]> = vec![0u32; bLen as usize].into_boxed_slice(); + let i: u32 = bBits.wrapping_div(32u32); + let j: u32 = bBits.wrapping_rem(32u32); + (&mut b2)[i as usize] = (&b2)[i as usize] | 1u32.wrapping_shl(j); + let mut acc0: [u32; 1] = [0u32; 1usize]; + for i0 in 0u32..bLen { + let beq: u32 = fstar::uint32::eq_mask(b[i0 as usize], (&b2)[i0 as usize]); + let blt: u32 = !fstar::uint32::gte_mask(b[i0 as usize], (&b2)[i0 as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let res: u32 = (&acc0)[0usize]; + res + } else { + 0xFFFFFFFFu32 + }; + let mut acc0: [u32; 1] = [0u32; 1usize]; + for i in 0u32..128u32 { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let m2: u32 = (&acc0)[0usize]; + let m: u32 = m10 & m2; + m00 & m +} + +#[inline] +fn exp_vartime_precomp( + n: &[u32], + mu: u32, + r2: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + if bBits < 200u32 { + let mut aM: [u32; 128] = [0u32; 128usize]; + super::bignum4096_32::to(n, mu, r2, a, &mut aM); + let mut resM: [u32; 128] = [0u32; 128usize]; + let mut ctx: [u32; 256] = [0u32; 256usize]; + ((&mut ctx)[0usize..128usize]).copy_from_slice(&n[0usize..128usize]); + ((&mut ctx)[128usize..128usize + 128usize]).copy_from_slice(&r2[0usize..128usize]); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(128usize); + super::bignum4096_32::from(ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = i.wrapping_div(32u32); + let j: u32 = i.wrapping_rem(32u32); + let tmp: u32 = b[i1 as usize]; + let bit: u32 = tmp.wrapping_shr(j) & 1u32; + if bit != 0u32 { + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&(&resM)[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_mul(ctx_n0.1, mu, &aM_copy, &aM, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&(&aM)[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut aM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::bignum4096_32::from(n, mu, &resM, res) + } else { + let mut aM: [u32; 128] = [0u32; 128usize]; + super::bignum4096_32::to(n, mu, r2, a, &mut aM); + let mut resM: [u32; 128] = [0u32; 128usize]; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let mut ctx: [u32; 256] = [0u32; 256usize]; + ((&mut ctx)[0usize..128usize]).copy_from_slice(&n[0usize..128usize]); + ((&mut ctx)[128usize..128usize + 128usize]).copy_from_slice(&r2[0usize..128usize]); + let mut table: [u32; 2048] = [0u32; 2048usize]; + let mut tmp: [u32; 128] = [0u32; 128usize]; + let t0: (&mut [u32], &mut [u32]) = table.split_at_mut(0usize); + let t1: (&mut [u32], &mut [u32]) = t0.1.split_at_mut(128usize); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(128usize); + super::bignum4096_32::from(ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (t1.1[0usize..128usize]).copy_from_slice(&(&aM)[0usize..128usize]); + lowstar::ignore::ignore::<&[u32]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u32], &[u32]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(128u32) as usize); + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&t11.1[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(128u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(128u32) as usize + + 128usize]) + .copy_from_slice(&(&tmp)[0usize..128usize]); + let t2: (&[u32], &[u32]) = table + .split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(128u32) as usize); + let mut aM_copy0: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy0)[0usize..128usize]).copy_from_slice(&(&aM)[0usize..128usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_mul(ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(128u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(128u32) as usize + 128usize]) + .copy_from_slice(&(&tmp)[0usize..128usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, i, 4u32); + let bits_l32: u32 = bits_c; + let a_bits_l: (&[u32], &[u32]) = table.split_at(bits_l32.wrapping_mul(128u32) as usize); + ((&mut resM)[0usize..128usize]).copy_from_slice(&a_bits_l.1[0usize..128usize]) + } else { + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r20: (&[u32], &[u32]) = ctx_n0.1.split_at(128usize); + super::bignum4096_32::from(ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut tmp0: [u32; 128] = [0u32; 128usize]; + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&(&resM)[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u32]>(&table); + let bits_l32: u32 = bits_l; + let a_bits_l: (&[u32], &[u32]) = table.split_at(bits_l32.wrapping_mul(128u32) as usize); + ((&mut tmp0)[0usize..128usize]).copy_from_slice(&a_bits_l.1[0usize..128usize]); + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&(&resM)[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_mul(ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::bignum4096_32::from(n, mu, &resM, res) + } +} + +#[inline] +fn exp_consttime_precomp( + n: &[u32], + mu: u32, + r2: &[u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + if bBits < 200u32 { + let mut aM: [u32; 128] = [0u32; 128usize]; + super::bignum4096_32::to(n, mu, r2, a, &mut aM); + let mut resM: [u32; 128] = [0u32; 128usize]; + let mut ctx: [u32; 256] = [0u32; 256usize]; + ((&mut ctx)[0usize..128usize]).copy_from_slice(&n[0usize..128usize]); + ((&mut ctx)[128usize..128usize + 128usize]).copy_from_slice(&r2[0usize..128usize]); + let mut sw: [u32; 1] = [0u32; 1usize]; + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(128usize); + super::bignum4096_32::from(ctx_r2.0, mu, ctx_r2.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + for i in 0u32..bBits { + let i1: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_div(32u32); + let j: u32 = bBits.wrapping_sub(i).wrapping_sub(1u32).wrapping_rem(32u32); + let tmp: u32 = b[i1 as usize]; + let bit: u32 = tmp.wrapping_shr(j) & 1u32; + let sw1: u32 = bit ^ (&sw)[0usize]; + for i0 in 0u32..128u32 { + let dummy: u32 = + 0u32.wrapping_sub(sw1) & ((&resM)[i0 as usize] ^ (&aM)[i0 as usize]); + (&mut resM)[i0 as usize] = (&resM)[i0 as usize] ^ dummy; + (&mut aM)[i0 as usize] = (&aM)[i0 as usize] ^ dummy + } + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&(&aM)[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_mul(ctx_n0.1, mu, &aM_copy, &resM, &mut aM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + let mut aM_copy0: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy0)[0usize..128usize]).copy_from_slice(&(&resM)[0usize..128usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_sqr(ctx_n1.1, mu, &aM_copy0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (&mut sw)[0usize] = bit + } + let sw0: u32 = (&sw)[0usize]; + for i in 0u32..128u32 { + let dummy: u32 = 0u32.wrapping_sub(sw0) & ((&resM)[i as usize] ^ (&aM)[i as usize]); + (&mut resM)[i as usize] = (&resM)[i as usize] ^ dummy; + (&mut aM)[i as usize] = (&aM)[i as usize] ^ dummy + } + super::bignum4096_32::from(n, mu, &resM, res) + } else { + let mut aM: [u32; 128] = [0u32; 128usize]; + super::bignum4096_32::to(n, mu, r2, a, &mut aM); + let mut resM: [u32; 128] = [0u32; 128usize]; + let bLen: u32 = if bBits == 0u32 { + 1u32 + } else { + bBits + .wrapping_sub(1u32) + .wrapping_div(32u32) + .wrapping_add(1u32) + }; + let mut ctx: [u32; 256] = [0u32; 256usize]; + ((&mut ctx)[0usize..128usize]).copy_from_slice(&n[0usize..128usize]); + ((&mut ctx)[128usize..128usize + 128usize]).copy_from_slice(&r2[0usize..128usize]); + let mut table: [u32; 2048] = [0u32; 2048usize]; + let mut tmp: [u32; 128] = [0u32; 128usize]; + let t0: (&mut [u32], &mut [u32]) = table.split_at_mut(0usize); + let t1: (&mut [u32], &mut [u32]) = t0.1.split_at_mut(128usize); + let ctx_n: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r2: (&[u32], &[u32]) = ctx_n.1.split_at(128usize); + super::bignum4096_32::from(ctx_r2.0, mu, ctx_r2.1, t1.0); + lowstar::ignore::ignore::<&[u32]>(&ctx); + (t1.1[0usize..128usize]).copy_from_slice(&(&aM)[0usize..128usize]); + lowstar::ignore::ignore::<&[u32]>(&table); + krml::unroll_for!(7, "i", 0u32, 1u32, { + let t11: (&[u32], &[u32]) = + table.split_at(i.wrapping_add(1u32).wrapping_mul(128u32) as usize); + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&t11.1[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(128u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(128u32) as usize + + 128usize]) + .copy_from_slice(&(&tmp)[0usize..128usize]); + let t2: (&[u32], &[u32]) = table + .split_at(2u32.wrapping_mul(i).wrapping_add(2u32).wrapping_mul(128u32) as usize); + let mut aM_copy0: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy0)[0usize..128usize]).copy_from_slice(&(&aM)[0usize..128usize]); + let ctx_n1: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_mul(ctx_n1.1, mu, &aM_copy0, t2.1, &mut tmp); + lowstar::ignore::ignore::<&[u32]>(&ctx); + ((&mut table)[2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(128u32) as usize + ..2u32.wrapping_mul(i).wrapping_add(3u32).wrapping_mul(128u32) as usize + 128usize]) + .copy_from_slice(&(&tmp)[0usize..128usize]) + }); + if bBits.wrapping_rem(4u32) != 0u32 { + let i: u32 = bBits.wrapping_div(4u32).wrapping_mul(4u32); + let bits_c: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, i, 4u32); + ((&mut resM)[0usize..128usize]) + .copy_from_slice(&(&(&table)[0usize..] as &[u32])[0usize..128usize]); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u32 = fstar::uint32::eq_mask(bits_c, i0.wrapping_add(1u32)); + let res_j: (&[u32], &[u32]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(128u32) as usize); + for i1 in 0u32..128u32 { + let x: u32 = c & res_j.1[i1 as usize] | !c & (&resM)[i1 as usize]; + let os: (&mut [u32], &mut [u32]) = resM.split_at_mut(0usize); + os.1[i1 as usize] = x + } + }) + } else { + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + let ctx_r20: (&[u32], &[u32]) = ctx_n0.1.split_at(128usize); + super::bignum4096_32::from(ctx_r20.0, mu, ctx_r20.1, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }; + let mut tmp0: [u32; 128] = [0u32; 128usize]; + for i in 0u32..bBits.wrapping_div(4u32) { + krml::unroll_for!(4, "_i", 0u32, 1u32, { + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&(&resM)[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_sqr(ctx_n0.1, mu, &aM_copy, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + }); + let k: u32 = bBits + .wrapping_sub(bBits.wrapping_rem(4u32)) + .wrapping_sub(4u32.wrapping_mul(i)) + .wrapping_sub(4u32); + let bits_l: u32 = super::bignum_base::bn_get_bits_u32(bLen, b, k, 4u32); + lowstar::ignore::ignore::<&[u32]>(&table); + ((&mut tmp0)[0usize..128usize]) + .copy_from_slice(&(&(&table)[0usize..] as &[u32])[0usize..128usize]); + krml::unroll_for!(15, "i0", 0u32, 1u32, { + let c: u32 = fstar::uint32::eq_mask(bits_l, i0.wrapping_add(1u32)); + let res_j: (&[u32], &[u32]) = + table.split_at(i0.wrapping_add(1u32).wrapping_mul(128u32) as usize); + for i1 in 0u32..128u32 { + let x: u32 = c & res_j.1[i1 as usize] | !c & (&tmp0)[i1 as usize]; + let os: (&mut [u32], &mut [u32]) = tmp0.split_at_mut(0usize); + os.1[i1 as usize] = x + } + }); + let mut aM_copy: [u32; 128] = [0u32; 128usize]; + ((&mut aM_copy)[0usize..128usize]).copy_from_slice(&(&resM)[0usize..128usize]); + let ctx_n0: (&[u32], &[u32]) = ctx.split_at(0usize); + super::bignum4096_32::amont_mul(ctx_n0.1, mu, &aM_copy, &tmp0, &mut resM); + lowstar::ignore::ignore::<&[u32]>(&ctx) + } + super::bignum4096_32::from(n, mu, &resM, res) + } +} + +#[inline] +fn exp_vartime(nBits: u32, n: &[u32], a: &[u32], bBits: u32, b: &[u32], res: &mut [u32]) { + let mut r2: [u32; 128] = [0u32; 128usize]; + super::bignum4096_32::precompr2(nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::bignum4096_32::exp_vartime_precomp(n, mu, &r2, a, bBits, b, res) +} + +#[inline] +fn exp_consttime(nBits: u32, n: &[u32], a: &[u32], bBits: u32, b: &[u32], res: &mut [u32]) { + let mut r2: [u32; 128] = [0u32; 128usize]; + super::bignum4096_32::precompr2(nBits, n, &mut r2); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + super::bignum4096_32::exp_consttime_precomp(n, mu, &r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime(n: &[u32], a: &[u32], bBits: u32, b: &[u32], res: &mut [u32]) -> bool { + let is_valid_m: u32 = super::bignum4096_32::exp_check(n, a, bBits, b); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(128u32, n)); + if is_valid_m == 0xFFFFFFFFu32 { + super::bignum4096_32::exp_vartime(nBits, n, a, bBits, b, res) + } else { + (res[0usize..128usize]).copy_from_slice(&[0u32; 128usize]) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime(n: &[u32], a: &[u32], bBits: u32, b: &[u32], res: &mut [u32]) -> bool { + let is_valid_m: u32 = super::bignum4096_32::exp_check(n, a, bBits, b); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(128u32, n)); + if is_valid_m == 0xFFFFFFFFu32 { + super::bignum4096_32::exp_consttime(nBits, n, a, bBits, b, res) + } else { + (res[0usize..128usize]).copy_from_slice(&[0u32; 128usize]) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The arguments a, n and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + + The function returns false if any of the following preconditions are violated, true otherwise. + • n % 2 = 1 + • 1 < n + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime(n: &[u32], a: &[u32], res: &mut [u32]) -> bool { + let mut one: [u32; 128] = [0u32; 128usize]; + ((&mut one)[0usize..128usize]).copy_from_slice(&[0u32; 128usize]); + (&mut one)[0usize] = 1u32; + let bit0: u32 = n[0usize] & 1u32; + let m0: u32 = 0u32.wrapping_sub(bit0); + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..128u32 { + let beq: u32 = fstar::uint32::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u32 = (&acc)[0usize]; + let m00: u32 = m0 & m1; + let bn_zero: [u32; 128] = [0u32; 128usize]; + let mut mask: [u32; 1] = [0xFFFFFFFFu32; 1usize]; + for i in 0u32..128u32 { + let uu____0: u32 = fstar::uint32::eq_mask(a[i as usize], (&bn_zero)[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + } + let mask1: u32 = (&mask)[0usize]; + let res1: u32 = mask1; + let m10: u32 = res1; + let mut acc0: [u32; 1] = [0u32; 1usize]; + for i in 0u32..128u32 { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], n[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let m2: u32 = (&acc0)[0usize]; + let is_valid_m: u32 = m00 & !m10 & m2; + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(128u32, n)); + if is_valid_m == 0xFFFFFFFFu32 { + let mut n2: [u32; 128] = [0u32; 128usize]; + let c0: u32 = lib::inttypes_intrinsics::sub_borrow_u32( + 0u32, + n[0usize], + 2u32, + &mut (&mut n2)[0usize..], + ); + let a1: (&[u32], &[u32]) = n.split_at(1usize); + let res10: (&mut [u32], &mut [u32]) = n2.split_at_mut(1usize); + let mut c: [u32; 1] = [c0; 1usize]; + krml::unroll_for!(31, "i", 0u32, 1u32, { + let t1: u32 = a1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res10.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1); + let t10: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, 0u32, res_i0.1); + let t11: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, 0u32, res_i1.1); + let t12: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, 0u32, res_i2.1) + }); + krml::unroll_for!(3, "i", 124u32, 1u32, { + let t1: u32 = a1.1[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res10.1.split_at_mut(i as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1) + }); + let c1: u32 = (&c)[0usize]; + let c2: u32 = c1; + lowstar::ignore::ignore::(c2); + super::bignum4096_32::exp_vartime(nBits, n, a, 4096u32, &n2, res) + } else { + (res[0usize..128usize]).copy_from_slice(&[0u32; 128usize]) + }; + is_valid_m == 0xFFFFFFFFu32 +} + +/** +Heap-allocate and initialize a montgomery context. + + The argument n is meant to be a 4096-bit bignum, i.e. uint32_t[128]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n % 2 = 1 + • 1 < n + + The caller will need to call Hacl_Bignum4096_mont_ctx_free on the return value + to avoid memory leaks. +*/ +pub fn mont_ctx_init(n: &[u32]) -> Box<[super::base::bn_mont_ctx_u32]> { + let mut r2: Box<[u32]> = vec![0u32; 128usize].into_boxed_slice(); + let mut n1: Box<[u32]> = vec![0u32; 128usize].into_boxed_slice(); + let r21: &mut [u32] = &mut r2; + let n11: &mut [u32] = &mut n1; + (n11[0usize..128usize]).copy_from_slice(&n[0usize..128usize]); + let nBits: u32 = 32u32.wrapping_mul(super::bignum_base::bn_get_top_index_u32(128u32, n)); + super::bignum4096_32::precompr2(nBits, n, r21); + let mu: u32 = super::base::mod_inv_uint32(n[0usize]); + let res: super::base::bn_mont_ctx_u32 = super::base::bn_mont_ctx_u32 { + len: 128u32, + n: (*n11).into(), + mu, + r2: (*r21).into(), + }; + let buf: Box<[super::base::bn_mont_ctx_u32]> = vec![res].into_boxed_slice(); + buf +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be a 8192-bit bignum, i.e. uint32_t[256]. + The outparam res is meant to be a 4096-bit bignum, i.e. uint32_t[128]. + The argument k is a montgomery context obtained through Hacl_Bignum4096_mont_ctx_init. +*/ +pub fn mod_precomp(k: &[super::base::bn_mont_ctx_u32], a: &[u32], res: &mut [u32]) { + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::bignum4096_32::bn_slow_precomp(n, mu, r2, a, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + The argument k is a montgomery context obtained through Hacl_Bignum4096_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::bignum4096_32::exp_vartime_precomp(n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + The argument k is a montgomery context obtained through Hacl_Bignum4096_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime_*. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + bBits: u32, + b: &[u32], + res: &mut [u32], +) { + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + super::bignum4096_32::exp_consttime_precomp(n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The argument a and the outparam res are meant to be 4096-bit bignums, i.e. uint32_t[128]. + The argument k is a montgomery context obtained through Hacl_Bignum4096_mont_ctx_init. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime_precomp( + k: &[super::base::bn_mont_ctx_u32], + a: &[u32], + res: &mut [u32], +) { + let n: &[u32] = &(k[0usize]).n; + let mu: u32 = (k[0usize]).mu; + let r2: &[u32] = &(k[0usize]).r2; + let mut n2: [u32; 128] = [0u32; 128usize]; + let c0: u32 = + lib::inttypes_intrinsics::sub_borrow_u32(0u32, n[0usize], 2u32, &mut (&mut n2)[0usize..]); + let a1: (&[u32], &[u32]) = n.split_at(1usize); + let res1: (&mut [u32], &mut [u32]) = n2.split_at_mut(1usize); + let mut c: [u32; 1] = [c0; 1usize]; + krml::unroll_for!(31, "i", 0u32, 1u32, { + let t1: u32 = a1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res1.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1); + let t10: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, 0u32, res_i0.1); + let t11: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, 0u32, res_i1.1); + let t12: u32 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, 0u32, res_i2.1) + }); + krml::unroll_for!(3, "i", 124u32, 1u32, { + let t1: u32 = a1.1[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res1.1.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, 0u32, res_i.1) + }); + let c1: u32 = (&c)[0usize]; + let c2: u32 = c1; + lowstar::ignore::ignore::(c2); + super::bignum4096_32::exp_vartime_precomp(n, mu, r2, a, 4096u32, &n2, res) +} + +/** +Load a bid-endian bignum from memory. + + The argument b points to len bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_be(len: u32, b: &[u8]) -> Box<[u32]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) > 1073741823u32 { + [].into() + } else { + let mut res: Box<[u32]> = + vec![0u32; len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u32] = &mut res; + let res2: &mut [u32] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32); + let tmpLen: u32 = 4u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[tmpLen.wrapping_sub(len) as usize + ..tmpLen.wrapping_sub(len) as usize + len as usize]) + .copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..bnLen { + let u: u32 = lowstar::endianness::load32_be( + &(&tmp)[bnLen.wrapping_sub(i).wrapping_sub(1u32).wrapping_mul(4u32) as usize..], + ); + let x: u32 = u; + let os: (&mut [u32], &mut [u32]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Load a little-endian bignum from memory. + + The argument b points to len bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_le(len: u32, b: &[u8]) -> Box<[u32]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) > 1073741823u32 { + [].into() + } else { + let mut res: Box<[u32]> = + vec![0u32; len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u32] = &mut res; + let res2: &mut [u32] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32); + let tmpLen: u32 = 4u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_add(1u32) { + let bj: (&[u8], &[u8]) = tmp.split_at(i.wrapping_mul(4u32) as usize); + let u: u32 = lowstar::endianness::load32_le(bj.1); + let r1: u32 = u; + let x: u32 = r1; + let os: (&mut [u32], &mut [u32]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Serialize a bignum into big-endian memory. + + The argument b points to a 4096-bit bignum. + The outparam res points to 512 bytes of valid memory. +*/ +pub fn bn_to_bytes_be(b: &[u32], res: &mut [u8]) { + let tmp: [u8; 512] = [0u8; 512usize]; + lowstar::ignore::ignore::<&[u8]>(&tmp); + for i in 0u32..128u32 { + lowstar::endianness::store32_be( + &mut res[i.wrapping_mul(4u32) as usize..], + b[128u32.wrapping_sub(i).wrapping_sub(1u32) as usize], + ) + } +} + +/** +Serialize a bignum into little-endian memory. + + The argument b points to a 4096-bit bignum. + The outparam res points to 512 bytes of valid memory. +*/ +pub fn bn_to_bytes_le(b: &[u32], res: &mut [u8]) { + let tmp: [u8; 512] = [0u8; 512usize]; + lowstar::ignore::ignore::<&[u8]>(&tmp); + for i in 0u32..128u32 { + lowstar::endianness::store32_le(&mut res[i.wrapping_mul(4u32) as usize..], b[i as usize]) + } +} + +/** +Returns 2^32 - 1 if a < b, otherwise returns 0. + + The arguments a and b are meant to be 4096-bit bignums, i.e. uint32_t[128]. +*/ +pub fn lt_mask(a: &[u32], b: &[u32]) -> u32 { + let mut acc: [u32; 1] = [0u32; 1usize]; + for i in 0u32..128u32 { + let beq: u32 = fstar::uint32::eq_mask(a[i as usize], b[i as usize]); + let blt: u32 = !fstar::uint32::gte_mask(a[i as usize], b[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + (&acc)[0usize] +} + +/** +Returns 2^32 - 1 if a = b, otherwise returns 0. + + The arguments a and b are meant to be 4096-bit bignums, i.e. uint32_t[128]. +*/ +pub fn eq_mask(a: &[u32], b: &[u32]) -> u32 { + let mut mask: [u32; 1] = [0xFFFFFFFFu32; 1usize]; + for i in 0u32..128u32 { + let uu____0: u32 = fstar::uint32::eq_mask(a[i as usize], b[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + } + let mask1: u32 = (&mask)[0usize]; + mask1 +} diff --git a/hacl-rs/src/bignum/bignum64.rs b/hacl-rs/src/bignum/bignum64.rs new file mode 100644 index 000000000..fb11f586e --- /dev/null +++ b/hacl-rs/src/bignum/bignum64.rs @@ -0,0 +1,651 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use crate::fstar; +use crate::lowstar; +use crate::util as lib; + +pub type pbn_mont_ctx_u64<'a> = &'a [super::base::bn_mont_ctx_u64]; + +/** +Write `a + b mod 2 ^ (64 * len)` in `res`. + + This functions returns the carry. + + The arguments a, b and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len] +*/ +pub fn add(len: u32, a: &[u64], b: &[u64], res: &mut [u64]) -> u64 { + super::bignum_base::bn_add_eq_len_u64(len, a, b, res) +} + +/** +Write `a - b mod 2 ^ (64 * len)` in `res`. + + This functions returns the carry. + + The arguments a, b and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len] +*/ +pub fn sub(len: u32, a: &[u64], b: &[u64], res: &mut [u64]) -> u64 { + super::bignum_base::bn_sub_eq_len_u64(len, a, b, res) +} + +/** +Write `(a + b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn add_mod(len: u32, n: &[u64], a: &[u64], b: &[u64], res: &mut [u64]) { + let mut a_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let mut b_copy: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..len as usize]).copy_from_slice(&a[0usize..len as usize]); + ((&mut b_copy)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]); + super::base::bn_add_mod_n_u64(len, n, &a_copy, &b_copy, res) +} + +/** +Write `(a - b) mod n` in `res`. + + The arguments a, b, n and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • a < n + • b < n +*/ +pub fn sub_mod(len: u32, n: &[u64], a: &[u64], b: &[u64], res: &mut [u64]) { + super::base::bn_sub_mod_n_u64(len, n, a, b, res) +} + +/** +Write `a * b` in `res`. + + The arguments a and b are meant to be `len` limbs in size, i.e. uint64_t[len]. + The outparam res is meant to be `2*len` limbs in size, i.e. uint64_t[2*len]. +*/ +pub fn mul(len: u32, a: &[u64], b: &[u64], res: &mut [u64]) { + let mut tmp: Box<[u64]> = vec![0u64; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_mul_uint64(len, a, b, &mut tmp, res) +} + +/** +Write `a * a` in `res`. + + The argument a is meant to be `len` limbs in size, i.e. uint64_t[len]. + The outparam res is meant to be `2*len` limbs in size, i.e. uint64_t[2*len]. +*/ +pub fn sqr(len: u32, a: &[u64], res: &mut [u64]) { + let mut tmp: Box<[u64]> = vec![0u64; 4u32.wrapping_mul(len) as usize].into_boxed_slice(); + super::base::bn_karatsuba_sqr_uint64(len, a, &mut tmp, res) +} + +#[inline] +fn bn_slow_precomp(len: u32, n: &[u64], mu: u64, r2: &[u64], a: &[u64], res: &mut [u64]) { + let mut a_mod: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let mut a1: Box<[u64]> = vec![0u64; len.wrapping_add(len) as usize].into_boxed_slice(); + ((&mut a1)[0usize..len.wrapping_add(len) as usize]) + .copy_from_slice(&a[0usize..len.wrapping_add(len) as usize]); + super::base::bn_almost_mont_reduction_u64(len, n, mu, &mut a1, &mut a_mod); + super::base::bn_to_mont_u64(len, n, mu, r2, &a_mod, res) +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be `2*len` limbs in size, i.e. uint64_t[2*len]. + The argument n and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • 1 < n + • n % 2 = 1 +*/ +pub fn r#mod(len: u32, n: &[u64], a: &[u64], res: &mut [u64]) -> bool { + let mut one: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut one)[0usize..len as usize]) + .copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u64 = (&acc)[0usize]; + let is_valid_m: u64 = m0 & m1; + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(len, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + let mut r2: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + super::base::bn_precomp_r2_mod_n_u64(len, nBits, n, &mut r2); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + super::bignum64::bn_slow_precomp(len, n, mu, &r2, a, res) + } else { + (res[0usize..len as usize]).copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime( + len: u32, + n: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) -> bool { + let is_valid_m: u64 = super::base::bn_check_mod_exp_u64(len, n, a, bBits, b); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(len, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + super::base::bn_mod_exp_vartime_u64(len, nBits, n, a, bBits, b, res) + } else { + (res[0usize..len as usize]).copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a, n and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime. + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime( + len: u32, + n: &[u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) -> bool { + let is_valid_m: u64 = super::base::bn_check_mod_exp_u64(len, n, a, bBits, b); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(len, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + super::base::bn_mod_exp_consttime_u64(len, nBits, n, a, bBits, b, res) + } else { + (res[0usize..len as usize]).copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The arguments a, n and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + + The function returns false if any of the following preconditions are violated, + true otherwise. + • n % 2 = 1 + • 1 < n + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime(len: u32, n: &[u64], a: &[u64], res: &mut [u64]) -> bool { + let mut one: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + ((&mut one)[0usize..len as usize]) + .copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()); + (&mut one)[0usize] = 1u64; + let bit0: u64 = n[0usize] & 1u64; + let m0: u64 = 0u64.wrapping_sub(bit0); + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let beq: u64 = fstar::uint64::eq_mask((&one)[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask((&one)[i as usize], n[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + let m1: u64 = (&acc)[0usize]; + let m00: u64 = m0 & m1; + let bn_zero: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let mut mask: [u64; 1] = [0xFFFFFFFFFFFFFFFFu64; 1usize]; + for i in 0u32..len { + let uu____0: u64 = fstar::uint64::eq_mask(a[i as usize], (&bn_zero)[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + } + let mask1: u64 = (&mask)[0usize]; + let res1: u64 = mask1; + let m10: u64 = res1; + let mut acc0: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], n[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], n[i as usize]); + (&mut acc0)[0usize] = beq & (&acc0)[0usize] | !beq & blt + } + let m2: u64 = (&acc0)[0usize]; + let is_valid_m: u64 = m00 & !m10 & m2; + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(len, n) as u32); + if is_valid_m == 0xFFFFFFFFFFFFFFFFu64 { + let mut n2: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let c0: u64 = lib::inttypes_intrinsics::sub_borrow_u64( + 0u64, + n[0usize], + 2u64, + &mut (&mut n2)[0usize..], + ); + let c: u64 = if 1u32 < len { + let a1: (&[u64], &[u64]) = n.split_at(1usize); + let res10: (&mut [u64], &mut [u64]) = n2.split_at_mut(1usize); + let mut c: [u64; 1] = [c0; 1usize]; + for i in 0u32..len.wrapping_sub(1u32).wrapping_div(4u32) { + let t1: u64 = a1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res10.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1); + let t10: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, 0u64, res_i0.1); + let t11: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, 0u64, res_i1.1); + let t12: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, 0u64, res_i2.1) + } + for i in + len.wrapping_sub(1u32).wrapping_div(4u32).wrapping_mul(4u32)..len.wrapping_sub(1u32) + { + let t1: u64 = a1.1[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res10.1.split_at_mut(i as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1) + } + let c1: u64 = (&c)[0usize]; + c1 + } else { + c0 + }; + lowstar::ignore::ignore::(c); + super::base::bn_mod_exp_vartime_u64(len, nBits, n, a, 64u32.wrapping_mul(len), &n2, res) + } else { + (res[0usize..len as usize]).copy_from_slice(&vec![0u64; len as usize].into_boxed_slice()) + }; + is_valid_m == 0xFFFFFFFFFFFFFFFFu64 +} + +/** +Heap-allocate and initialize a montgomery context. + + The argument n is meant to be `len` limbs in size, i.e. uint64_t[len]. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n % 2 = 1 + • 1 < n + + The caller will need to call Hacl_Bignum64_mont_ctx_free on the return value + to avoid memory leaks. +*/ +pub fn mont_ctx_init(len: u32, n: &[u64]) -> Box<[super::base::bn_mont_ctx_u64]> { + let mut r2: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let mut n1: Box<[u64]> = vec![0u64; len as usize].into_boxed_slice(); + let r21: &mut [u64] = &mut r2; + let n11: &mut [u64] = &mut n1; + (n11[0usize..len as usize]).copy_from_slice(&n[0usize..len as usize]); + let nBits: u32 = 64u32.wrapping_mul(super::bignum_base::bn_get_top_index_u64(len, n) as u32); + super::base::bn_precomp_r2_mod_n_u64(len, nBits, n, r21); + let mu: u64 = super::base::mod_inv_uint64(n[0usize]); + let res: super::base::bn_mont_ctx_u64 = super::base::bn_mont_ctx_u64 { + len, + n: (*n11).into(), + mu, + r2: (*r21).into(), + }; + let buf: Box<[super::base::bn_mont_ctx_u64]> = vec![res].into_boxed_slice(); + buf +} + +/** +Write `a mod n` in `res`. + + The argument a is meant to be `2*len` limbs in size, i.e. uint64_t[2*len]. + The outparam res is meant to be `len` limbs in size, i.e. uint64_t[len]. + The argument k is a montgomery context obtained through Hacl_Bignum64_mont_ctx_init. +*/ +pub fn mod_precomp(k: &[super::base::bn_mont_ctx_u64], a: &[u64], res: &mut [u64]) { + let len1: u32 = (k[0usize]).len; + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::bignum64::bn_slow_precomp(len1, n, mu, r2, a, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + The argument k is a montgomery context obtained through Hacl_Bignum64_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + The function is *NOT* constant-time on the argument b. See the + mod_exp_consttime_* functions for constant-time variants. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_vartime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + let len1: u32 = (k[0usize]).len; + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::base::bn_mod_exp_vartime_precomp_u64(len1, n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ b mod n` in `res`. + + The arguments a and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + The argument k is a montgomery context obtained through Hacl_Bignum64_mont_ctx_init. + + The argument b is a bignum of any size, and bBits is an upper bound on the + number of significant bits of b. A tighter bound results in faster execution + time. When in doubt, the number of bits for the bignum size is always a safe + default, e.g. if b is a 4096-bit bignum, bBits should be 4096. + + This function is constant-time over its argument b, at the cost of a slower + execution time than mod_exp_vartime_*. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • b < pow2 bBits + • a < n +*/ +pub fn mod_exp_consttime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + bBits: u32, + b: &[u64], + res: &mut [u64], +) { + let len1: u32 = (k[0usize]).len; + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + super::base::bn_mod_exp_consttime_precomp_u64(len1, n, mu, r2, a, bBits, b, res) +} + +/** +Write `a ^ (-1) mod n` in `res`. + + The argument a and the outparam res are meant to be `len` limbs in size, i.e. uint64_t[len]. + The argument k is a montgomery context obtained through Hacl_Bignum64_mont_ctx_init. + + Before calling this function, the caller will need to ensure that the following + preconditions are observed. + • n is a prime + • 0 < a + • a < n +*/ +pub fn mod_inv_prime_vartime_precomp( + k: &[super::base::bn_mont_ctx_u64], + a: &[u64], + res: &mut [u64], +) { + let len1: u32 = (k[0usize]).len; + let n: &[u64] = &(k[0usize]).n; + let mu: u64 = (k[0usize]).mu; + let r2: &[u64] = &(k[0usize]).r2; + let mut n2: Box<[u64]> = vec![0u64; len1 as usize].into_boxed_slice(); + let c0: u64 = + lib::inttypes_intrinsics::sub_borrow_u64(0u64, n[0usize], 2u64, &mut (&mut n2)[0usize..]); + let c: u64 = if 1u32 < len1 { + let a1: (&[u64], &[u64]) = n.split_at(1usize); + let res1: (&mut [u64], &mut [u64]) = n2.split_at_mut(1usize); + let mut c: [u64; 1] = [c0; 1usize]; + for i in 0u32..len1.wrapping_sub(1u32).wrapping_div(4u32) { + let t1: u64 = a1.1[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res1.1.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1); + let t10: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, 0u64, res_i0.1); + let t11: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, 0u64, res_i1.1); + let t12: u64 = a1.1[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, 0u64, res_i2.1) + } + for i in len1 + .wrapping_sub(1u32) + .wrapping_div(4u32) + .wrapping_mul(4u32)..len1.wrapping_sub(1u32) + { + let t1: u64 = a1.1[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res1.1.split_at_mut(i as usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, 0u64, res_i.1) + } + let c1: u64 = (&c)[0usize]; + c1 + } else { + c0 + }; + lowstar::ignore::ignore::(c); + super::base::bn_mod_exp_vartime_precomp_u64( + len1, + n, + mu, + r2, + a, + 64u32.wrapping_mul(len1), + &n2, + res, + ) +} + +/** +Load a bid-endian bignum from memory. + + The argument b points to `len` bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_be(len: u32, b: &[u8]) -> Box<[u64]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) > 536870911u32 { + [].into() + } else { + let mut res: Box<[u64]> = + vec![0u64; len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u64] = &mut res; + let res2: &mut [u64] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[tmpLen.wrapping_sub(len) as usize + ..tmpLen.wrapping_sub(len) as usize + len as usize]) + .copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..bnLen { + let u: u64 = lowstar::endianness::load64_be( + &(&tmp)[bnLen.wrapping_sub(i).wrapping_sub(1u32).wrapping_mul(8u32) as usize..], + ); + let x: u64 = u; + let os: (&mut [u64], &mut [u64]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Load a little-endian bignum from memory. + + The argument b points to `len` bytes of valid memory. + The function returns a heap-allocated bignum of size sufficient to hold the + result of loading b, or NULL if either the allocation failed, or the amount of + required memory would exceed 4GB. + + If the return value is non-null, clients must eventually call free(3) on it to + avoid memory leaks. +*/ +pub fn new_bn_from_bytes_le(len: u32, b: &[u8]) -> Box<[u64]> { + if len == 0u32 || len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) > 536870911u32 { + [].into() + } else { + let mut res: Box<[u64]> = + vec![0u64; len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) as usize] + .into_boxed_slice(); + if false { + res + } else { + let res1: &mut [u64] = &mut res; + let res2: &mut [u64] = res1; + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp)[0usize..len as usize]).copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32) { + let bj: (&[u8], &[u8]) = tmp.split_at(i.wrapping_mul(8u32) as usize); + let u: u64 = lowstar::endianness::load64_le(bj.1); + let r1: u64 = u; + let x: u64 = r1; + let os: (&mut [u64], &mut [u64]) = res2.split_at_mut(0usize); + os.1[i as usize] = x + } + (*res2).into() + } + } +} + +/** +Serialize a bignum into big-endian memory. + + The argument b points to a bignum of ⌈len / 8⌉ size. + The outparam res points to `len` bytes of valid memory. +*/ +pub fn bn_to_bytes_be(len: u32, b: &[u64], res: &mut [u8]) { + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + for i in 0u32..bnLen { + lowstar::endianness::store64_be( + &mut (&mut tmp)[i.wrapping_mul(8u32) as usize..], + b[bnLen.wrapping_sub(i).wrapping_sub(1u32) as usize], + ) + } + (res[0usize..len as usize]) + .copy_from_slice(&(&(&tmp)[tmpLen.wrapping_sub(len) as usize..])[0usize..len as usize]) +} + +/** +Serialize a bignum into little-endian memory. + + The argument b points to a bignum of ⌈len / 8⌉ size. + The outparam res points to `len` bytes of valid memory. +*/ +pub fn bn_to_bytes_le(len: u32, b: &[u64], res: &mut [u8]) { + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + for i in 0u32..bnLen { + lowstar::endianness::store64_le( + &mut (&mut tmp)[i.wrapping_mul(8u32) as usize..], + b[i as usize], + ) + } + (res[0usize..len as usize]).copy_from_slice(&(&(&tmp)[0usize..])[0usize..len as usize]) +} + +/** +Returns 2^64 - 1 if a < b, otherwise returns 0. + + The arguments a and b are meant to be `len` limbs in size, i.e. uint64_t[len]. +*/ +pub fn lt_mask(len: u32, a: &[u64], b: &[u64]) -> u64 { + let mut acc: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let beq: u64 = fstar::uint64::eq_mask(a[i as usize], b[i as usize]); + let blt: u64 = !fstar::uint64::gte_mask(a[i as usize], b[i as usize]); + (&mut acc)[0usize] = beq & (&acc)[0usize] | !beq & blt + } + (&acc)[0usize] +} + +/** +Returns 2^64 - 1 if a = b, otherwise returns 0. + + The arguments a and b are meant to be `len` limbs in size, i.e. uint64_t[len]. +*/ +pub fn eq_mask(len: u32, a: &[u64], b: &[u64]) -> u64 { + let mut mask: [u64; 1] = [0xFFFFFFFFFFFFFFFFu64; 1usize]; + for i in 0u32..len { + let uu____0: u64 = fstar::uint64::eq_mask(a[i as usize], b[i as usize]); + (&mut mask)[0usize] = uu____0 & (&mask)[0usize] + } + let mask1: u64 = (&mask)[0usize]; + mask1 +} diff --git a/hacl-rs/src/bignum/bignum_base.rs b/hacl-rs/src/bignum/bignum_base.rs new file mode 100644 index 000000000..5760b4fbd --- /dev/null +++ b/hacl-rs/src/bignum/bignum_base.rs @@ -0,0 +1,467 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use crate::fstar; +use crate::lowstar; +use crate::util as lib; + +#[inline] +pub(crate) fn mul_wide_add2_u32(a: u32, b: u32, c_in: u32, out: &mut [u32]) -> u32 { + let out0: u32 = out[0usize]; + let res: u64 = (a as u64) + .wrapping_mul(b as u64) + .wrapping_add(c_in as u64) + .wrapping_add(out0 as u64); + out[0usize] = res as u32; + res.wrapping_shr(32u32) as u32 +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +#[inline] +pub fn mul_wide_add2_u64(a: u64, b: u64, c_in: u64, out: &mut [u64]) -> u64 { + let out0: u64 = out[0usize]; + let res: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(a, b), + fstar::uint128::uint64_to_uint128(c_in), + ), + fstar::uint128::uint64_to_uint128(out0), + ); + out[0usize] = fstar::uint128::uint128_to_uint64(res); + fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(res, 64u32)) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_from_bytes_be_uint64(len: u32, b: &[u8], res: &mut [u64]) { + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + ((&mut tmp) + [tmpLen.wrapping_sub(len) as usize..tmpLen.wrapping_sub(len) as usize + len as usize]) + .copy_from_slice(&b[0usize..len as usize]); + for i in 0u32..bnLen { + let u: u64 = lowstar::endianness::load64_be( + &(&tmp)[bnLen.wrapping_sub(i).wrapping_sub(1u32).wrapping_mul(8u32) as usize..], + ); + let x: u64 = u; + let os: (&mut [u64], &mut [u64]) = res.split_at_mut(0usize); + os.1[i as usize] = x + } +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_to_bytes_be_uint64(len: u32, b: &[u64], res: &mut [u8]) { + let bnLen: u32 = len.wrapping_sub(1u32).wrapping_div(8u32).wrapping_add(1u32); + let tmpLen: u32 = 8u32.wrapping_mul(bnLen); + let mut tmp: Box<[u8]> = vec![0u8; tmpLen as usize].into_boxed_slice(); + for i in 0u32..bnLen { + lowstar::endianness::store64_be( + &mut (&mut tmp)[i.wrapping_mul(8u32) as usize..], + b[bnLen.wrapping_sub(i).wrapping_sub(1u32) as usize], + ) + } + (res[0usize..len as usize]) + .copy_from_slice(&(&(&tmp)[tmpLen.wrapping_sub(len) as usize..])[0usize..len as usize]) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_get_top_index_u32(len: u32, b: &[u32]) -> u32 { + let mut r#priv: [u32; 1] = [0u32; 1usize]; + for i in 0u32..len { + let mask: u32 = fstar::uint32::eq_mask(b[i as usize], 0u32); + (&mut r#priv)[0usize] = mask & (&r#priv)[0usize] | !mask & i + } + (&r#priv)[0usize] +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_get_top_index_u64(len: u32, b: &[u64]) -> u64 { + let mut r#priv: [u64; 1] = [0u64; 1usize]; + for i in 0u32..len { + let mask: u64 = fstar::uint64::eq_mask(b[i as usize], 0u64); + (&mut r#priv)[0usize] = mask & (&r#priv)[0usize] | !mask & i as u64 + } + (&r#priv)[0usize] +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +#[inline] +pub fn bn_get_bits_u32(len: u32, b: &[u32], i: u32, l: u32) -> u32 { + let i1: u32 = i.wrapping_div(32u32); + let j: u32 = i.wrapping_rem(32u32); + let p1: u32 = (b[i1 as usize]).wrapping_shr(j); + let ite: u32 = if i1.wrapping_add(1u32) < len && 0u32 < j { + p1 | (b[i1.wrapping_add(1u32) as usize]).wrapping_shl(32u32.wrapping_sub(j)) + } else { + p1 + }; + ite & 1u32.wrapping_shl(l).wrapping_sub(1u32) +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +#[inline] +pub fn bn_get_bits_u64(len: u32, b: &[u64], i: u32, l: u32) -> u64 { + let i1: u32 = i.wrapping_div(64u32); + let j: u32 = i.wrapping_rem(64u32); + let p1: u64 = (b[i1 as usize]).wrapping_shr(j); + let ite: u64 = if i1.wrapping_add(1u32) < len && 0u32 < j { + p1 | (b[i1.wrapping_add(1u32) as usize]).wrapping_shl(64u32.wrapping_sub(j)) + } else { + p1 + }; + ite & 1u64.wrapping_shl(l).wrapping_sub(1u64) +} + +pub(crate) fn bn_sub_eq_len_u32(aLen: u32, a: &[u32], b: &[u32], res: &mut [u32]) -> u32 { + let mut c: [u32; 1] = [0u32; 1usize]; + for i in 0u32..aLen.wrapping_div(4u32) { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t12, t22, res_i2.1) + } + for i in aLen.wrapping_div(4u32).wrapping_mul(4u32)..aLen { + let t1: u32 = a[i as usize]; + let t2: u32 = b[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u32((&c)[0usize], t1, t2, res_i.1) + } + (&c)[0usize] +} + +pub(crate) fn bn_sub_eq_len_u64(aLen: u32, a: &[u64], b: &[u64], res: &mut [u64]) -> u64 { + let mut c: [u64; 1] = [0u64; 1usize]; + for i in 0u32..aLen.wrapping_div(4u32) { + let t1: u64 = a[4u32.wrapping_mul(i) as usize]; + let t2: u64 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t12, t22, res_i2.1) + } + for i in aLen.wrapping_div(4u32).wrapping_mul(4u32)..aLen { + let t1: u64 = a[i as usize]; + let t2: u64 = b[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::sub_borrow_u64((&c)[0usize], t1, t2, res_i.1) + } + (&c)[0usize] +} + +pub(crate) fn bn_add_eq_len_u32(aLen: u32, a: &[u32], b: &[u32], res: &mut [u32]) -> u32 { + let mut c: [u32; 1] = [0u32; 1usize]; + for i in 0u32..aLen.wrapping_div(4u32) { + let t1: u32 = a[4u32.wrapping_mul(i) as usize]; + let t2: u32 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t1, t2, res_i.1); + let t10: u32 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u32 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t10, t20, res_i0.1); + let t11: u32 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u32 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t11, t21, res_i1.1); + let t12: u32 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u32 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t12, t22, res_i2.1) + } + for i in aLen.wrapping_div(4u32).wrapping_mul(4u32)..aLen { + let t1: u32 = a[i as usize]; + let t2: u32 = b[i as usize]; + let res_i: (&mut [u32], &mut [u32]) = res.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u32((&c)[0usize], t1, t2, res_i.1) + } + (&c)[0usize] +} + +/** +ATTENTION: this function is public, but is intended for internal use within this workspace; callers should not rely on the availability of this function, or its behavior! +*/ +pub fn bn_add_eq_len_u64(aLen: u32, a: &[u64], b: &[u64], res: &mut [u64]) -> u64 { + let mut c: [u64; 1] = [0u64; 1usize]; + for i in 0u32..aLen.wrapping_div(4u32) { + let t1: u64 = a[4u32.wrapping_mul(i) as usize]; + let t2: u64 = b[4u32.wrapping_mul(i) as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(4u32.wrapping_mul(i) as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t1, t2, res_i.1); + let t10: u64 = a[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let t20: u64 = b[4u32.wrapping_mul(i).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t10, t20, res_i0.1); + let t11: u64 = a[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let t21: u64 = b[4u32.wrapping_mul(i).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t11, t21, res_i1.1); + let t12: u64 = a[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let t22: u64 = b[4u32.wrapping_mul(i).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t12, t22, res_i2.1) + } + for i in aLen.wrapping_div(4u32).wrapping_mul(4u32)..aLen { + let t1: u64 = a[i as usize]; + let t2: u64 = b[i as usize]; + let res_i: (&mut [u64], &mut [u64]) = res.split_at_mut(i as usize); + (&mut c)[0usize] = lib::inttypes_intrinsics::add_carry_u64((&c)[0usize], t1, t2, res_i.1) + } + (&c)[0usize] +} + +#[inline] +pub(crate) fn bn_mul_u32(aLen: u32, a: &[u32], bLen: u32, b: &[u32], res: &mut [u32]) { + (res[0usize..aLen.wrapping_add(bLen) as usize]) + .copy_from_slice(&vec![0u32; aLen.wrapping_add(bLen) as usize].into_boxed_slice()); + for i in 0u32..bLen { + let bj: u32 = b[i as usize]; + let res_j: (&mut [u32], &mut [u32]) = res.split_at_mut(i as usize); + let mut c: [u32; 1] = [0u32; 1usize]; + for i0 in 0u32..aLen.wrapping_div(4u32) { + let a_i: u32 = a[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, bj, (&c)[0usize], res_i.1); + let a_i0: u32 = a[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, bj, (&c)[0usize], res_i0.1); + let a_i1: u32 = a[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, bj, (&c)[0usize], res_i1.1); + let a_i2: u32 = a[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, bj, (&c)[0usize], res_i2.1) + } + for i0 in aLen.wrapping_div(4u32).wrapping_mul(4u32)..aLen { + let a_i: u32 = a[i0 as usize]; + let res_i: (&mut [u32], &mut [u32]) = res_j.1.split_at_mut(i0 as usize); + (&mut c)[0usize] = super::bignum_base::mul_wide_add2_u32(a_i, bj, (&c)[0usize], res_i.1) + } + let r: u32 = (&c)[0usize]; + res[aLen.wrapping_add(i) as usize] = r + } +} + +#[inline] +pub(crate) fn bn_mul_u64(aLen: u32, a: &[u64], bLen: u32, b: &[u64], res: &mut [u64]) { + (res[0usize..aLen.wrapping_add(bLen) as usize]) + .copy_from_slice(&vec![0u64; aLen.wrapping_add(bLen) as usize].into_boxed_slice()); + for i in 0u32..bLen { + let bj: u64 = b[i as usize]; + let res_j: (&mut [u64], &mut [u64]) = res.split_at_mut(i as usize); + let mut c: [u64; 1] = [0u64; 1usize]; + for i0 in 0u32..aLen.wrapping_div(4u32) { + let a_i: u64 = a[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, bj, (&c)[0usize], res_i.1); + let a_i0: u64 = a[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, bj, (&c)[0usize], res_i0.1); + let a_i1: u64 = a[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, bj, (&c)[0usize], res_i1.1); + let a_i2: u64 = a[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, bj, (&c)[0usize], res_i2.1) + } + for i0 in aLen.wrapping_div(4u32).wrapping_mul(4u32)..aLen { + let a_i: u64 = a[i0 as usize]; + let res_i: (&mut [u64], &mut [u64]) = res_j.1.split_at_mut(i0 as usize); + (&mut c)[0usize] = super::bignum_base::mul_wide_add2_u64(a_i, bj, (&c)[0usize], res_i.1) + } + let r: u64 = (&c)[0usize]; + res[aLen.wrapping_add(i) as usize] = r + } +} + +#[inline] +pub(crate) fn bn_sqr_u32(aLen: u32, a: &[u32], res: &mut [u32]) { + (res[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&vec![0u32; aLen.wrapping_add(aLen) as usize].into_boxed_slice()); + for i in 0u32..aLen { + let a_j: u32 = a[i as usize]; + let ab: (&[u32], &[u32]) = a.split_at(0usize); + let res_j: (&mut [u32], &mut [u32]) = res.split_at_mut(i as usize); + let mut c: [u32; 1] = [0u32; 1usize]; + for i0 in 0u32..i.wrapping_div(4u32) { + let a_i: u32 = ab.1[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u32], &mut [u32]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, a_j, (&c)[0usize], res_i.1); + let a_i0: u32 = ab.1[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u32], &mut [u32]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i0, a_j, (&c)[0usize], res_i0.1); + let a_i1: u32 = ab.1[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u32], &mut [u32]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i1, a_j, (&c)[0usize], res_i1.1); + let a_i2: u32 = ab.1[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u32], &mut [u32]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i2, a_j, (&c)[0usize], res_i2.1) + } + for i0 in i.wrapping_div(4u32).wrapping_mul(4u32)..i { + let a_i: u32 = ab.1[i0 as usize]; + let res_i: (&mut [u32], &mut [u32]) = res_j.1.split_at_mut(i0 as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u32(a_i, a_j, (&c)[0usize], res_i.1) + } + let r: u32 = (&c)[0usize]; + res[i.wrapping_add(i) as usize] = r + } + let mut a_copy: Box<[u32]> = vec![0u32; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + let mut b_copy: Box<[u32]> = vec![0u32; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&res[0usize..aLen.wrapping_add(aLen) as usize]); + ((&mut b_copy)[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&res[0usize..aLen.wrapping_add(aLen) as usize]); + let r: u32 = + super::bignum_base::bn_add_eq_len_u32(aLen.wrapping_add(aLen), &a_copy, &b_copy, res); + let c0: u32 = r; + lowstar::ignore::ignore::(c0); + let mut tmp: Box<[u32]> = vec![0u32; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + for i in 0u32..aLen { + let res1: u64 = (a[i as usize] as u64).wrapping_mul(a[i as usize] as u64); + let hi: u32 = res1.wrapping_shr(32u32) as u32; + let lo: u32 = res1 as u32; + (&mut tmp)[2u32.wrapping_mul(i) as usize] = lo; + (&mut tmp)[2u32.wrapping_mul(i).wrapping_add(1u32) as usize] = hi + } + let mut a_copy0: Box<[u32]> = vec![0u32; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + let mut b_copy0: Box<[u32]> = vec![0u32; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + ((&mut a_copy0)[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&res[0usize..aLen.wrapping_add(aLen) as usize]); + ((&mut b_copy0)[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&(&tmp)[0usize..aLen.wrapping_add(aLen) as usize]); + let r0: u32 = + super::bignum_base::bn_add_eq_len_u32(aLen.wrapping_add(aLen), &a_copy0, &b_copy0, res); + let c1: u32 = r0; + lowstar::ignore::ignore::(c1) +} + +#[inline] +pub(crate) fn bn_sqr_u64(aLen: u32, a: &[u64], res: &mut [u64]) { + (res[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&vec![0u64; aLen.wrapping_add(aLen) as usize].into_boxed_slice()); + for i in 0u32..aLen { + let a_j: u64 = a[i as usize]; + let ab: (&[u64], &[u64]) = a.split_at(0usize); + let res_j: (&mut [u64], &mut [u64]) = res.split_at_mut(i as usize); + let mut c: [u64; 1] = [0u64; 1usize]; + for i0 in 0u32..i.wrapping_div(4u32) { + let a_i: u64 = ab.1[4u32.wrapping_mul(i0) as usize]; + let res_i: (&mut [u64], &mut [u64]) = + res_j.1.split_at_mut(4u32.wrapping_mul(i0) as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, a_j, (&c)[0usize], res_i.1); + let a_i0: u64 = ab.1[4u32.wrapping_mul(i0).wrapping_add(1u32) as usize]; + let res_i0: (&mut [u64], &mut [u64]) = res_i.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i0, a_j, (&c)[0usize], res_i0.1); + let a_i1: u64 = ab.1[4u32.wrapping_mul(i0).wrapping_add(2u32) as usize]; + let res_i1: (&mut [u64], &mut [u64]) = res_i0.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i1, a_j, (&c)[0usize], res_i1.1); + let a_i2: u64 = ab.1[4u32.wrapping_mul(i0).wrapping_add(3u32) as usize]; + let res_i2: (&mut [u64], &mut [u64]) = res_i1.1.split_at_mut(1usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i2, a_j, (&c)[0usize], res_i2.1) + } + for i0 in i.wrapping_div(4u32).wrapping_mul(4u32)..i { + let a_i: u64 = ab.1[i0 as usize]; + let res_i: (&mut [u64], &mut [u64]) = res_j.1.split_at_mut(i0 as usize); + (&mut c)[0usize] = + super::bignum_base::mul_wide_add2_u64(a_i, a_j, (&c)[0usize], res_i.1) + } + let r: u64 = (&c)[0usize]; + res[i.wrapping_add(i) as usize] = r + } + let mut a_copy: Box<[u64]> = vec![0u64; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + let mut b_copy: Box<[u64]> = vec![0u64; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + ((&mut a_copy)[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&res[0usize..aLen.wrapping_add(aLen) as usize]); + ((&mut b_copy)[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&res[0usize..aLen.wrapping_add(aLen) as usize]); + let r: u64 = + super::bignum_base::bn_add_eq_len_u64(aLen.wrapping_add(aLen), &a_copy, &b_copy, res); + let c0: u64 = r; + lowstar::ignore::ignore::(c0); + let mut tmp: Box<[u64]> = vec![0u64; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + for i in 0u32..aLen { + let res1: fstar::uint128::uint128 = fstar::uint128::mul_wide(a[i as usize], a[i as usize]); + let hi: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(res1, 64u32)); + let lo: u64 = fstar::uint128::uint128_to_uint64(res1); + (&mut tmp)[2u32.wrapping_mul(i) as usize] = lo; + (&mut tmp)[2u32.wrapping_mul(i).wrapping_add(1u32) as usize] = hi + } + let mut a_copy0: Box<[u64]> = vec![0u64; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + let mut b_copy0: Box<[u64]> = vec![0u64; aLen.wrapping_add(aLen) as usize].into_boxed_slice(); + ((&mut a_copy0)[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&res[0usize..aLen.wrapping_add(aLen) as usize]); + ((&mut b_copy0)[0usize..aLen.wrapping_add(aLen) as usize]) + .copy_from_slice(&(&tmp)[0usize..aLen.wrapping_add(aLen) as usize]); + let r0: u64 = + super::bignum_base::bn_add_eq_len_u64(aLen.wrapping_add(aLen), &a_copy0, &b_copy0, res); + let c1: u64 = r0; + lowstar::ignore::ignore::(c1) +} diff --git a/hacl-rs/src/bignum25519_51.rs b/hacl-rs/src/bignum25519_51.rs new file mode 100644 index 000000000..28e3324c9 --- /dev/null +++ b/hacl-rs/src/bignum25519_51.rs @@ -0,0 +1,726 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_macros as krml; + +use crate::fstar; +use crate::lowstar; + +#[inline] +pub fn fadd(out: &mut [u64], f1: &[u64], f2: &[u64]) { + let f10: u64 = f1[0usize]; + let f20: u64 = f2[0usize]; + let f11: u64 = f1[1usize]; + let f21: u64 = f2[1usize]; + let f12: u64 = f1[2usize]; + let f22: u64 = f2[2usize]; + let f13: u64 = f1[3usize]; + let f23: u64 = f2[3usize]; + let f14: u64 = f1[4usize]; + let f24: u64 = f2[4usize]; + out[0usize] = f10.wrapping_add(f20); + out[1usize] = f11.wrapping_add(f21); + out[2usize] = f12.wrapping_add(f22); + out[3usize] = f13.wrapping_add(f23); + out[4usize] = f14.wrapping_add(f24) +} + +#[inline] +pub fn fsub(out: &mut [u64], f1: &[u64], f2: &[u64]) { + let f10: u64 = f1[0usize]; + let f20: u64 = f2[0usize]; + let f11: u64 = f1[1usize]; + let f21: u64 = f2[1usize]; + let f12: u64 = f1[2usize]; + let f22: u64 = f2[2usize]; + let f13: u64 = f1[3usize]; + let f23: u64 = f2[3usize]; + let f14: u64 = f1[4usize]; + let f24: u64 = f2[4usize]; + out[0usize] = f10.wrapping_add(0x3fffffffffff68u64).wrapping_sub(f20); + out[1usize] = f11.wrapping_add(0x3ffffffffffff8u64).wrapping_sub(f21); + out[2usize] = f12.wrapping_add(0x3ffffffffffff8u64).wrapping_sub(f22); + out[3usize] = f13.wrapping_add(0x3ffffffffffff8u64).wrapping_sub(f23); + out[4usize] = f14.wrapping_add(0x3ffffffffffff8u64).wrapping_sub(f24) +} + +#[inline] +pub fn fmul(out: &mut [u64], f1: &[u64], f2: &[u64], uu___: &[fstar::uint128::uint128]) { + lowstar::ignore::ignore::<&[fstar::uint128::uint128]>(uu___); + let f10: u64 = f1[0usize]; + let f11: u64 = f1[1usize]; + let f12: u64 = f1[2usize]; + let f13: u64 = f1[3usize]; + let f14: u64 = f1[4usize]; + let f20: u64 = f2[0usize]; + let f21: u64 = f2[1usize]; + let f22: u64 = f2[2usize]; + let f23: u64 = f2[3usize]; + let f24: u64 = f2[4usize]; + let tmp1: u64 = f21.wrapping_mul(19u64); + let tmp2: u64 = f22.wrapping_mul(19u64); + let tmp3: u64 = f23.wrapping_mul(19u64); + let tmp4: u64 = f24.wrapping_mul(19u64); + let o0: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f20); + let o1: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f21); + let o2: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f22); + let o3: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f23); + let o4: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f24); + let o01: fstar::uint128::uint128 = fstar::uint128::add(o0, fstar::uint128::mul_wide(f11, tmp4)); + let o11: fstar::uint128::uint128 = fstar::uint128::add(o1, fstar::uint128::mul_wide(f11, f20)); + let o21: fstar::uint128::uint128 = fstar::uint128::add(o2, fstar::uint128::mul_wide(f11, f21)); + let o31: fstar::uint128::uint128 = fstar::uint128::add(o3, fstar::uint128::mul_wide(f11, f22)); + let o41: fstar::uint128::uint128 = fstar::uint128::add(o4, fstar::uint128::mul_wide(f11, f23)); + let o02: fstar::uint128::uint128 = + fstar::uint128::add(o01, fstar::uint128::mul_wide(f12, tmp3)); + let o12: fstar::uint128::uint128 = + fstar::uint128::add(o11, fstar::uint128::mul_wide(f12, tmp4)); + let o22: fstar::uint128::uint128 = fstar::uint128::add(o21, fstar::uint128::mul_wide(f12, f20)); + let o32: fstar::uint128::uint128 = fstar::uint128::add(o31, fstar::uint128::mul_wide(f12, f21)); + let o42: fstar::uint128::uint128 = fstar::uint128::add(o41, fstar::uint128::mul_wide(f12, f22)); + let o03: fstar::uint128::uint128 = + fstar::uint128::add(o02, fstar::uint128::mul_wide(f13, tmp2)); + let o13: fstar::uint128::uint128 = + fstar::uint128::add(o12, fstar::uint128::mul_wide(f13, tmp3)); + let o23: fstar::uint128::uint128 = + fstar::uint128::add(o22, fstar::uint128::mul_wide(f13, tmp4)); + let o33: fstar::uint128::uint128 = fstar::uint128::add(o32, fstar::uint128::mul_wide(f13, f20)); + let o43: fstar::uint128::uint128 = fstar::uint128::add(o42, fstar::uint128::mul_wide(f13, f21)); + let o04: fstar::uint128::uint128 = + fstar::uint128::add(o03, fstar::uint128::mul_wide(f14, tmp1)); + let o14: fstar::uint128::uint128 = + fstar::uint128::add(o13, fstar::uint128::mul_wide(f14, tmp2)); + let o24: fstar::uint128::uint128 = + fstar::uint128::add(o23, fstar::uint128::mul_wide(f14, tmp3)); + let o34: fstar::uint128::uint128 = + fstar::uint128::add(o33, fstar::uint128::mul_wide(f14, tmp4)); + let o44: fstar::uint128::uint128 = fstar::uint128::add(o43, fstar::uint128::mul_wide(f14, f20)); + let tmp_w0: fstar::uint128::uint128 = o04; + let tmp_w1: fstar::uint128::uint128 = o14; + let tmp_w2: fstar::uint128::uint128 = o24; + let tmp_w3: fstar::uint128::uint128 = o34; + let tmp_w4: fstar::uint128::uint128 = o44; + let l·: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w0, fstar::uint128::uint64_to_uint128(0u64)); + let tmp01: u64 = fstar::uint128::uint128_to_uint64(l·) & 0x7ffffffffffffu64; + let c0: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·, 51u32)); + let l·0: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w1, fstar::uint128::uint64_to_uint128(c0)); + let tmp11: u64 = fstar::uint128::uint128_to_uint64(l·0) & 0x7ffffffffffffu64; + let c1: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·0, 51u32)); + let l·1: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w2, fstar::uint128::uint64_to_uint128(c1)); + let tmp21: u64 = fstar::uint128::uint128_to_uint64(l·1) & 0x7ffffffffffffu64; + let c2: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·1, 51u32)); + let l·2: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w3, fstar::uint128::uint64_to_uint128(c2)); + let tmp31: u64 = fstar::uint128::uint128_to_uint64(l·2) & 0x7ffffffffffffu64; + let c3: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·2, 51u32)); + let l·3: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w4, fstar::uint128::uint64_to_uint128(c3)); + let tmp41: u64 = fstar::uint128::uint128_to_uint64(l·3) & 0x7ffffffffffffu64; + let c4: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·3, 51u32)); + let l·4: u64 = tmp01.wrapping_add(c4.wrapping_mul(19u64)); + let tmp0·: u64 = l·4 & 0x7ffffffffffffu64; + let c5: u64 = l·4.wrapping_shr(51u32); + let o00: u64 = tmp0·; + let o10: u64 = tmp11.wrapping_add(c5); + let o20: u64 = tmp21; + let o30: u64 = tmp31; + let o40: u64 = tmp41; + out[0usize] = o00; + out[1usize] = o10; + out[2usize] = o20; + out[3usize] = o30; + out[4usize] = o40 +} + +#[inline] +pub fn fmul2(out: &mut [u64], f1: &[u64], f2: &[u64], uu___: &[fstar::uint128::uint128]) { + lowstar::ignore::ignore::<&[fstar::uint128::uint128]>(uu___); + let f10: u64 = f1[0usize]; + let f11: u64 = f1[1usize]; + let f12: u64 = f1[2usize]; + let f13: u64 = f1[3usize]; + let f14: u64 = f1[4usize]; + let f20: u64 = f2[0usize]; + let f21: u64 = f2[1usize]; + let f22: u64 = f2[2usize]; + let f23: u64 = f2[3usize]; + let f24: u64 = f2[4usize]; + let f30: u64 = f1[5usize]; + let f31: u64 = f1[6usize]; + let f32: u64 = f1[7usize]; + let f33: u64 = f1[8usize]; + let f34: u64 = f1[9usize]; + let f40: u64 = f2[5usize]; + let f41: u64 = f2[6usize]; + let f42: u64 = f2[7usize]; + let f43: u64 = f2[8usize]; + let f44: u64 = f2[9usize]; + let tmp11: u64 = f21.wrapping_mul(19u64); + let tmp12: u64 = f22.wrapping_mul(19u64); + let tmp13: u64 = f23.wrapping_mul(19u64); + let tmp14: u64 = f24.wrapping_mul(19u64); + let tmp21: u64 = f41.wrapping_mul(19u64); + let tmp22: u64 = f42.wrapping_mul(19u64); + let tmp23: u64 = f43.wrapping_mul(19u64); + let tmp24: u64 = f44.wrapping_mul(19u64); + let o0: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f20); + let o1: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f21); + let o2: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f22); + let o3: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f23); + let o4: fstar::uint128::uint128 = fstar::uint128::mul_wide(f10, f24); + let o01: fstar::uint128::uint128 = + fstar::uint128::add(o0, fstar::uint128::mul_wide(f11, tmp14)); + let o11: fstar::uint128::uint128 = fstar::uint128::add(o1, fstar::uint128::mul_wide(f11, f20)); + let o21: fstar::uint128::uint128 = fstar::uint128::add(o2, fstar::uint128::mul_wide(f11, f21)); + let o31: fstar::uint128::uint128 = fstar::uint128::add(o3, fstar::uint128::mul_wide(f11, f22)); + let o41: fstar::uint128::uint128 = fstar::uint128::add(o4, fstar::uint128::mul_wide(f11, f23)); + let o02: fstar::uint128::uint128 = + fstar::uint128::add(o01, fstar::uint128::mul_wide(f12, tmp13)); + let o12: fstar::uint128::uint128 = + fstar::uint128::add(o11, fstar::uint128::mul_wide(f12, tmp14)); + let o22: fstar::uint128::uint128 = fstar::uint128::add(o21, fstar::uint128::mul_wide(f12, f20)); + let o32: fstar::uint128::uint128 = fstar::uint128::add(o31, fstar::uint128::mul_wide(f12, f21)); + let o42: fstar::uint128::uint128 = fstar::uint128::add(o41, fstar::uint128::mul_wide(f12, f22)); + let o03: fstar::uint128::uint128 = + fstar::uint128::add(o02, fstar::uint128::mul_wide(f13, tmp12)); + let o13: fstar::uint128::uint128 = + fstar::uint128::add(o12, fstar::uint128::mul_wide(f13, tmp13)); + let o23: fstar::uint128::uint128 = + fstar::uint128::add(o22, fstar::uint128::mul_wide(f13, tmp14)); + let o33: fstar::uint128::uint128 = fstar::uint128::add(o32, fstar::uint128::mul_wide(f13, f20)); + let o43: fstar::uint128::uint128 = fstar::uint128::add(o42, fstar::uint128::mul_wide(f13, f21)); + let o04: fstar::uint128::uint128 = + fstar::uint128::add(o03, fstar::uint128::mul_wide(f14, tmp11)); + let o14: fstar::uint128::uint128 = + fstar::uint128::add(o13, fstar::uint128::mul_wide(f14, tmp12)); + let o24: fstar::uint128::uint128 = + fstar::uint128::add(o23, fstar::uint128::mul_wide(f14, tmp13)); + let o34: fstar::uint128::uint128 = + fstar::uint128::add(o33, fstar::uint128::mul_wide(f14, tmp14)); + let o44: fstar::uint128::uint128 = fstar::uint128::add(o43, fstar::uint128::mul_wide(f14, f20)); + let tmp_w10: fstar::uint128::uint128 = o04; + let tmp_w11: fstar::uint128::uint128 = o14; + let tmp_w12: fstar::uint128::uint128 = o24; + let tmp_w13: fstar::uint128::uint128 = o34; + let tmp_w14: fstar::uint128::uint128 = o44; + let o00: fstar::uint128::uint128 = fstar::uint128::mul_wide(f30, f40); + let o10: fstar::uint128::uint128 = fstar::uint128::mul_wide(f30, f41); + let o20: fstar::uint128::uint128 = fstar::uint128::mul_wide(f30, f42); + let o30: fstar::uint128::uint128 = fstar::uint128::mul_wide(f30, f43); + let o40: fstar::uint128::uint128 = fstar::uint128::mul_wide(f30, f44); + let o010: fstar::uint128::uint128 = + fstar::uint128::add(o00, fstar::uint128::mul_wide(f31, tmp24)); + let o110: fstar::uint128::uint128 = + fstar::uint128::add(o10, fstar::uint128::mul_wide(f31, f40)); + let o210: fstar::uint128::uint128 = + fstar::uint128::add(o20, fstar::uint128::mul_wide(f31, f41)); + let o310: fstar::uint128::uint128 = + fstar::uint128::add(o30, fstar::uint128::mul_wide(f31, f42)); + let o410: fstar::uint128::uint128 = + fstar::uint128::add(o40, fstar::uint128::mul_wide(f31, f43)); + let o020: fstar::uint128::uint128 = + fstar::uint128::add(o010, fstar::uint128::mul_wide(f32, tmp23)); + let o120: fstar::uint128::uint128 = + fstar::uint128::add(o110, fstar::uint128::mul_wide(f32, tmp24)); + let o220: fstar::uint128::uint128 = + fstar::uint128::add(o210, fstar::uint128::mul_wide(f32, f40)); + let o320: fstar::uint128::uint128 = + fstar::uint128::add(o310, fstar::uint128::mul_wide(f32, f41)); + let o420: fstar::uint128::uint128 = + fstar::uint128::add(o410, fstar::uint128::mul_wide(f32, f42)); + let o030: fstar::uint128::uint128 = + fstar::uint128::add(o020, fstar::uint128::mul_wide(f33, tmp22)); + let o130: fstar::uint128::uint128 = + fstar::uint128::add(o120, fstar::uint128::mul_wide(f33, tmp23)); + let o230: fstar::uint128::uint128 = + fstar::uint128::add(o220, fstar::uint128::mul_wide(f33, tmp24)); + let o330: fstar::uint128::uint128 = + fstar::uint128::add(o320, fstar::uint128::mul_wide(f33, f40)); + let o430: fstar::uint128::uint128 = + fstar::uint128::add(o420, fstar::uint128::mul_wide(f33, f41)); + let o040: fstar::uint128::uint128 = + fstar::uint128::add(o030, fstar::uint128::mul_wide(f34, tmp21)); + let o140: fstar::uint128::uint128 = + fstar::uint128::add(o130, fstar::uint128::mul_wide(f34, tmp22)); + let o240: fstar::uint128::uint128 = + fstar::uint128::add(o230, fstar::uint128::mul_wide(f34, tmp23)); + let o340: fstar::uint128::uint128 = + fstar::uint128::add(o330, fstar::uint128::mul_wide(f34, tmp24)); + let o440: fstar::uint128::uint128 = + fstar::uint128::add(o430, fstar::uint128::mul_wide(f34, f40)); + let tmp_w20: fstar::uint128::uint128 = o040; + let tmp_w21: fstar::uint128::uint128 = o140; + let tmp_w22: fstar::uint128::uint128 = o240; + let tmp_w23: fstar::uint128::uint128 = o340; + let tmp_w24: fstar::uint128::uint128 = o440; + let l·: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w10, fstar::uint128::uint64_to_uint128(0u64)); + let tmp0: u64 = fstar::uint128::uint128_to_uint64(l·) & 0x7ffffffffffffu64; + let c0: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·, 51u32)); + let l·0: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w11, fstar::uint128::uint64_to_uint128(c0)); + let tmp1: u64 = fstar::uint128::uint128_to_uint64(l·0) & 0x7ffffffffffffu64; + let c1: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·0, 51u32)); + let l·1: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w12, fstar::uint128::uint64_to_uint128(c1)); + let tmp2: u64 = fstar::uint128::uint128_to_uint64(l·1) & 0x7ffffffffffffu64; + let c2: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·1, 51u32)); + let l·2: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w13, fstar::uint128::uint64_to_uint128(c2)); + let tmp3: u64 = fstar::uint128::uint128_to_uint64(l·2) & 0x7ffffffffffffu64; + let c3: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·2, 51u32)); + let l·3: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w14, fstar::uint128::uint64_to_uint128(c3)); + let tmp4: u64 = fstar::uint128::uint128_to_uint64(l·3) & 0x7ffffffffffffu64; + let c4: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·3, 51u32)); + let l·4: u64 = tmp0.wrapping_add(c4.wrapping_mul(19u64)); + let tmp0·: u64 = l·4 & 0x7ffffffffffffu64; + let c5: u64 = l·4.wrapping_shr(51u32); + let o100: u64 = tmp0·; + let o111: u64 = tmp1.wrapping_add(c5); + let o121: u64 = tmp2; + let o131: u64 = tmp3; + let o141: u64 = tmp4; + let l·5: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w20, fstar::uint128::uint64_to_uint128(0u64)); + let tmp00: u64 = fstar::uint128::uint128_to_uint64(l·5) & 0x7ffffffffffffu64; + let c00: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·5, 51u32)); + let l·6: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w21, fstar::uint128::uint64_to_uint128(c00)); + let tmp10: u64 = fstar::uint128::uint128_to_uint64(l·6) & 0x7ffffffffffffu64; + let c10: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·6, 51u32)); + let l·7: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w22, fstar::uint128::uint64_to_uint128(c10)); + let tmp20: u64 = fstar::uint128::uint128_to_uint64(l·7) & 0x7ffffffffffffu64; + let c20: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·7, 51u32)); + let l·8: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w23, fstar::uint128::uint64_to_uint128(c20)); + let tmp30: u64 = fstar::uint128::uint128_to_uint64(l·8) & 0x7ffffffffffffu64; + let c30: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·8, 51u32)); + let l·9: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w24, fstar::uint128::uint64_to_uint128(c30)); + let tmp40: u64 = fstar::uint128::uint128_to_uint64(l·9) & 0x7ffffffffffffu64; + let c40: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·9, 51u32)); + let l·10: u64 = tmp00.wrapping_add(c40.wrapping_mul(19u64)); + let tmp0·0: u64 = l·10 & 0x7ffffffffffffu64; + let c50: u64 = l·10.wrapping_shr(51u32); + let o200: u64 = tmp0·0; + let o211: u64 = tmp10.wrapping_add(c50); + let o221: u64 = tmp20; + let o231: u64 = tmp30; + let o241: u64 = tmp40; + let o101: u64 = o100; + let o112: u64 = o111; + let o122: u64 = o121; + let o132: u64 = o131; + let o142: u64 = o141; + let o201: u64 = o200; + let o212: u64 = o211; + let o222: u64 = o221; + let o232: u64 = o231; + let o242: u64 = o241; + out[0usize] = o101; + out[1usize] = o112; + out[2usize] = o122; + out[3usize] = o132; + out[4usize] = o142; + out[5usize] = o201; + out[6usize] = o212; + out[7usize] = o222; + out[8usize] = o232; + out[9usize] = o242 +} + +#[inline] +pub fn fmul1(out: &mut [u64], f1: &[u64], f2: u64) { + let f10: u64 = f1[0usize]; + let f11: u64 = f1[1usize]; + let f12: u64 = f1[2usize]; + let f13: u64 = f1[3usize]; + let f14: u64 = f1[4usize]; + let tmp_w0: fstar::uint128::uint128 = fstar::uint128::mul_wide(f2, f10); + let tmp_w1: fstar::uint128::uint128 = fstar::uint128::mul_wide(f2, f11); + let tmp_w2: fstar::uint128::uint128 = fstar::uint128::mul_wide(f2, f12); + let tmp_w3: fstar::uint128::uint128 = fstar::uint128::mul_wide(f2, f13); + let tmp_w4: fstar::uint128::uint128 = fstar::uint128::mul_wide(f2, f14); + let l·: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w0, fstar::uint128::uint64_to_uint128(0u64)); + let tmp0: u64 = fstar::uint128::uint128_to_uint64(l·) & 0x7ffffffffffffu64; + let c0: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·, 51u32)); + let l·0: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w1, fstar::uint128::uint64_to_uint128(c0)); + let tmp1: u64 = fstar::uint128::uint128_to_uint64(l·0) & 0x7ffffffffffffu64; + let c1: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·0, 51u32)); + let l·1: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w2, fstar::uint128::uint64_to_uint128(c1)); + let tmp2: u64 = fstar::uint128::uint128_to_uint64(l·1) & 0x7ffffffffffffu64; + let c2: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·1, 51u32)); + let l·2: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w3, fstar::uint128::uint64_to_uint128(c2)); + let tmp3: u64 = fstar::uint128::uint128_to_uint64(l·2) & 0x7ffffffffffffu64; + let c3: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·2, 51u32)); + let l·3: fstar::uint128::uint128 = + fstar::uint128::add(tmp_w4, fstar::uint128::uint64_to_uint128(c3)); + let tmp4: u64 = fstar::uint128::uint128_to_uint64(l·3) & 0x7ffffffffffffu64; + let c4: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·3, 51u32)); + let l·4: u64 = tmp0.wrapping_add(c4.wrapping_mul(19u64)); + let tmp0·: u64 = l·4 & 0x7ffffffffffffu64; + let c5: u64 = l·4.wrapping_shr(51u32); + let o0: u64 = tmp0·; + let o1: u64 = tmp1.wrapping_add(c5); + let o2: u64 = tmp2; + let o3: u64 = tmp3; + let o4: u64 = tmp4; + out[0usize] = o0; + out[1usize] = o1; + out[2usize] = o2; + out[3usize] = o3; + out[4usize] = o4 +} + +#[inline] +pub fn fsqr(out: &mut [u64], f: &[u64], uu___: &[fstar::uint128::uint128]) { + lowstar::ignore::ignore::<&[fstar::uint128::uint128]>(uu___); + let f0: u64 = f[0usize]; + let f1: u64 = f[1usize]; + let f2: u64 = f[2usize]; + let f3: u64 = f[3usize]; + let f4: u64 = f[4usize]; + let d0: u64 = 2u64.wrapping_mul(f0); + let d1: u64 = 2u64.wrapping_mul(f1); + let d2: u64 = 38u64.wrapping_mul(f2); + let d3: u64 = 19u64.wrapping_mul(f3); + let d419: u64 = 19u64.wrapping_mul(f4); + let d4: u64 = 2u64.wrapping_mul(d419); + let s0: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(f0, f0), + fstar::uint128::mul_wide(d4, f1), + ), + fstar::uint128::mul_wide(d2, f3), + ); + let s1: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d0, f1), + fstar::uint128::mul_wide(d4, f2), + ), + fstar::uint128::mul_wide(d3, f3), + ); + let s2: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d0, f2), + fstar::uint128::mul_wide(f1, f1), + ), + fstar::uint128::mul_wide(d4, f3), + ); + let s3: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d0, f3), + fstar::uint128::mul_wide(d1, f2), + ), + fstar::uint128::mul_wide(f4, d419), + ); + let s4: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d0, f4), + fstar::uint128::mul_wide(d1, f3), + ), + fstar::uint128::mul_wide(f2, f2), + ); + let o0: fstar::uint128::uint128 = s0; + let o1: fstar::uint128::uint128 = s1; + let o2: fstar::uint128::uint128 = s2; + let o3: fstar::uint128::uint128 = s3; + let o4: fstar::uint128::uint128 = s4; + let l·: fstar::uint128::uint128 = + fstar::uint128::add(o0, fstar::uint128::uint64_to_uint128(0u64)); + let tmp0: u64 = fstar::uint128::uint128_to_uint64(l·) & 0x7ffffffffffffu64; + let c0: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·, 51u32)); + let l·0: fstar::uint128::uint128 = + fstar::uint128::add(o1, fstar::uint128::uint64_to_uint128(c0)); + let tmp1: u64 = fstar::uint128::uint128_to_uint64(l·0) & 0x7ffffffffffffu64; + let c1: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·0, 51u32)); + let l·1: fstar::uint128::uint128 = + fstar::uint128::add(o2, fstar::uint128::uint64_to_uint128(c1)); + let tmp2: u64 = fstar::uint128::uint128_to_uint64(l·1) & 0x7ffffffffffffu64; + let c2: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·1, 51u32)); + let l·2: fstar::uint128::uint128 = + fstar::uint128::add(o3, fstar::uint128::uint64_to_uint128(c2)); + let tmp3: u64 = fstar::uint128::uint128_to_uint64(l·2) & 0x7ffffffffffffu64; + let c3: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·2, 51u32)); + let l·3: fstar::uint128::uint128 = + fstar::uint128::add(o4, fstar::uint128::uint64_to_uint128(c3)); + let tmp4: u64 = fstar::uint128::uint128_to_uint64(l·3) & 0x7ffffffffffffu64; + let c4: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·3, 51u32)); + let l·4: u64 = tmp0.wrapping_add(c4.wrapping_mul(19u64)); + let tmp0·: u64 = l·4 & 0x7ffffffffffffu64; + let c5: u64 = l·4.wrapping_shr(51u32); + let o00: u64 = tmp0·; + let o10: u64 = tmp1.wrapping_add(c5); + let o20: u64 = tmp2; + let o30: u64 = tmp3; + let o40: u64 = tmp4; + out[0usize] = o00; + out[1usize] = o10; + out[2usize] = o20; + out[3usize] = o30; + out[4usize] = o40 +} + +#[inline] +pub fn fsqr2(out: &mut [u64], f: &[u64], uu___: &[fstar::uint128::uint128]) { + lowstar::ignore::ignore::<&[fstar::uint128::uint128]>(uu___); + let f10: u64 = f[0usize]; + let f11: u64 = f[1usize]; + let f12: u64 = f[2usize]; + let f13: u64 = f[3usize]; + let f14: u64 = f[4usize]; + let f20: u64 = f[5usize]; + let f21: u64 = f[6usize]; + let f22: u64 = f[7usize]; + let f23: u64 = f[8usize]; + let f24: u64 = f[9usize]; + let d0: u64 = 2u64.wrapping_mul(f10); + let d1: u64 = 2u64.wrapping_mul(f11); + let d2: u64 = 38u64.wrapping_mul(f12); + let d3: u64 = 19u64.wrapping_mul(f13); + let d419: u64 = 19u64.wrapping_mul(f14); + let d4: u64 = 2u64.wrapping_mul(d419); + let s0: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(f10, f10), + fstar::uint128::mul_wide(d4, f11), + ), + fstar::uint128::mul_wide(d2, f13), + ); + let s1: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d0, f11), + fstar::uint128::mul_wide(d4, f12), + ), + fstar::uint128::mul_wide(d3, f13), + ); + let s2: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d0, f12), + fstar::uint128::mul_wide(f11, f11), + ), + fstar::uint128::mul_wide(d4, f13), + ); + let s3: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d0, f13), + fstar::uint128::mul_wide(d1, f12), + ), + fstar::uint128::mul_wide(f14, d419), + ); + let s4: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d0, f14), + fstar::uint128::mul_wide(d1, f13), + ), + fstar::uint128::mul_wide(f12, f12), + ); + let o10: fstar::uint128::uint128 = s0; + let o11: fstar::uint128::uint128 = s1; + let o12: fstar::uint128::uint128 = s2; + let o13: fstar::uint128::uint128 = s3; + let o14: fstar::uint128::uint128 = s4; + let d00: u64 = 2u64.wrapping_mul(f20); + let d10: u64 = 2u64.wrapping_mul(f21); + let d20: u64 = 38u64.wrapping_mul(f22); + let d30: u64 = 19u64.wrapping_mul(f23); + let d4190: u64 = 19u64.wrapping_mul(f24); + let d40: u64 = 2u64.wrapping_mul(d4190); + let s00: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(f20, f20), + fstar::uint128::mul_wide(d40, f21), + ), + fstar::uint128::mul_wide(d20, f23), + ); + let s10: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d00, f21), + fstar::uint128::mul_wide(d40, f22), + ), + fstar::uint128::mul_wide(d30, f23), + ); + let s20: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d00, f22), + fstar::uint128::mul_wide(f21, f21), + ), + fstar::uint128::mul_wide(d40, f23), + ); + let s30: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d00, f23), + fstar::uint128::mul_wide(d10, f22), + ), + fstar::uint128::mul_wide(f24, d4190), + ); + let s40: fstar::uint128::uint128 = fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::mul_wide(d00, f24), + fstar::uint128::mul_wide(d10, f23), + ), + fstar::uint128::mul_wide(f22, f22), + ); + let o20: fstar::uint128::uint128 = s00; + let o21: fstar::uint128::uint128 = s10; + let o22: fstar::uint128::uint128 = s20; + let o23: fstar::uint128::uint128 = s30; + let o24: fstar::uint128::uint128 = s40; + let l·: fstar::uint128::uint128 = + fstar::uint128::add(o10, fstar::uint128::uint64_to_uint128(0u64)); + let tmp0: u64 = fstar::uint128::uint128_to_uint64(l·) & 0x7ffffffffffffu64; + let c0: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·, 51u32)); + let l·0: fstar::uint128::uint128 = + fstar::uint128::add(o11, fstar::uint128::uint64_to_uint128(c0)); + let tmp1: u64 = fstar::uint128::uint128_to_uint64(l·0) & 0x7ffffffffffffu64; + let c1: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·0, 51u32)); + let l·1: fstar::uint128::uint128 = + fstar::uint128::add(o12, fstar::uint128::uint64_to_uint128(c1)); + let tmp2: u64 = fstar::uint128::uint128_to_uint64(l·1) & 0x7ffffffffffffu64; + let c2: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·1, 51u32)); + let l·2: fstar::uint128::uint128 = + fstar::uint128::add(o13, fstar::uint128::uint64_to_uint128(c2)); + let tmp3: u64 = fstar::uint128::uint128_to_uint64(l·2) & 0x7ffffffffffffu64; + let c3: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·2, 51u32)); + let l·3: fstar::uint128::uint128 = + fstar::uint128::add(o14, fstar::uint128::uint64_to_uint128(c3)); + let tmp4: u64 = fstar::uint128::uint128_to_uint64(l·3) & 0x7ffffffffffffu64; + let c4: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·3, 51u32)); + let l·4: u64 = tmp0.wrapping_add(c4.wrapping_mul(19u64)); + let tmp0·: u64 = l·4 & 0x7ffffffffffffu64; + let c5: u64 = l·4.wrapping_shr(51u32); + let o101: u64 = tmp0·; + let o111: u64 = tmp1.wrapping_add(c5); + let o121: u64 = tmp2; + let o131: u64 = tmp3; + let o141: u64 = tmp4; + let l·5: fstar::uint128::uint128 = + fstar::uint128::add(o20, fstar::uint128::uint64_to_uint128(0u64)); + let tmp00: u64 = fstar::uint128::uint128_to_uint64(l·5) & 0x7ffffffffffffu64; + let c00: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·5, 51u32)); + let l·6: fstar::uint128::uint128 = + fstar::uint128::add(o21, fstar::uint128::uint64_to_uint128(c00)); + let tmp10: u64 = fstar::uint128::uint128_to_uint64(l·6) & 0x7ffffffffffffu64; + let c10: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·6, 51u32)); + let l·7: fstar::uint128::uint128 = + fstar::uint128::add(o22, fstar::uint128::uint64_to_uint128(c10)); + let tmp20: u64 = fstar::uint128::uint128_to_uint64(l·7) & 0x7ffffffffffffu64; + let c20: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·7, 51u32)); + let l·8: fstar::uint128::uint128 = + fstar::uint128::add(o23, fstar::uint128::uint64_to_uint128(c20)); + let tmp30: u64 = fstar::uint128::uint128_to_uint64(l·8) & 0x7ffffffffffffu64; + let c30: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·8, 51u32)); + let l·9: fstar::uint128::uint128 = + fstar::uint128::add(o24, fstar::uint128::uint64_to_uint128(c30)); + let tmp40: u64 = fstar::uint128::uint128_to_uint64(l·9) & 0x7ffffffffffffu64; + let c40: u64 = fstar::uint128::uint128_to_uint64(fstar::uint128::shift_right(l·9, 51u32)); + let l·10: u64 = tmp00.wrapping_add(c40.wrapping_mul(19u64)); + let tmp0·0: u64 = l·10 & 0x7ffffffffffffu64; + let c50: u64 = l·10.wrapping_shr(51u32); + let o201: u64 = tmp0·0; + let o211: u64 = tmp10.wrapping_add(c50); + let o221: u64 = tmp20; + let o231: u64 = tmp30; + let o241: u64 = tmp40; + let o100: u64 = o101; + let o110: u64 = o111; + let o120: u64 = o121; + let o130: u64 = o131; + let o140: u64 = o141; + let o200: u64 = o201; + let o210: u64 = o211; + let o220: u64 = o221; + let o230: u64 = o231; + let o240: u64 = o241; + out[0usize] = o100; + out[1usize] = o110; + out[2usize] = o120; + out[3usize] = o130; + out[4usize] = o140; + out[5usize] = o200; + out[6usize] = o210; + out[7usize] = o220; + out[8usize] = o230; + out[9usize] = o240 +} + +pub fn store_felem(u64s: &mut [u64], f: &[u64]) { + let f0: u64 = f[0usize]; + let f1: u64 = f[1usize]; + let f2: u64 = f[2usize]; + let f3: u64 = f[3usize]; + let f4: u64 = f[4usize]; + let l·: u64 = f0.wrapping_add(0u64); + let tmp0: u64 = l· & 0x7ffffffffffffu64; + let c0: u64 = l·.wrapping_shr(51u32); + let l·0: u64 = f1.wrapping_add(c0); + let tmp1: u64 = l·0 & 0x7ffffffffffffu64; + let c1: u64 = l·0.wrapping_shr(51u32); + let l·1: u64 = f2.wrapping_add(c1); + let tmp2: u64 = l·1 & 0x7ffffffffffffu64; + let c2: u64 = l·1.wrapping_shr(51u32); + let l·2: u64 = f3.wrapping_add(c2); + let tmp3: u64 = l·2 & 0x7ffffffffffffu64; + let c3: u64 = l·2.wrapping_shr(51u32); + let l·3: u64 = f4.wrapping_add(c3); + let tmp4: u64 = l·3 & 0x7ffffffffffffu64; + let c4: u64 = l·3.wrapping_shr(51u32); + let l·4: u64 = tmp0.wrapping_add(c4.wrapping_mul(19u64)); + let tmp0·: u64 = l·4 & 0x7ffffffffffffu64; + let c5: u64 = l·4.wrapping_shr(51u32); + let f01: u64 = tmp0·; + let f11: u64 = tmp1.wrapping_add(c5); + let f21: u64 = tmp2; + let f31: u64 = tmp3; + let f41: u64 = tmp4; + let m0: u64 = fstar::uint64::gte_mask(f01, 0x7ffffffffffedu64); + let m1: u64 = fstar::uint64::eq_mask(f11, 0x7ffffffffffffu64); + let m2: u64 = fstar::uint64::eq_mask(f21, 0x7ffffffffffffu64); + let m3: u64 = fstar::uint64::eq_mask(f31, 0x7ffffffffffffu64); + let m4: u64 = fstar::uint64::eq_mask(f41, 0x7ffffffffffffu64); + let mask: u64 = m0 & m1 & m2 & m3 & m4; + let f0·: u64 = f01.wrapping_sub(mask & 0x7ffffffffffedu64); + let f1·: u64 = f11.wrapping_sub(mask & 0x7ffffffffffffu64); + let f2·: u64 = f21.wrapping_sub(mask & 0x7ffffffffffffu64); + let f3·: u64 = f31.wrapping_sub(mask & 0x7ffffffffffffu64); + let f4·: u64 = f41.wrapping_sub(mask & 0x7ffffffffffffu64); + let f02: u64 = f0·; + let f12: u64 = f1·; + let f22: u64 = f2·; + let f32: u64 = f3·; + let f42: u64 = f4·; + let o0: u64 = f02 | f12.wrapping_shl(51u32); + let o1: u64 = f12.wrapping_shr(13u32) | f22.wrapping_shl(38u32); + let o2: u64 = f22.wrapping_shr(26u32) | f32.wrapping_shl(25u32); + let o3: u64 = f32.wrapping_shr(39u32) | f42.wrapping_shl(12u32); + let o00: u64 = o0; + let o10: u64 = o1; + let o20: u64 = o2; + let o30: u64 = o3; + u64s[0usize] = o00; + u64s[1usize] = o10; + u64s[2usize] = o20; + u64s[3usize] = o30 +} + +#[inline] +pub fn cswap2(bit: u64, p1: &mut [u64], p2: &mut [u64]) { + let mask: u64 = 0u64.wrapping_sub(bit); + krml::unroll_for!(10, "i", 0u32, 1u32, { + let dummy: u64 = mask & (p1[i as usize] ^ p2[i as usize]); + p1[i as usize] ^= dummy; + p2[i as usize] ^= dummy + }) +} diff --git a/hacl-rs/src/curve25519_51.rs b/hacl-rs/src/curve25519_51.rs new file mode 100644 index 000000000..f759a1859 --- /dev/null +++ b/hacl-rs/src/curve25519_51.rs @@ -0,0 +1,342 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_macros as krml; + +use crate::fstar; +use crate::lowstar; + +const g25519: [u8; 32] = [ + 9u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +]; + +fn point_add_and_double(q: &[u64], p01_tmp1: &mut [u64], tmp2: &[fstar::uint128::uint128]) { + let nq: (&mut [u64], &mut [u64]) = p01_tmp1.split_at_mut(0usize); + let nq_p1: (&mut [u64], &mut [u64]) = nq.1.split_at_mut(10usize); + let tmp1: (&mut [u64], &mut [u64]) = nq_p1.1.split_at_mut(10usize); + let x1: (&[u64], &[u64]) = q.split_at(0usize); + let x2: (&[u64], &[u64]) = nq_p1.0.split_at(0usize); + let z2: (&[u64], &[u64]) = x2.1.split_at(5usize); + let dc: (&mut [u64], &mut [u64]) = tmp1.1.split_at_mut(10usize); + let ab: (&mut [u64], &mut [u64]) = dc.0.split_at_mut(0usize); + let a: (&mut [u64], &mut [u64]) = ab.1.split_at_mut(0usize); + let b: (&mut [u64], &mut [u64]) = a.1.split_at_mut(5usize); + crate::bignum25519_51::fadd(b.0, z2.0, z2.1); + crate::bignum25519_51::fsub(b.1, z2.0, z2.1); + let ab1: (&mut [u64], &mut [u64]) = ab.1.split_at_mut(0usize); + let x3: (&mut [u64], &mut [u64]) = tmp1.0.split_at_mut(0usize); + let z31: (&mut [u64], &mut [u64]) = x3.1.split_at_mut(5usize); + let d: (&mut [u64], &mut [u64]) = dc.1.split_at_mut(0usize); + let c: (&mut [u64], &mut [u64]) = d.1.split_at_mut(5usize); + crate::bignum25519_51::fadd(c.1, z31.0, z31.1); + crate::bignum25519_51::fsub(c.0, z31.0, z31.1); + let mut f1_copy: [u64; 10] = [0u64; 10usize]; + ((&mut f1_copy)[0usize..10usize]).copy_from_slice(&dc.1[0usize..10usize]); + crate::bignum25519_51::fmul2(dc.1, &f1_copy, ab1.1, tmp2); + let d1: (&[u64], &[u64]) = dc.1.split_at(0usize); + let c1: (&[u64], &[u64]) = d1.1.split_at(5usize); + crate::bignum25519_51::fadd(z31.0, c1.0, c1.1); + crate::bignum25519_51::fsub(z31.1, c1.0, c1.1); + let ab2: (&mut [u64], &mut [u64]) = ab1.1.split_at_mut(0usize); + let dc1: (&mut [u64], &mut [u64]) = dc.1.split_at_mut(0usize); + crate::bignum25519_51::fsqr2(dc1.1, ab2.1, tmp2); + let mut f1_copy0: [u64; 10] = [0u64; 10usize]; + ((&mut f1_copy0)[0usize..10usize]).copy_from_slice(&tmp1.0[0usize..10usize]); + crate::bignum25519_51::fsqr2(tmp1.0, &f1_copy0, tmp2); + let a1: (&mut [u64], &mut [u64]) = ab2.1.split_at_mut(0usize); + let b1: (&mut [u64], &mut [u64]) = a1.1.split_at_mut(5usize); + let d0: (&mut [u64], &mut [u64]) = dc1.1.split_at_mut(0usize); + let c0: (&mut [u64], &mut [u64]) = d0.1.split_at_mut(5usize); + b1.0[0usize] = c0.1[0usize]; + b1.0[1usize] = c0.1[1usize]; + b1.0[2usize] = c0.1[2usize]; + b1.0[3usize] = c0.1[3usize]; + b1.0[4usize] = c0.1[4usize]; + let mut f2_copy: [u64; 5] = [0u64; 5usize]; + ((&mut f2_copy)[0usize..5usize]).copy_from_slice(&c0.1[0usize..5usize]); + crate::bignum25519_51::fsub(c0.1, c0.0, &f2_copy); + crate::bignum25519_51::fmul1(b1.1, c0.1, 121665u64); + let mut f1_copy1: [u64; 5] = [0u64; 5usize]; + ((&mut f1_copy1)[0usize..5usize]).copy_from_slice(&b1.1[0usize..5usize]); + crate::bignum25519_51::fadd(b1.1, &f1_copy1, c0.0); + let ab3: (&[u64], &[u64]) = ab2.1.split_at(0usize); + let dc2: (&[u64], &[u64]) = dc1.1.split_at(0usize); + crate::bignum25519_51::fmul2(nq_p1.0, dc2.1, ab3.1, tmp2); + let z310: (&mut [u64], &mut [u64]) = tmp1.0.split_at_mut(5usize); + let mut f1_copy2: [u64; 5] = [0u64; 5usize]; + ((&mut f1_copy2)[0usize..5usize]).copy_from_slice(&z310.1[0usize..5usize]); + crate::bignum25519_51::fmul(z310.1, &f1_copy2, x1.1, tmp2) +} + +fn point_double(nq: &mut [u64], tmp1: &mut [u64], tmp2: &[fstar::uint128::uint128]) { + let x2: (&[u64], &[u64]) = nq.split_at(0usize); + let z2: (&[u64], &[u64]) = x2.1.split_at(5usize); + let ab: (&mut [u64], &mut [u64]) = tmp1.split_at_mut(0usize); + let dc: (&mut [u64], &mut [u64]) = ab.1.split_at_mut(10usize); + let a: (&mut [u64], &mut [u64]) = dc.0.split_at_mut(0usize); + let b: (&mut [u64], &mut [u64]) = a.1.split_at_mut(5usize); + crate::bignum25519_51::fadd(b.0, z2.0, z2.1); + crate::bignum25519_51::fsub(b.1, z2.0, z2.1); + crate::bignum25519_51::fsqr2(dc.1, dc.0, tmp2); + let d: (&mut [u64], &mut [u64]) = dc.1.split_at_mut(0usize); + let c: (&mut [u64], &mut [u64]) = d.1.split_at_mut(5usize); + let a1: (&mut [u64], &mut [u64]) = dc.0.split_at_mut(0usize); + let b1: (&mut [u64], &mut [u64]) = a1.1.split_at_mut(5usize); + b1.0[0usize] = c.1[0usize]; + b1.0[1usize] = c.1[1usize]; + b1.0[2usize] = c.1[2usize]; + b1.0[3usize] = c.1[3usize]; + b1.0[4usize] = c.1[4usize]; + let mut f2_copy: [u64; 5] = [0u64; 5usize]; + ((&mut f2_copy)[0usize..5usize]).copy_from_slice(&c.1[0usize..5usize]); + crate::bignum25519_51::fsub(c.1, c.0, &f2_copy); + crate::bignum25519_51::fmul1(b1.1, c.1, 121665u64); + let mut f1_copy: [u64; 5] = [0u64; 5usize]; + ((&mut f1_copy)[0usize..5usize]).copy_from_slice(&b1.1[0usize..5usize]); + crate::bignum25519_51::fadd(b1.1, &f1_copy, c.0); + let ab1: (&[u64], &[u64]) = dc.0.split_at(0usize); + let dc1: (&[u64], &[u64]) = dc.1.split_at(0usize); + crate::bignum25519_51::fmul2(nq, dc1.1, ab1.1, tmp2) +} + +fn montgomery_ladder(out: &mut [u64], key: &[u8], init: &[u64]) { + let tmp2: [fstar::uint128::uint128; 10] = [fstar::uint128::uint64_to_uint128(0u64); 10usize]; + let mut p01_tmp1_swap: [u64; 41] = [0u64; 41usize]; + let p01: (&mut [u64], &mut [u64]) = p01_tmp1_swap.split_at_mut(0usize); + let p03: (&mut [u64], &mut [u64]) = p01.1.split_at_mut(0usize); + let p11: (&mut [u64], &mut [u64]) = p03.1.split_at_mut(10usize); + (p11.1[0usize..10usize]).copy_from_slice(&init[0usize..10usize]); + let x0: (&mut [u64], &mut [u64]) = p11.0.split_at_mut(0usize); + let z0: (&mut [u64], &mut [u64]) = x0.1.split_at_mut(5usize); + z0.0[0usize] = 1u64; + z0.0[1usize] = 0u64; + z0.0[2usize] = 0u64; + z0.0[3usize] = 0u64; + z0.0[4usize] = 0u64; + z0.1[0usize] = 0u64; + z0.1[1usize] = 0u64; + z0.1[2usize] = 0u64; + z0.1[3usize] = 0u64; + z0.1[4usize] = 0u64; + let swap: (&mut [u64], &mut [u64]) = p01.1.split_at_mut(40usize); + let p01_tmp1: (&mut [u64], &mut [u64]) = swap.0.split_at_mut(0usize); + let nq: (&mut [u64], &mut [u64]) = p01_tmp1.1.split_at_mut(0usize); + let nq_p1: (&mut [u64], &mut [u64]) = nq.1.split_at_mut(10usize); + crate::bignum25519_51::cswap2(1u64, nq_p1.0, nq_p1.1); + let p01_tmp11: (&mut [u64], &mut [u64]) = p01_tmp1.1.split_at_mut(0usize); + crate::curve25519_51::point_add_and_double(init, p01_tmp11.1, &tmp2); + swap.1[0usize] = 1u64; + for i in 0u32..251u32 { + let p01_tmp12: (&mut [u64], &mut [u64]) = p01_tmp11.1.split_at_mut(0usize); + let swap1: (&mut [u64], &mut [u64]) = swap.1.split_at_mut(0usize); + let nq1: (&mut [u64], &mut [u64]) = p01_tmp12.1.split_at_mut(0usize); + let nq_p11: (&mut [u64], &mut [u64]) = nq1.1.split_at_mut(10usize); + let bit: u64 = ((key[253u32.wrapping_sub(i).wrapping_div(8u32) as usize]) + .wrapping_shr(253u32.wrapping_sub(i).wrapping_rem(8u32)) + & 1u8) as u64; + let sw: u64 = swap1.1[0usize] ^ bit; + crate::bignum25519_51::cswap2(sw, nq_p11.0, nq_p11.1); + crate::curve25519_51::point_add_and_double(init, p01_tmp12.1, &tmp2); + swap1.1[0usize] = bit + } + let sw: u64 = swap.1[0usize]; + let p01_tmp12: (&mut [u64], &mut [u64]) = p01_tmp11.1.split_at_mut(0usize); + let nq1: (&mut [u64], &mut [u64]) = p01_tmp12.1.split_at_mut(0usize); + let nq_p11: (&mut [u64], &mut [u64]) = nq1.1.split_at_mut(10usize); + crate::bignum25519_51::cswap2(sw, nq_p11.0, nq_p11.1); + let p01_tmp10: (&mut [u64], &mut [u64]) = p01_tmp12.1.split_at_mut(0usize); + let nq0: (&mut [u64], &mut [u64]) = p01_tmp10.1.split_at_mut(0usize); + let tmp1: (&mut [u64], &mut [u64]) = nq0.1.split_at_mut(20usize); + crate::curve25519_51::point_double(tmp1.0, tmp1.1, &tmp2); + crate::curve25519_51::point_double(tmp1.0, tmp1.1, &tmp2); + crate::curve25519_51::point_double(tmp1.0, tmp1.1, &tmp2); + let p010: (&[u64], &[u64]) = p01_tmp10.1.split_at(0usize); + (out[0usize..10usize]).copy_from_slice(&p010.1[0usize..10usize]) +} + +pub fn fsquare_times(o: &mut [u64], inp: &[u64], tmp: &[fstar::uint128::uint128], n: u32) { + crate::bignum25519_51::fsqr(o, inp, tmp); + for _i in 0u32..n.wrapping_sub(1u32) { + let mut f1_copy: [u64; 5] = [0u64; 5usize]; + ((&mut f1_copy)[0usize..5usize]).copy_from_slice(&o[0usize..5usize]); + crate::bignum25519_51::fsqr(o, &f1_copy, tmp) + } +} + +pub fn finv(o: &mut [u64], i: &[u64], tmp: &[fstar::uint128::uint128]) { + let mut t1: [u64; 20] = [0u64; 20usize]; + let a1: (&mut [u64], &mut [u64]) = t1.split_at_mut(0usize); + let b1: (&mut [u64], &mut [u64]) = a1.1.split_at_mut(5usize); + let t01: (&mut [u64], &mut [u64]) = b1.1.split_at_mut(10usize); + let tmp1: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + crate::curve25519_51::fsquare_times(b1.0, i, tmp1.1, 1u32); + crate::curve25519_51::fsquare_times(t01.1, b1.0, tmp1.1, 2u32); + crate::bignum25519_51::fmul(t01.0, t01.1, i, tmp); + let mut f2_copy: [u64; 5] = [0u64; 5usize]; + ((&mut f2_copy)[0usize..5usize]).copy_from_slice(&b1.0[0usize..5usize]); + crate::bignum25519_51::fmul(b1.0, t01.0, &f2_copy, tmp); + let tmp11: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + crate::curve25519_51::fsquare_times(t01.1, b1.0, tmp11.1, 1u32); + let mut f2_copy0: [u64; 5] = [0u64; 5usize]; + ((&mut f2_copy0)[0usize..5usize]).copy_from_slice(&t01.0[0usize..5usize]); + crate::bignum25519_51::fmul(t01.0, t01.1, &f2_copy0, tmp); + let tmp12: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + crate::curve25519_51::fsquare_times(t01.1, t01.0, tmp12.1, 5u32); + let mut f2_copy1: [u64; 5] = [0u64; 5usize]; + ((&mut f2_copy1)[0usize..5usize]).copy_from_slice(&t01.0[0usize..5usize]); + crate::bignum25519_51::fmul(t01.0, t01.1, &f2_copy1, tmp); + let b10: (&mut [u64], &mut [u64]) = t01.0.split_at_mut(0usize); + let c1: (&mut [u64], &mut [u64]) = b10.1.split_at_mut(5usize); + let t010: (&mut [u64], &mut [u64]) = t01.1.split_at_mut(0usize); + let tmp10: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + crate::curve25519_51::fsquare_times(t010.1, c1.0, tmp10.1, 10u32); + crate::bignum25519_51::fmul(c1.1, t010.1, c1.0, tmp); + let tmp110: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + crate::curve25519_51::fsquare_times(t010.1, c1.1, tmp110.1, 20u32); + let mut f1_copy: [u64; 5] = [0u64; 5usize]; + ((&mut f1_copy)[0usize..5usize]).copy_from_slice(&t010.1[0usize..5usize]); + crate::bignum25519_51::fmul(t010.1, &f1_copy, c1.1, tmp); + let tmp120: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + let mut i_copy: [u64; 5] = [0u64; 5usize]; + ((&mut i_copy)[0usize..5usize]).copy_from_slice(&t010.1[0usize..5usize]); + crate::curve25519_51::fsquare_times(t010.1, &i_copy, tmp120.1, 10u32); + let mut f2_copy2: [u64; 5] = [0u64; 5usize]; + ((&mut f2_copy2)[0usize..5usize]).copy_from_slice(&c1.0[0usize..5usize]); + crate::bignum25519_51::fmul(c1.0, t010.1, &f2_copy2, tmp); + let tmp13: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + crate::curve25519_51::fsquare_times(t010.1, c1.0, tmp13.1, 50u32); + crate::bignum25519_51::fmul(c1.1, t010.1, c1.0, tmp); + let b11: (&[u64], &[u64]) = c1.0.split_at(0usize); + let c10: (&[u64], &[u64]) = c1.1.split_at(0usize); + let t011: (&mut [u64], &mut [u64]) = t010.1.split_at_mut(0usize); + let tmp14: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + crate::curve25519_51::fsquare_times(t011.1, c10.1, tmp14.1, 100u32); + let mut f1_copy0: [u64; 5] = [0u64; 5usize]; + ((&mut f1_copy0)[0usize..5usize]).copy_from_slice(&t011.1[0usize..5usize]); + crate::bignum25519_51::fmul(t011.1, &f1_copy0, c10.1, tmp); + let tmp111: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + let mut i_copy0: [u64; 5] = [0u64; 5usize]; + ((&mut i_copy0)[0usize..5usize]).copy_from_slice(&t011.1[0usize..5usize]); + crate::curve25519_51::fsquare_times(t011.1, &i_copy0, tmp111.1, 50u32); + let mut f1_copy1: [u64; 5] = [0u64; 5usize]; + ((&mut f1_copy1)[0usize..5usize]).copy_from_slice(&t011.1[0usize..5usize]); + crate::bignum25519_51::fmul(t011.1, &f1_copy1, b11.1, tmp); + let tmp121: (&[fstar::uint128::uint128], &[fstar::uint128::uint128]) = tmp.split_at(0usize); + let mut i_copy1: [u64; 5] = [0u64; 5usize]; + ((&mut i_copy1)[0usize..5usize]).copy_from_slice(&t011.1[0usize..5usize]); + crate::curve25519_51::fsquare_times(t011.1, &i_copy1, tmp121.1, 5u32); + let a: (&[u64], &[u64]) = b1.0.split_at(0usize); + let t0: (&[u64], &[u64]) = t011.1.split_at(0usize); + crate::bignum25519_51::fmul(o, t0.1, a.1, tmp) +} + +fn encode_point(o: &mut [u8], i: &[u64]) { + let x: (&[u64], &[u64]) = i.split_at(0usize); + let z: (&[u64], &[u64]) = x.1.split_at(5usize); + let mut tmp: [u64; 5] = [0u64; 5usize]; + let mut u64s: [u64; 4] = [0u64; 4usize]; + let tmp_w: [fstar::uint128::uint128; 10] = [fstar::uint128::uint64_to_uint128(0u64); 10usize]; + crate::curve25519_51::finv(&mut tmp, z.1, &tmp_w); + let mut f1_copy: [u64; 5] = [0u64; 5usize]; + ((&mut f1_copy)[0usize..5usize]).copy_from_slice(&(&tmp)[0usize..5usize]); + crate::bignum25519_51::fmul(&mut tmp, &f1_copy, z.0, &tmp_w); + crate::bignum25519_51::store_felem(&mut u64s, &tmp); + krml::unroll_for!( + 4, + "i0", + 0u32, + 1u32, + lowstar::endianness::store64_le( + &mut o[i0.wrapping_mul(8u32) as usize..], + (&u64s)[i0 as usize] + ) + ) +} + +/** +Compute the scalar multiple of a point. + +@param out Pointer to 32 bytes of memory, allocated by the caller, where the resulting point is written to. +@param priv Pointer to 32 bytes of memory where the secret/private key is read from. +@param pub Pointer to 32 bytes of memory where the public point is read from. +*/ +pub fn scalarmult(out: &mut [u8], r#priv: &[u8], r#pub: &[u8]) { + let mut init: [u64; 10] = [0u64; 10usize]; + let mut init_copy: [u64; 10] = [0u64; 10usize]; + let mut tmp: [u64; 4] = [0u64; 4usize]; + krml::unroll_for!(4, "i", 0u32, 1u32, { + let bj: (&[u8], &[u8]) = r#pub.split_at(i.wrapping_mul(8u32) as usize); + let u: u64 = lowstar::endianness::load64_le(bj.1); + let r: u64 = u; + let x: u64 = r; + let os: (&mut [u64], &mut [u64]) = tmp.split_at_mut(0usize); + os.1[i as usize] = x + }); + let tmp3: u64 = (&tmp)[3usize]; + (&mut tmp)[3usize] = tmp3 & 0x7fffffffffffffffu64; + let x: (&mut [u64], &mut [u64]) = init.split_at_mut(0usize); + let z: (&mut [u64], &mut [u64]) = x.1.split_at_mut(5usize); + z.1[0usize] = 1u64; + z.1[1usize] = 0u64; + z.1[2usize] = 0u64; + z.1[3usize] = 0u64; + z.1[4usize] = 0u64; + let f0l: u64 = (&tmp)[0usize] & 0x7ffffffffffffu64; + let f0h: u64 = ((&tmp)[0usize]).wrapping_shr(51u32); + let f1l: u64 = ((&tmp)[1usize] & 0x3fffffffffu64).wrapping_shl(13u32); + let f1h: u64 = ((&tmp)[1usize]).wrapping_shr(38u32); + let f2l: u64 = ((&tmp)[2usize] & 0x1ffffffu64).wrapping_shl(26u32); + let f2h: u64 = ((&tmp)[2usize]).wrapping_shr(25u32); + let f3l: u64 = ((&tmp)[3usize] & 0xfffu64).wrapping_shl(39u32); + let f3h: u64 = ((&tmp)[3usize]).wrapping_shr(12u32); + z.0[0usize] = f0l; + z.0[1usize] = f0h | f1l; + z.0[2usize] = f1h | f2l; + z.0[3usize] = f2h | f3l; + z.0[4usize] = f3h; + ((&mut init_copy)[0usize..10usize]).copy_from_slice(&(&init)[0usize..10usize]); + crate::curve25519_51::montgomery_ladder(&mut init, r#priv, &init_copy); + crate::curve25519_51::encode_point(out, &init) +} + +/** +Calculate a public point from a secret/private key. + +This computes a scalar multiplication of the secret/private key with the curve's basepoint. + +@param pub Pointer to 32 bytes of memory, allocated by the caller, where the resulting point is written to. +@param priv Pointer to 32 bytes of memory where the secret/private key is read from. +*/ +pub fn secret_to_public(r#pub: &mut [u8], r#priv: &[u8]) { + let mut basepoint: [u8; 32] = [0u8; 32usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let x: u8 = (&crate::curve25519_51::g25519)[i as usize]; + let os: (&mut [u8], &mut [u8]) = basepoint.split_at_mut(0usize); + os.1[i as usize] = x + }); + crate::curve25519_51::scalarmult(r#pub, r#priv, &basepoint) +} + +/** +Execute the diffie-hellmann key exchange. + +@param out Pointer to 32 bytes of memory, allocated by the caller, where the resulting point is written to. +@param priv Pointer to 32 bytes of memory where **our** secret/private key is read from. +@param pub Pointer to 32 bytes of memory where **their** public point is read from. +*/ +pub fn ecdh(out: &mut [u8], r#priv: &[u8], r#pub: &[u8]) -> bool { + let zeros: [u8; 32] = [0u8; 32usize]; + crate::curve25519_51::scalarmult(out, r#priv, r#pub); + let mut res: [u8; 1] = [255u8; 1usize]; + krml::unroll_for!(32, "i", 0u32, 1u32, { + let uu____0: u8 = fstar::uint8::eq_mask(out[i as usize], (&zeros)[i as usize]); + (&mut res)[0usize] = uu____0 & (&res)[0usize] + }); + let z: u8 = (&res)[0usize]; + let r: bool = z == 255u8; + !r +} diff --git a/hacl-rs/src/fstar.rs b/hacl-rs/src/fstar.rs new file mode 100644 index 000000000..e15b79144 --- /dev/null +++ b/hacl-rs/src/fstar.rs @@ -0,0 +1,5 @@ +pub mod uint128; +pub mod uint16; +pub mod uint32; +pub mod uint64; +pub mod uint8; diff --git a/hacl-rs/src/fstar/uint128.rs b/hacl-rs/src/fstar/uint128.rs new file mode 100644 index 000000000..1c8b2446c --- /dev/null +++ b/hacl-rs/src/fstar/uint128.rs @@ -0,0 +1,79 @@ +#![allow(non_camel_case_types)] + +pub type uint128 = u128; + +pub fn add(x: uint128, y: uint128) -> uint128 { + x.wrapping_add(y) +} +pub fn add_mod(x: uint128, y: uint128) -> uint128 { + x.wrapping_add(y) +} +pub fn sub(x: uint128, y: uint128) -> uint128 { + x.wrapping_sub(y) +} +pub fn sub_mod(x: uint128, y: uint128) -> uint128 { + x.wrapping_sub(y) +} +pub fn logand(x: uint128, y: uint128) -> uint128 { + x & y +} +pub fn logxor(x: uint128, y: uint128) -> uint128 { + x ^ y +} +pub fn logor(x: uint128, y: uint128) -> uint128 { + x | y +} +pub fn lognot(x: uint128) -> uint128 { + !x +} +pub fn shift_left(x: uint128, y: u32) -> uint128 { + x.wrapping_shl(y) +} +pub fn shift_right(x: uint128, y: u32) -> uint128 { + x.wrapping_shr(y) +} +pub fn eq(x: uint128, y: uint128) -> bool { + x == y +} +pub fn gt(x: uint128, y: uint128) -> bool { + x > y +} +pub fn lt(x: uint128, y: uint128) -> bool { + x < y +} +pub fn gte(x: uint128, y: uint128) -> bool { + x >= y +} +pub fn lte(x: uint128, y: uint128) -> bool { + x <= y +} +pub fn eq_mask(a: uint128, b: uint128) -> uint128 { + let x = a ^ b; + let minus_x = (!x).wrapping_add(1u128); + let x_or_minus_x = x | minus_x; + let xnx = x_or_minus_x.wrapping_shr(127); + xnx.wrapping_sub(1u128) +} +pub fn gte_mask(a: uint128, b: uint128) -> uint128 { + let x = a; + let y = b; + let x_xor_y = x ^ y; + let x_sub_y = x.wrapping_sub(y); + let x_sub_y_xor_y = x_sub_y ^ y; + let q = x_xor_y | x_sub_y_xor_y; + let x_xor_q = x ^ q; + let x_xor_q_ = x_xor_q.wrapping_shr(127); + x_xor_q_.wrapping_sub(1u128) +} +pub fn uint64_to_uint128(x: u64) -> uint128 { + x as u128 +} +pub fn uint128_to_uint64(x: uint128) -> u64 { + x as u64 +} +pub fn mul32(x: u64, y: u32) -> uint128 { + (x as u128) * (y as u128) +} +pub fn mul_wide(x: u64, y: u64) -> uint128 { + (x as u128) * (y as u128) +} diff --git a/hacl-rs/src/fstar/uint16.rs b/hacl-rs/src/fstar/uint16.rs new file mode 100644 index 000000000..42f429efc --- /dev/null +++ b/hacl-rs/src/fstar/uint16.rs @@ -0,0 +1,19 @@ +pub fn eq_mask(a: u16, b: u16) -> u16 { + let x = a ^ b; + let minus_x = (!x).wrapping_add(1u16); + let x_or_minus_x = x | minus_x; + let xnx = x_or_minus_x.wrapping_shr(15); + xnx.wrapping_sub(1u16) +} + +pub fn gte_mask(a: u16, b: u16) -> u16 { + let x = a; + let y = b; + let x_xor_y = x ^ y; + let x_sub_y = x.wrapping_sub(y); + let x_sub_y_xor_y = x_sub_y ^ y; + let q = x_xor_y | x_sub_y_xor_y; + let x_xor_q = x ^ q; + let x_xor_q_ = x_xor_q.wrapping_shr(15); + x_xor_q_.wrapping_sub(1u16) +} diff --git a/hacl-rs/src/fstar/uint32.rs b/hacl-rs/src/fstar/uint32.rs new file mode 100644 index 000000000..9ea3a652f --- /dev/null +++ b/hacl-rs/src/fstar/uint32.rs @@ -0,0 +1,19 @@ +pub fn eq_mask(a: u32, b: u32) -> u32 { + let x = a ^ b; + let minus_x = (!x).wrapping_add(1u32); + let x_or_minus_x = x | minus_x; + let xnx = x_or_minus_x.wrapping_shr(31); + xnx.wrapping_sub(1u32) +} + +pub fn gte_mask(a: u32, b: u32) -> u32 { + let x = a; + let y = b; + let x_xor_y = x ^ y; + let x_sub_y = x.wrapping_sub(y); + let x_sub_y_xor_y = x_sub_y ^ y; + let q = x_xor_y | x_sub_y_xor_y; + let x_xor_q = x ^ q; + let x_xor_q_ = x_xor_q.wrapping_shr(31); + x_xor_q_.wrapping_sub(1u32) +} diff --git a/hacl-rs/src/fstar/uint64.rs b/hacl-rs/src/fstar/uint64.rs new file mode 100644 index 000000000..4f48d9d4d --- /dev/null +++ b/hacl-rs/src/fstar/uint64.rs @@ -0,0 +1,19 @@ +pub fn eq_mask(a: u64, b: u64) -> u64 { + let x = a ^ b; + let minus_x = (!x).wrapping_add(1u64); + let x_or_minus_x = x | minus_x; + let xnx = x_or_minus_x.wrapping_shr(63); + xnx.wrapping_sub(1u64) +} + +pub fn gte_mask(a: u64, b: u64) -> u64 { + let x = a; + let y = b; + let x_xor_y = x ^ y; + let x_sub_y = x.wrapping_sub(y); + let x_sub_y_xor_y = x_sub_y ^ y; + let q = x_xor_y | x_sub_y_xor_y; + let x_xor_q = x ^ q; + let x_xor_q_ = x_xor_q.wrapping_shr(63); + x_xor_q_.wrapping_sub(1u64) +} diff --git a/hacl-rs/src/fstar/uint8.rs b/hacl-rs/src/fstar/uint8.rs new file mode 100644 index 000000000..196e153bc --- /dev/null +++ b/hacl-rs/src/fstar/uint8.rs @@ -0,0 +1,19 @@ +pub fn eq_mask(a: u8, b: u8) -> u8 { + let x = a ^ b; + let minus_x = (!x).wrapping_add(1u8); + let x_or_minus_x = x | minus_x; + let xnx = x_or_minus_x.wrapping_shr(7); + xnx.wrapping_sub(1u8) +} + +pub fn gte_mask(a: u8, b: u8) -> u8 { + let x = a; + let y = b; + let x_xor_y = x ^ y; + let x_sub_y = x.wrapping_sub(y); + let x_sub_y_xor_y = x_sub_y ^ y; + let q = x_xor_y | x_sub_y_xor_y; + let x_xor_q = x ^ q; + let x_xor_q_ = x_xor_q.wrapping_shr(7); + x_xor_q_.wrapping_sub(1u8) +} diff --git a/hacl-rs/src/lib.rs b/hacl-rs/src/lib.rs new file mode 100644 index 000000000..3aaaaa6fe --- /dev/null +++ b/hacl-rs/src/lib.rs @@ -0,0 +1,15 @@ +//! This crate contains hacl-generated utility modules for other hacl-generated code. +//! You most likely don't need to import this. +//! +//! hacl-star commit: efbf82f29190e2aecdac8899e4f42c8cb9defc98 + +// Utility modules. In the generated hacl-rs, these are individual crates. +pub mod bignum; +pub mod fstar; +pub mod lowstar; +pub mod util; + +// Utility modules that were modules of hacl in the generated code +pub mod bignum25519_51; +pub mod curve25519_51; +pub mod streaming_types; diff --git a/hacl-rs/src/lowstar.rs b/hacl-rs/src/lowstar.rs new file mode 100644 index 000000000..f63af5cbe --- /dev/null +++ b/hacl-rs/src/lowstar.rs @@ -0,0 +1,2 @@ +pub mod endianness; +pub mod ignore; diff --git a/hacl-rs/src/lowstar/endianness.rs b/hacl-rs/src/lowstar/endianness.rs new file mode 100644 index 000000000..27e227900 --- /dev/null +++ b/hacl-rs/src/lowstar/endianness.rs @@ -0,0 +1,53 @@ +use std::convert::TryInto; + +// Little Endian + +pub fn load16_le(bytes: &[u8]) -> u16 { + u16::from_le_bytes(bytes[0..2].try_into().unwrap()) +} + +pub fn store16_le(bytes: &mut [u8], x: u16) { + bytes[0..2].copy_from_slice(&u16::to_le_bytes(x)) +} + +pub fn load32_le(bytes: &[u8]) -> u32 { + u32::from_le_bytes(bytes[0..4].try_into().unwrap()) +} + +pub fn store32_le(bytes: &mut [u8], x: u32) { + bytes[0..4].copy_from_slice(&u32::to_le_bytes(x)) +} + +pub fn load64_le(bytes: &[u8]) -> u64 { + u64::from_le_bytes(bytes[0..8].try_into().unwrap()) +} + +pub fn store64_le(bytes: &mut [u8], x: u64) { + bytes[0..8].copy_from_slice(&u64::to_le_bytes(x)) +} + +// Big Endian + +pub fn load32_be(bytes: &[u8]) -> u32 { + u32::from_be_bytes(bytes[0..4].try_into().unwrap()) +} + +pub fn store32_be(bytes: &mut [u8], x: u32) { + bytes[0..4].copy_from_slice(&u32::to_be_bytes(x)) +} + +pub fn load64_be(bytes: &[u8]) -> u64 { + u64::from_be_bytes(bytes[0..8].try_into().unwrap()) +} + +pub fn store64_be(bytes: &mut [u8], x: u64) { + bytes[0..8].copy_from_slice(&u64::to_be_bytes(x)) +} + +pub fn load128_be(bytes: &[u8]) -> u128 { + u128::from_be_bytes(bytes[0..16].try_into().unwrap()) +} + +pub fn store128_be(bytes: &mut [u8], x: u128) { + bytes[0..16].copy_from_slice(&u128::to_be_bytes(x)) +} diff --git a/hacl-rs/src/lowstar/ignore.rs b/hacl-rs/src/lowstar/ignore.rs new file mode 100644 index 000000000..919eb52f9 --- /dev/null +++ b/hacl-rs/src/lowstar/ignore.rs @@ -0,0 +1 @@ +pub fn ignore(_: T) {} diff --git a/hacl-rs/src/streaming_types.rs b/hacl-rs/src/streaming_types.rs new file mode 100644 index 000000000..0c53b03f2 --- /dev/null +++ b/hacl-rs/src/streaming_types.rs @@ -0,0 +1,45 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +#[derive(PartialEq, Clone, Copy)] +pub enum hash_alg { + SHA2_224, + SHA2_256, + SHA2_384, + SHA2_512, + SHA1, + MD5, + Blake2S, + Blake2B, + SHA3_256, + SHA3_224, + SHA3_384, + SHA3_512, + Shake128, + Shake256, +} + +#[derive(PartialEq, Clone, Copy)] +pub enum error_code { + Success, + InvalidAlgorithm, + InvalidLength, + MaximumLengthExceeded, +} + +#[derive(PartialEq, Clone)] +pub struct state_32 { + pub block_state: Box<[u32]>, + pub buf: Box<[u8]>, + pub total_len: u64, +} + +#[derive(PartialEq, Clone)] +pub struct state_64 { + pub block_state: Box<[u64]>, + pub buf: Box<[u8]>, + pub total_len: u64, +} diff --git a/hacl-rs/src/util.rs b/hacl-rs/src/util.rs new file mode 100644 index 000000000..035d286e2 --- /dev/null +++ b/hacl-rs/src/util.rs @@ -0,0 +1 @@ +pub mod inttypes_intrinsics; diff --git a/hacl-rs/src/util/inttypes_intrinsics.rs b/hacl-rs/src/util/inttypes_intrinsics.rs new file mode 100644 index 000000000..daa304a6f --- /dev/null +++ b/hacl-rs/src/util/inttypes_intrinsics.rs @@ -0,0 +1,37 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use crate::fstar; + +pub fn add_carry_u32(cin: u32, x: u32, y: u32, r: &mut [u32]) -> u32 { + let res: u64 = (x as u64).wrapping_add(cin as u64).wrapping_add(y as u64); + let c: u32 = res.wrapping_shr(32u32) as u32; + r[0usize] = res as u32; + c +} + +pub fn sub_borrow_u32(cin: u32, x: u32, y: u32, r: &mut [u32]) -> u32 { + let res: u64 = (x as u64).wrapping_sub(y as u64).wrapping_sub(cin as u64); + let c: u32 = res.wrapping_shr(32u32) as u32 & 1u32; + r[0usize] = res as u32; + c +} + +pub fn add_carry_u64(cin: u64, x: u64, y: u64, r: &mut [u64]) -> u64 { + let res: u64 = x.wrapping_add(cin).wrapping_add(y); + let c: u64 = (!fstar::uint64::gte_mask(res, x) | fstar::uint64::eq_mask(res, x) & cin) & 1u64; + r[0usize] = res; + c +} + +pub fn sub_borrow_u64(cin: u64, x: u64, y: u64, r: &mut [u64]) -> u64 { + let res: u64 = x.wrapping_sub(y).wrapping_sub(cin); + let c: u64 = (fstar::uint64::gte_mask(res, x) & !fstar::uint64::eq_mask(res, x) + | fstar::uint64::eq_mask(res, x) & cin) + & 1u64; + r[0usize] = res; + c +} diff --git a/libcrux-ecdh/Cargo.toml b/libcrux-ecdh/Cargo.toml index eecc87753..3fa7eb40c 100644 --- a/libcrux-ecdh/Cargo.toml +++ b/libcrux-ecdh/Cargo.toml @@ -15,6 +15,9 @@ path = "src/ecdh.rs" [dependencies] rand = { version = "0.8" } libcrux-hacl = { version = "=0.0.2-beta.2", path = "../sys/hacl" } +libcrux-curve25519 = { version = "=0.0.2-beta.2", path = "../curve25519", features = [ + "hacl", +] } [dev-dependencies] rand_core = { version = "0.6" } diff --git a/libcrux-ecdh/src/ecdh.rs b/libcrux-ecdh/src/ecdh.rs index 3b9f11fe5..963fa17c5 100644 --- a/libcrux-ecdh/src/ecdh.rs +++ b/libcrux-ecdh/src/ecdh.rs @@ -55,6 +55,13 @@ pub(crate) mod x25519_internal { #[derive(Debug)] pub struct PublicKey(pub [u8; 32]); + /// Output of a scalar multiplication between a public key and a secret key. + /// + /// This value is NOT (!) safe for use as a key and needs to be processed in a round of key + /// derivation, to ensure both that the output is uniformly random and that unkown key share + /// attacks can not happen. + pub struct SharedSecret(pub [u8; 32]); + impl From<&[u8; 32]> for PublicKey { fn from(value: &[u8; 32]) -> Self { Self(*value) @@ -83,6 +90,20 @@ pub(crate) mod x25519_internal { } } + impl From<&[u8; 32]> for SharedSecret { + fn from(value: &[u8; 32]) -> Self { + Self(*value) + } + } + + impl TryFrom<&[u8]> for SharedSecret { + type Error = Error; + + fn try_from(value: &[u8]) -> Result { + Ok(Self(value.try_into().map_err(|_| Error::InvalidScalar)?)) + } + } + impl AsRef<[u8]> for PrivateKey { fn as_ref(&self) -> &[u8] { &self.0 @@ -95,6 +116,12 @@ pub(crate) mod x25519_internal { } } + impl AsRef<[u8]> for SharedSecret { + fn as_ref(&self) -> &[u8] { + &self.0 + } + } + impl AsRef<[u8; 32]> for PrivateKey { fn as_ref(&self) -> &[u8; 32] { &self.0 @@ -107,8 +134,14 @@ pub(crate) mod x25519_internal { } } + impl AsRef<[u8; 32]> for SharedSecret { + fn as_ref(&self) -> &[u8; 32] { + &self.0 + } + } + #[cfg(all(bmi2, adx, target_arch = "x86_64"))] - pub fn derive(p: &PublicKey, s: &PrivateKey) -> Result { + pub fn derive(p: &PublicKey, s: &PrivateKey) -> Result { use crate::hacl::curve25519; use libcrux_platform::x25519_support; // On x64 we use vale if available or hacl as fallback. @@ -117,14 +150,14 @@ pub(crate) mod x25519_internal { if x25519_support() { curve25519::vale::ecdh(s, p) .map_err(|e| Error::Custom(format!("HACL Error {:?}", e))) - .map(|p| PublicKey(p)) + .map(SharedSecret) // XXX: not verified yet // crate::jasmin::x25519::mulx::derive(s, p) // .map_err(|e| Error::Custom(format!("Libjade Error {:?}", e))) } else { curve25519::ecdh(s, p) .map_err(|e| Error::Custom(format!("HACL Error {:?}", e))) - .map(|p| PublicKey(p)) + .map(SharedSecret) // XXX: not verified yet // crate::jasmin::x25519::derive(s, p) // .map_err(|e| Error::Custom(format!("Libjade Error {:?}", e))) @@ -135,27 +168,27 @@ pub(crate) mod x25519_internal { all(target_arch = "x86_64", any(not(bmi2), not(adx))), target_arch = "x86" ))] - pub fn derive(p: &PublicKey, s: &PrivateKey) -> Result { + pub fn derive(p: &PublicKey, s: &PrivateKey) -> Result { use crate::hacl::curve25519; // On x64 we use vale if available or hacl as fallback. // Jasmin exists but is not verified yet. curve25519::ecdh(s, p) .map_err(|e| Error::Custom(format!("HACL Error {:?}", e))) - .map(|p| PublicKey(p)) + .map(SharedSecret) // XXX: not verified yet // crate::jasmin::x25519::derive(s, p) // .map_err(|e| Error::Custom(format!("Libjade Error {:?}", e))) } #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] - pub fn derive(p: &PublicKey, s: &PrivateKey) -> Result { + pub fn derive(p: &PublicKey, s: &PrivateKey) -> Result { // On any other platform we use the portable HACL implementation. use crate::hacl::curve25519; curve25519::ecdh(s, p) .map_err(|e| Error::Custom(format!("HACL Error {:?}", e))) - .map(PublicKey) + .map(SharedSecret) } // XXX: libjade's secret to public is broken on Windows (overflows the stack). @@ -209,11 +242,13 @@ pub use x25519_internal::generate_secret as x25519_generate_secret; pub use x25519_internal::key_gen as x25519_key_gen; pub use x25519_internal::PrivateKey as X25519PrivateKey; pub use x25519_internal::PublicKey as X25519PublicKey; +pub use x25519_internal::SharedSecret as X25519SharedSecret; pub mod curve25519 { use super::hacl; pub use hacl::curve25519::Error; } + pub(crate) mod p256_internal { use rand::{CryptoRng, Rng}; @@ -227,6 +262,13 @@ pub(crate) mod p256_internal { #[derive(Debug)] pub struct PublicKey(pub [u8; 64]); + /// Output of a scalar multiplication between a public key and a secret key. + /// + /// This value is NOT (!) safe for use as a key and needs to be processed in a round of key + /// derivation, to ensure both that the output is uniformly random and that unkown key share + /// attacks can not happen. + pub struct SharedSecret(pub [u8; 64]); + impl From<&[u8; 64]> for PublicKey { fn from(value: &[u8; 64]) -> Self { Self(*value) @@ -255,6 +297,20 @@ pub(crate) mod p256_internal { } } + impl From<&[u8; 64]> for SharedSecret { + fn from(value: &[u8; 64]) -> Self { + Self(*value) + } + } + + impl TryFrom<&[u8]> for SharedSecret { + type Error = Error; + + fn try_from(value: &[u8]) -> Result { + Ok(Self(value.try_into().map_err(|_| Error::InvalidScalar)?)) + } + } + impl AsRef<[u8]> for PrivateKey { fn as_ref(&self) -> &[u8] { &self.0 @@ -267,6 +323,12 @@ pub(crate) mod p256_internal { } } + impl AsRef<[u8]> for SharedSecret { + fn as_ref(&self) -> &[u8] { + &self.0 + } + } + impl AsRef<[u8; 32]> for PrivateKey { fn as_ref(&self) -> &[u8; 32] { &self.0 @@ -279,11 +341,17 @@ pub(crate) mod p256_internal { } } - pub(super) fn derive(p: &PublicKey, s: &PrivateKey) -> Result { + impl AsRef<[u8; 64]> for SharedSecret { + fn as_ref(&self) -> &[u8; 64] { + &self.0 + } + } + + pub(super) fn derive(p: &PublicKey, s: &PrivateKey) -> Result { // We assume that the private key has been validated. p256::ecdh(s, p) .map_err(|e| Error::Custom(format!("HACL Error {:?}", e))) - .map(PublicKey) + .map(SharedSecret) } pub(super) fn secret_to_public(s: &PrivateKey) -> Result { @@ -364,6 +432,7 @@ pub use p256_internal::key_gen as p256_key_gen; pub use p256_internal::validate_scalar as p256_validate_scalar; pub use p256_internal::PrivateKey as P256PrivateKey; pub use p256_internal::PublicKey as P256PublicKey; +pub use p256_internal::SharedSecret as P256SharedSecret; /// Derive the ECDH shared secret. /// Returns `Ok(point * scalar)` on the provided curve [`Algorithm`] or an error. @@ -391,7 +460,7 @@ pub fn derive( pub fn p256_derive( point: &p256_internal::PublicKey, scalar: &p256_internal::PrivateKey, -) -> Result { +) -> Result { p256_internal::validate_point(point)?; p256_internal::validate_scalar(scalar)?; diff --git a/libcrux-ecdh/src/hacl/curve25519.rs b/libcrux-ecdh/src/hacl/curve25519.rs index 8ee631669..b5e56e57c 100644 --- a/libcrux-ecdh/src/hacl/curve25519.rs +++ b/libcrux-ecdh/src/hacl/curve25519.rs @@ -1,5 +1,3 @@ -use libcrux_hacl::{Hacl_Curve25519_51_ecdh, Hacl_Curve25519_51_secret_to_public}; - #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum Error { InvalidInput, @@ -14,18 +12,9 @@ pub fn ecdh( public_key: impl AsRef<[u8; 32]>, ) -> Result<[u8; 32], Error> { let mut shared = [0u8; 32]; - let ok = unsafe { - Hacl_Curve25519_51_ecdh( - shared.as_mut_ptr(), - private_key.as_ref().as_ptr() as _, - public_key.as_ref().as_ptr() as _, - ) - }; - if !ok { - Err(Error::InvalidInput) - } else { - Ok(shared) - } + libcrux_curve25519::ecdh(&mut shared, public_key.as_ref(), private_key.as_ref()) + .map(|_| shared) + .map_err(|_| Error::InvalidInput) } /// Compute the public key for the provided `private_key` (scalar multiplication @@ -36,9 +25,7 @@ pub fn ecdh( #[inline(always)] pub fn secret_to_public(private_key: impl AsRef<[u8; 32]>) -> [u8; 32] { let mut public = [0u8; 32]; - unsafe { - Hacl_Curve25519_51_secret_to_public(public.as_mut_ptr(), private_key.as_ref().as_ptr() as _) - }; + libcrux_curve25519::secret_to_public(&mut public, private_key.as_ref()); public } diff --git a/libcrux-ecdh/tests/x25519.rs b/libcrux-ecdh/tests/x25519.rs index 1138d049b..0443513da 100644 --- a/libcrux-ecdh/tests/x25519.rs +++ b/libcrux-ecdh/tests/x25519.rs @@ -80,7 +80,7 @@ fn wycheproof() { "public key = 57896044618658097711785492504343953926634992332820282019728792003956564819968" => false, "public key = 57896044618658097711785492504343953926634992332820282019728792003956564819969" => false, "special case public key" => { - if (test.flags.contains(&"Twist".to_owned()) && test.tcId != 154) + (test.flags.contains(&"Twist".to_owned()) && test.tcId != 154) || test.tcId == 120 || test.tcId == 122 || test.tcId == 123 @@ -102,11 +102,7 @@ fn wycheproof() { || test.tcId == 150 || test.tcId == 151 || test.tcId == 152 - || test.tcId == 153 { - true - } else { - false - } + || test.tcId == 153 }, "D = 0 in multiplication by 2" => false, _ => valid, diff --git a/libcrux-hkdf/Cargo.toml b/libcrux-hkdf/Cargo.toml index af1715038..5c02eeec0 100644 --- a/libcrux-hkdf/Cargo.toml +++ b/libcrux-hkdf/Cargo.toml @@ -12,6 +12,13 @@ description = "Libcrux HKDF implementation" [lib] path = "src/hkdf.rs" -[dependencies] -libcrux-hacl = { version = "=0.0.2-beta.2", path = "../sys/hacl" } +[features] +default = ["portable_hacl"] +portable_hacl = ["hacl"] +hacl = ["dep:libcrux-hmac", "dep:libcrux-hacl-rs"] +[dependencies] +libcrux-hacl-rs = { version = "=0.0.2-beta.2", path = "../hacl-rs/", optional = true } +libcrux-hmac = { version = "=0.0.2-beta.2", path = "../libcrux-hmac", optional = true, features = [ + "hacl", +] } diff --git a/libcrux-hkdf/src/hacl.rs b/libcrux-hkdf/src/hacl.rs new file mode 100644 index 000000000..ab8321a0f --- /dev/null +++ b/libcrux-hkdf/src/hacl.rs @@ -0,0 +1,496 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +//! This module contains generated hacl code. + +use libcrux_hacl_rs::lowstar; + +/** +Expand pseudorandom key to desired length. + +@param okm Pointer to `len` bytes of memory where output keying material is written to. +@param prk Pointer to at least `HashLen` bytes of memory where pseudorandom key is read from. Usually, this points to the output from the extract step. +@param prklen Length of pseudorandom key. +@param info Pointer to `infolen` bytes of memory where context and application specific information is read from. Can be a zero-length string. +@param infolen Length of context and application specific information. +@param len Length of output keying material. +*/ +pub fn expand_sha2_256( + okm: &mut [u8], + prk: &[u8], + prklen: u32, + info: &[u8], + infolen: u32, + len: u32, +) { + let tlen: u32 = 32u32; + let n: u32 = len.wrapping_div(tlen); + let output: (&mut [u8], &mut [u8]) = okm.split_at_mut(0usize); + let mut text: Box<[u8]> = + vec![0u8; tlen.wrapping_add(infolen).wrapping_add(1u32) as usize].into_boxed_slice(); + ((&mut (&mut text)[tlen as usize..])[0usize..infolen as usize]) + .copy_from_slice(&info[0usize..infolen as usize]); + let mut tag: Box<[u8]> = vec![0u8; tlen as usize].into_boxed_slice(); + for i in 0u32..n { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = i.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if i == 0u32 { + libcrux_hmac::hacl::hmac::compute_sha2_256( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_sha2_256( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + ((&mut output.1[i.wrapping_mul(tlen) as usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]) + } + if n.wrapping_mul(tlen) < len { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = n.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if n == 0u32 { + libcrux_hmac::hacl::hmac::compute_sha2_256( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_sha2_256( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + let block: (&mut [u8], &mut [u8]) = output.1.split_at_mut(n.wrapping_mul(tlen) as usize); + (block.1[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize]).copy_from_slice( + &(&(&tag)[0usize..])[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize], + ) + } +} + +/** +Extract a fixed-length pseudorandom key from input keying material. + +@param prk Pointer to `HashLen` bytes of memory where pseudorandom key is written to. +@param salt Pointer to `saltlen` bytes of memory where salt value is read from. +@param saltlen Length of salt value. +@param ikm Pointer to `ikmlen` bytes of memory where input keying material is read from. +@param ikmlen Length of input keying material. +*/ +pub fn extract_sha2_256(prk: &mut [u8], salt: &[u8], saltlen: u32, ikm: &[u8], ikmlen: u32) { + libcrux_hmac::hacl::hmac::compute_sha2_256(prk, salt, saltlen, ikm, ikmlen) +} + +/** +Expand pseudorandom key to desired length. + +@param okm Pointer to `len` bytes of memory where output keying material is written to. +@param prk Pointer to at least `HashLen` bytes of memory where pseudorandom key is read from. Usually, this points to the output from the extract step. +@param prklen Length of pseudorandom key. +@param info Pointer to `infolen` bytes of memory where context and application specific information is read from. Can be a zero-length string. +@param infolen Length of context and application specific information. +@param len Length of output keying material. +*/ +pub fn expand_sha2_384( + okm: &mut [u8], + prk: &[u8], + prklen: u32, + info: &[u8], + infolen: u32, + len: u32, +) { + let tlen: u32 = 48u32; + let n: u32 = len.wrapping_div(tlen); + let output: (&mut [u8], &mut [u8]) = okm.split_at_mut(0usize); + let mut text: Box<[u8]> = + vec![0u8; tlen.wrapping_add(infolen).wrapping_add(1u32) as usize].into_boxed_slice(); + ((&mut (&mut text)[tlen as usize..])[0usize..infolen as usize]) + .copy_from_slice(&info[0usize..infolen as usize]); + let mut tag: Box<[u8]> = vec![0u8; tlen as usize].into_boxed_slice(); + for i in 0u32..n { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = i.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if i == 0u32 { + libcrux_hmac::hacl::hmac::compute_sha2_384( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_sha2_384( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + ((&mut output.1[i.wrapping_mul(tlen) as usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]) + } + if n.wrapping_mul(tlen) < len { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = n.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if n == 0u32 { + libcrux_hmac::hacl::hmac::compute_sha2_384( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_sha2_384( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + let block: (&mut [u8], &mut [u8]) = output.1.split_at_mut(n.wrapping_mul(tlen) as usize); + (block.1[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize]).copy_from_slice( + &(&(&tag)[0usize..])[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize], + ) + } +} + +/** +Extract a fixed-length pseudorandom key from input keying material. + +@param prk Pointer to `HashLen` bytes of memory where pseudorandom key is written to. +@param salt Pointer to `saltlen` bytes of memory where salt value is read from. +@param saltlen Length of salt value. +@param ikm Pointer to `ikmlen` bytes of memory where input keying material is read from. +@param ikmlen Length of input keying material. +*/ +pub fn extract_sha2_384(prk: &mut [u8], salt: &[u8], saltlen: u32, ikm: &[u8], ikmlen: u32) { + libcrux_hmac::hacl::hmac::compute_sha2_384(prk, salt, saltlen, ikm, ikmlen) +} + +/** +Expand pseudorandom key to desired length. + +@param okm Pointer to `len` bytes of memory where output keying material is written to. +@param prk Pointer to at least `HashLen` bytes of memory where pseudorandom key is read from. Usually, this points to the output from the extract step. +@param prklen Length of pseudorandom key. +@param info Pointer to `infolen` bytes of memory where context and application specific information is read from. Can be a zero-length string. +@param infolen Length of context and application specific information. +@param len Length of output keying material. +*/ +pub fn expand_sha2_512( + okm: &mut [u8], + prk: &[u8], + prklen: u32, + info: &[u8], + infolen: u32, + len: u32, +) { + let tlen: u32 = 64u32; + let n: u32 = len.wrapping_div(tlen); + let output: (&mut [u8], &mut [u8]) = okm.split_at_mut(0usize); + let mut text: Box<[u8]> = + vec![0u8; tlen.wrapping_add(infolen).wrapping_add(1u32) as usize].into_boxed_slice(); + ((&mut (&mut text)[tlen as usize..])[0usize..infolen as usize]) + .copy_from_slice(&info[0usize..infolen as usize]); + let mut tag: Box<[u8]> = vec![0u8; tlen as usize].into_boxed_slice(); + for i in 0u32..n { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = i.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if i == 0u32 { + libcrux_hmac::hacl::hmac::compute_sha2_512( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_sha2_512( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + ((&mut output.1[i.wrapping_mul(tlen) as usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]) + } + if n.wrapping_mul(tlen) < len { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = n.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if n == 0u32 { + libcrux_hmac::hacl::hmac::compute_sha2_512( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_sha2_512( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + let block: (&mut [u8], &mut [u8]) = output.1.split_at_mut(n.wrapping_mul(tlen) as usize); + (block.1[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize]).copy_from_slice( + &(&(&tag)[0usize..])[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize], + ) + } +} + +/** +Extract a fixed-length pseudorandom key from input keying material. + +@param prk Pointer to `HashLen` bytes of memory where pseudorandom key is written to. +@param salt Pointer to `saltlen` bytes of memory where salt value is read from. +@param saltlen Length of salt value. +@param ikm Pointer to `ikmlen` bytes of memory where input keying material is read from. +@param ikmlen Length of input keying material. +*/ +pub fn extract_sha2_512(prk: &mut [u8], salt: &[u8], saltlen: u32, ikm: &[u8], ikmlen: u32) { + libcrux_hmac::hacl::hmac::compute_sha2_512(prk, salt, saltlen, ikm, ikmlen) +} + +/* +/** +Expand pseudorandom key to desired length. + +@param okm Pointer to `len` bytes of memory where output keying material is written to. +@param prk Pointer to at least `HashLen` bytes of memory where pseudorandom key is read from. Usually, this points to the output from the extract step. +@param prklen Length of pseudorandom key. +@param info Pointer to `infolen` bytes of memory where context and application specific information is read from. Can be a zero-length string. +@param infolen Length of context and application specific information. +@param len Length of output keying material. +*/ +pub fn expand_blake2s_32( + okm: &mut [u8], + prk: &[u8], + prklen: u32, + info: &[u8], + infolen: u32, + len: u32, +) { + let tlen: u32 = 32u32; + let n: u32 = len.wrapping_div(tlen); + let output: (&mut [u8], &mut [u8]) = okm.split_at_mut(0usize); + let mut text: Box<[u8]> = + vec![0u8; tlen.wrapping_add(infolen).wrapping_add(1u32) as usize].into_boxed_slice(); + ((&mut (&mut text)[tlen as usize..])[0usize..infolen as usize]) + .copy_from_slice(&info[0usize..infolen as usize]); + let mut tag: Box<[u8]> = vec![0u8; tlen as usize].into_boxed_slice(); + for i in 0u32..n { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = i.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if i == 0u32 { + libcrux_hmac::hacl::hmac::compute_blake2s_32( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_blake2s_32( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + ((&mut output.1[i.wrapping_mul(tlen) as usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]) + } + if n.wrapping_mul(tlen) < len { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = n.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if n == 0u32 { + libcrux_hmac::hacl::hmac::compute_blake2s_32( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_blake2s_32( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + let block: (&mut [u8], &mut [u8]) = output.1.split_at_mut(n.wrapping_mul(tlen) as usize); + (block.1[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize]).copy_from_slice( + &(&(&tag)[0usize..])[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize], + ) + } +} + +/** +Extract a fixed-length pseudorandom key from input keying material. + +@param prk Pointer to `HashLen` bytes of memory where pseudorandom key is written to. +@param salt Pointer to `saltlen` bytes of memory where salt value is read from. +@param saltlen Length of salt value. +@param ikm Pointer to `ikmlen` bytes of memory where input keying material is read from. +@param ikmlen Length of input keying material. +*/ +pub fn extract_blake2s_32(prk: &mut [u8], salt: &[u8], saltlen: u32, ikm: &[u8], ikmlen: u32) { + libcrux_hmac::hacl::hmac::compute_blake2s_32(prk, salt, saltlen, ikm, ikmlen) +} + +/** +Expand pseudorandom key to desired length. + +@param okm Pointer to `len` bytes of memory where output keying material is written to. +@param prk Pointer to at least `HashLen` bytes of memory where pseudorandom key is read from. Usually, this points to the output from the extract step. +@param prklen Length of pseudorandom key. +@param info Pointer to `infolen` bytes of memory where context and application specific information is read from. Can be a zero-length string. +@param infolen Length of context and application specific information. +@param len Length of output keying material. +*/ +pub fn expand_blake2b_32( + okm: &mut [u8], + prk: &[u8], + prklen: u32, + info: &[u8], + infolen: u32, + len: u32, +) { + let tlen: u32 = 64u32; + let n: u32 = len.wrapping_div(tlen); + let output: (&mut [u8], &mut [u8]) = okm.split_at_mut(0usize); + let mut text: Box<[u8]> = + vec![0u8; tlen.wrapping_add(infolen).wrapping_add(1u32) as usize].into_boxed_slice(); + ((&mut (&mut text)[tlen as usize..])[0usize..infolen as usize]) + .copy_from_slice(&info[0usize..infolen as usize]); + let mut tag: Box<[u8]> = vec![0u8; tlen as usize].into_boxed_slice(); + for i in 0u32..n { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = i.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if i == 0u32 { + libcrux_hmac::hacl::hmac::compute_blake2b_32( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_blake2b_32( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + ((&mut output.1[i.wrapping_mul(tlen) as usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]) + } + if n.wrapping_mul(tlen) < len { + let ctr: (&mut [u8], &mut [u8]) = text.split_at_mut(tlen.wrapping_add(infolen) as usize); + ctr.1[0usize] = n.wrapping_add(1u32) as u8; + lowstar::ignore::ignore::<&[u8]>(&text); + let text0: (&[u8], &[u8]) = text.split_at(tlen as usize); + if n == 0u32 { + libcrux_hmac::hacl::hmac::compute_blake2b_32( + &mut tag, + prk, + prklen, + text0.1, + infolen.wrapping_add(1u32), + ) + } else { + ((&mut (&mut text)[0usize..])[0usize..tlen as usize]) + .copy_from_slice(&(&tag)[0usize..tlen as usize]); + libcrux_hmac::hacl::hmac::compute_blake2b_32( + &mut tag, + prk, + prklen, + &text, + tlen.wrapping_add(infolen).wrapping_add(1u32), + ) + }; + let block: (&mut [u8], &mut [u8]) = output.1.split_at_mut(n.wrapping_mul(tlen) as usize); + (block.1[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize]).copy_from_slice( + &(&(&tag)[0usize..])[0usize..len.wrapping_sub(n.wrapping_mul(tlen)) as usize], + ) + } +} + +/** +Extract a fixed-length pseudorandom key from input keying material. + +@param prk Pointer to `HashLen` bytes of memory where pseudorandom key is written to. +@param salt Pointer to `saltlen` bytes of memory where salt value is read from. +@param saltlen Length of salt value. +@param ikm Pointer to `ikmlen` bytes of memory where input keying material is read from. +@param ikmlen Length of input keying material. +*/ +pub fn extract_blake2b_32(prk: &mut [u8], salt: &[u8], saltlen: u32, ikm: &[u8], ikmlen: u32) { + libcrux_hmac::hacl::hmac::compute_blake2b_32(prk, salt, saltlen, ikm, ikmlen) +} +*/ diff --git a/libcrux-hkdf/src/hacl_hkdf.rs b/libcrux-hkdf/src/hacl_hkdf.rs deleted file mode 100644 index 346060e04..000000000 --- a/libcrux-hkdf/src/hacl_hkdf.rs +++ /dev/null @@ -1,137 +0,0 @@ -#![allow(dead_code)] - -/// HKDF Errors. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Error { - /// The requested output key material in expand was too large for the used - /// hash function. - OkmTooLarge, - /// At least one function argument has been too large to process. - ArgumentsTooLarge, -} - -macro_rules! impl_hkdf { - ($name:ident,$extract:ident,$expand:ident,$tag_len:literal) => { - pub mod $name { - use super::Error; - - /// HKDF extract using the `salt`, and the input key material `ikm`. - /// Returns the pre-key material in an array of tag length. - /// - /// Note that this function panics if `salt` or `ikm` is larger than 2**32 bytes. - pub fn extract(salt: &[u8], ikm: &[u8]) -> [u8; $tag_len] { - let mut prk = [0u8; $tag_len]; - unsafe { - libcrux_hacl::$extract( - prk.as_mut_ptr(), - salt.as_ptr() as _, - salt.len().try_into().unwrap(), - ikm.as_ptr() as _, - ikm.len().try_into().unwrap(), - ); - } - prk - } - - /// HKDF expand using the pre-key material `prk` and `info`. The output length - /// is defined through the result type. - /// Returns the key material in an array of length `okm_len` or - /// [`Error::OkmTooLarge`] if the requested `okm_len` is too large. - /// - /// Note that this function returns an [`Error::ArgumentsTooLarge`] - /// if `salt`, `ikm`, or `OKM_LEN` is larger than 2**32 bytes. - pub fn expand( - prk: &[u8], - info: &[u8], - ) -> Result<[u8; OKM_LEN], Error> { - if OKM_LEN > 255 * $tag_len { - // Output size is too large. HACL doesn't catch this. - return Err(Error::OkmTooLarge); - } - let mut okm = [0u8; OKM_LEN]; - unsafe { - libcrux_hacl::$expand( - okm.as_mut_ptr(), - prk.as_ptr() as _, - prk.len().try_into().map_err(|_| Error::ArgumentsTooLarge)?, - info.as_ptr() as _, - info.len() - .try_into() - .map_err(|_| Error::ArgumentsTooLarge)?, - OKM_LEN.try_into().map_err(|_| Error::ArgumentsTooLarge)?, - ); - } - Ok(okm) - } - - /// HKDF using the `salt`, input key material `ikm`, `info`. The output length - /// is defined through the result type. - /// Calls `extract` and `expand` with the given input. - /// - /// Returns the key material in an array of length `okm_len`. - pub fn hkdf( - salt: &[u8], - ikm: &[u8], - info: &[u8], - ) -> Result<[u8; OKM_LEN], Error> { - let prk = extract(salt, ikm); - expand(&prk, info) - } - - /// This module uses heap allocated vectors for cases where the output - /// length is not const. - pub mod vec { - use super::super::Error; - - /// HKDF expand using the pre-key material `prk` and `info`. The output length - /// is defined through the result type. - /// Returns the key material in an array of length `okm_len` or - /// [`Error::OkmTooLarge`] if the requested `okm_len` is too large. - /// - /// Note that this function returns an [`Error::ArgumentsTooLarge`] - /// if `salt`, `ikm`, or `OKM_LEN` is larger than 2**32 bytes. - pub fn expand(prk: &[u8], info: &[u8], okm_len: usize) -> Result, Error> { - if okm_len > 255 * $tag_len { - // Output size is too large. HACL doesn't catch this. - return Err(Error::OkmTooLarge); - } - let mut okm = vec![0u8; okm_len]; - unsafe { - libcrux_hacl::$expand( - okm.as_mut_ptr(), - prk.as_ptr() as _, - prk.len().try_into().map_err(|_| Error::ArgumentsTooLarge)?, - info.as_ptr() as _, - info.len() - .try_into() - .map_err(|_| Error::ArgumentsTooLarge)?, - okm_len.try_into().map_err(|_| Error::ArgumentsTooLarge)?, - ); - } - Ok(okm) - } - } - } - }; -} - -impl_hkdf!( - sha2_256, - Hacl_HKDF_extract_sha2_256, - Hacl_HKDF_expand_sha2_256, - 32 -); - -impl_hkdf!( - sha2_384, - Hacl_HKDF_extract_sha2_384, - Hacl_HKDF_expand_sha2_384, - 48 -); - -impl_hkdf!( - sha2_512, - Hacl_HKDF_extract_sha2_512, - Hacl_HKDF_expand_sha2_512, - 64 -); diff --git a/libcrux-hkdf/src/hkdf.rs b/libcrux-hkdf/src/hkdf.rs index c3a9036fe..83a0ca004 100644 --- a/libcrux-hkdf/src/hkdf.rs +++ b/libcrux-hkdf/src/hkdf.rs @@ -2,7 +2,13 @@ //! //! This crate implements HKDF on SHA 1 and SHA 2 (except for SHA 224). -pub(crate) mod hacl_hkdf; +#[cfg(feature = "hacl")] +pub mod hacl; + +#[cfg(feature = "hacl")] +mod impl_hacl; + +use impl_hacl::{HkdfMode, HkdfSha2_256, HkdfSha2_384, HkdfSha2_512}; /// The HKDF algorithm defining the used hash function. #[derive(Copy, Clone, Debug, PartialEq)] @@ -12,25 +18,40 @@ pub enum Algorithm { Sha512, } +impl Algorithm { + /// Returns the length of the underlying hash function. + pub const fn hash_len(self) -> usize { + match self { + Algorithm::Sha256 => 32, + Algorithm::Sha384 => 48, + Algorithm::Sha512 => 64, + } + } +} + /// HKDF Errors #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Error { - OkmLengthTooLarge, + /// The requested output key material in expand was too large for the used + /// hash function. + OkmTooLarge, + /// At least one function argument has been too large to process. + ArgumentsTooLarge, } /// HKDF extract using hash function `mode`, `salt`, and the input key material `ikm`. /// Returns the pre-key material in a vector of tag length. -pub fn extract(alg: Algorithm, salt: impl AsRef<[u8]>, ikm: impl AsRef<[u8]>) -> Vec { +pub fn extract( + alg: Algorithm, + salt: impl AsRef<[u8]>, + ikm: impl AsRef<[u8]>, +) -> Result, Error> { + let salt = salt.as_ref(); + let ikm = ikm.as_ref(); match alg { - Algorithm::Sha256 => { - crate::hacl_hkdf::sha2_256::extract(salt.as_ref(), ikm.as_ref()).into() - } - Algorithm::Sha384 => { - crate::hacl_hkdf::sha2_384::extract(salt.as_ref(), ikm.as_ref()).into() - } - Algorithm::Sha512 => { - crate::hacl_hkdf::sha2_512::extract(salt.as_ref(), ikm.as_ref()).into() - } + Algorithm::Sha256 => allocbuf(|prk| HkdfSha2_256::extract(prk, salt, ikm)), + Algorithm::Sha384 => allocbuf(|prk| HkdfSha2_384::extract(prk, salt, ikm)), + Algorithm::Sha512 => allocbuf(|prk| HkdfSha2_512::extract(prk, salt, ikm)), } } @@ -43,19 +64,12 @@ pub fn expand( info: impl AsRef<[u8]>, okm_len: usize, ) -> Result, Error> { + let prk = prk.as_ref(); + let info = info.as_ref(); match alg { - Algorithm::Sha256 => { - crate::hacl_hkdf::sha2_256::vec::expand(prk.as_ref(), info.as_ref(), okm_len) - .map_err(|_| Error::OkmLengthTooLarge) - } - Algorithm::Sha384 => { - crate::hacl_hkdf::sha2_384::vec::expand(prk.as_ref(), info.as_ref(), okm_len) - .map_err(|_| Error::OkmLengthTooLarge) - } - Algorithm::Sha512 => { - crate::hacl_hkdf::sha2_512::vec::expand(prk.as_ref(), info.as_ref(), okm_len) - .map_err(|_| Error::OkmLengthTooLarge) - } + Algorithm::Sha256 => HkdfSha2_256::expand_vec(prk, info, okm_len), + Algorithm::Sha384 => HkdfSha2_384::expand_vec(prk, info, okm_len), + Algorithm::Sha512 => HkdfSha2_512::expand_vec(prk, info, okm_len), } } @@ -65,11 +79,24 @@ pub fn expand( /// if the requested output length is too large. pub fn hkdf( mode: Algorithm, - salt: &[u8], - ikm: &[u8], - info: &[u8], + salt: impl AsRef<[u8]>, + ikm: impl AsRef<[u8]>, + info: impl AsRef<[u8]>, okm_len: usize, ) -> Result, Error> { - let prk = extract(mode, salt, ikm); - expand(mode, prk, info, okm_len) + let salt = salt.as_ref(); + let ikm = ikm.as_ref(); + let info = info.as_ref(); + + match mode { + Algorithm::Sha256 => HkdfSha2_256::hkdf_vec(salt, ikm, info, okm_len), + Algorithm::Sha384 => HkdfSha2_384::hkdf_vec(salt, ikm, info, okm_len), + Algorithm::Sha512 => HkdfSha2_512::hkdf_vec(salt, ikm, info, okm_len), + } +} + +fn allocbuf Result>(f: F) -> Result, E> { + let mut buf = [0u8; N]; + + f(&mut buf).map(|_| buf.into()) } diff --git a/libcrux-hkdf/src/impl_hacl.rs b/libcrux-hkdf/src/impl_hacl.rs new file mode 100644 index 000000000..a296a72ff --- /dev/null +++ b/libcrux-hkdf/src/impl_hacl.rs @@ -0,0 +1,224 @@ +#![allow(dead_code)] + +use crate::{Algorithm, Error}; + +pub trait HkdfMode { + /// The hash algorithm used in this HKDF mode. + const MODE: Algorithm; + + /// HKDF extract using the `salt` and the input key material `ikm`. + /// The result is written to `prk`. + /// + /// Note that this function panics if `salt` or `ikm` is longer than (2**32 - 1) bytes. + fn extract(prk: &mut [u8; HASH_LEN], salt: &[u8], ikm: &[u8]) -> Result<(), Error>; + + /// HKDF expand using the pre-key material `prk` and `info`. The output length + /// is defined through the type of the `okm` parameter, that the output is written to. + /// + /// Returns nothing on success. + /// Returns [`Error::OkmTooLarge`] if the requested `okm_len` is too large. + /// Returns [`Error::ArgumentsTooLarge`] if one of `salt` or `ikm` are longer than, or + /// `OKM_LEN` is larger than (2**32 - 1) bytes. + fn expand( + okm: &mut [u8; OKM_LEN], + prk: &[u8], + info: &[u8], + ) -> Result<(), Error>; + + /// HKDF expand using the pre-key material `prk` and `info`. The output length + /// is defined by the parameter `okm_len`. + /// + /// Returns the key material in an array of length `okm_len` on success. + /// Returns [`Error::OkmTooLarge`] if the requested `okm_len` is too large. + /// Returns [`Error::ArgumentsTooLarge`] if `salt` or `ikm` is longer than + /// (2**32 - 1) bytes. + fn expand_vec(prk: &[u8], info: &[u8], okm_len: usize) -> Result, Error>; + + /// HKDF using the `salt`, input key material `ikm`, `info`. The output length + /// is defined through the result type. + /// Calls `extract` and `expand` with the given input. + /// + /// Returns the key material in an array of length `okm_len`. + /// Note that this function panics if `salt` or `ikm` is longer than (2**32 - 1) bytes. + fn hkdf( + okm: &mut [u8; OKM_LEN], + salt: &[u8], + ikm: &[u8], + info: &[u8], + ) -> Result<(), Error> { + let mut prk = [0u8; HASH_LEN]; + Self::extract(&mut prk, salt, ikm)?; + Self::expand(okm, &prk, info) + } + + /// HKDF using the `salt`, input key material `ikm`, `info`. The output length + /// is defined by the parameter `okm_len`. + /// Calls `extract` and `expand` with the given input. + /// + /// Returns the key material in an array of length `okm_len`. + /// Note that this function panics if `salt` or `ikm` is longer than (2**32 - 1) bytes. + fn hkdf_vec(salt: &[u8], ikm: &[u8], info: &[u8], okm_len: usize) -> Result, Error> { + let mut prk = [0u8; HASH_LEN]; + Self::extract(&mut prk, salt, ikm)?; + Self::expand_vec(&prk, info, okm_len) + } +} + +macro_rules! impl_hkdf { + ($sname:ident,$name:ident, $mode:path, $extract:ident, $expand:ident,$hash_len:literal) => { + pub struct $sname; + + pub mod $name { + use super::{checked_u32, $sname, Algorithm, Error, HkdfMode}; + + impl HkdfMode<$hash_len> for $sname { + const MODE: Algorithm = $mode; + + fn extract( + prk: &mut [u8; $hash_len], + salt: &[u8], + ikm: &[u8], + ) -> Result<(), Error> { + extract(prk, salt, ikm) + } + + fn expand( + okm: &mut [u8; OKM_LEN], + prk: &[u8], + info: &[u8], + ) -> Result<(), Error> { + expand(okm, prk, info) + } + + fn expand_vec(prk: &[u8], info: &[u8], okm_len: usize) -> Result, Error> { + vec::expand(prk, info, okm_len) + } + } + + /// HKDF extract using the `salt`, and the input key material `ikm`. + /// Returns the pre-key material in an array of hash length. + /// + /// Note that this function returns an [`Error::ArgumentsTooLarge`] + /// if `salt` or `ikm` is larger than 2**32 bytes. + pub fn extract( + prk: &mut [u8; $hash_len], + salt: &[u8], + ikm: &[u8], + ) -> Result<(), Error> { + Ok(crate::hacl::$extract( + prk, + salt, + checked_u32(salt.len())?, + ikm, + checked_u32(ikm.len())?, + )) + } + + /// HKDF expand using the pre-key material `prk` and `info`. The output length + /// is defined through the result type. + /// Returns the key material in an array of length `okm_len` or + /// [`Error::OkmTooLarge`] if the requested `okm_len` is too large. + /// + /// Note that this function returns an [`Error::ArgumentsTooLarge`] + /// if `prk`, `info`, or `OKM_LEN` is larger than 2**32 bytes. + pub fn expand( + okm: &mut [u8; OKM_LEN], + prk: &[u8], + info: &[u8], + ) -> Result<(), Error> { + if OKM_LEN > 255 * $hash_len { + // Output size is too large. HACL doesn't catch this. + return Err(Error::OkmTooLarge); + } + + Ok(crate::hacl::$expand( + okm, + prk, + checked_u32(prk.len())?, + info, + checked_u32(info.len())?, + checked_u32(OKM_LEN)?, + )) + } + + /// HKDF using the `salt`, input key material `ikm`, `info`. The output length + /// is defined through the result type. + /// Calls `extract` and `expand` with the given input. + /// + /// Returns the key material in an array of length `okm_len`. + /// Note that this function panics if `salt` or `ikm` is longer than (2**32 - 1) bytes. + pub fn hkdf( + okm: &mut [u8; OKM_LEN], + salt: &[u8], + ikm: &[u8], + info: &[u8], + ) -> Result<(), Error> { + let mut prk = [0u8; $hash_len]; + extract(&mut prk, salt, ikm)?; + expand(okm, &prk, info) + } + + /// This module uses heap allocated vectors for cases where the output + /// length is not const. + pub mod vec { + use super::{checked_u32, Error}; + + /// HKDF expand using the pre-key material `prk` and `info`. The output length + /// is defined by the parameter `okm_len`. + /// Returns the key material in an array of length `okm_len` or + /// [`Error::OkmTooLarge`] if the requested `okm_len` is too large. + /// + /// Note that this function returns an [`Error::ArgumentsTooLarge`] + /// if `salt`, `ikm`, or `OKM_LEN` is longer than (2**32 - 1) bytes. + pub fn expand(prk: &[u8], info: &[u8], okm_len: usize) -> Result, Error> { + if okm_len > 255 * $hash_len { + // Output size is too large. HACL doesn't catch this. + return Err(Error::OkmTooLarge); + } + + let mut okm = vec![0u8; okm_len]; + crate::hacl::$expand( + &mut okm, + prk, + checked_u32(prk.len())?, + info, + checked_u32(info.len())?, + checked_u32(okm_len)?, + ); + Ok(okm) + } + } + } + }; +} + +impl_hkdf!( + HkdfSha2_256, + sha2_256, + Algorithm::Sha256, + extract_sha2_256, + expand_sha2_256, + 32 +); + +impl_hkdf!( + HkdfSha2_384, + sha2_384, + Algorithm::Sha384, + extract_sha2_384, + expand_sha2_384, + 48 +); + +impl_hkdf!( + HkdfSha2_512, + sha2_512, + Algorithm::Sha512, + extract_sha2_512, + expand_sha2_512, + 64 +); + +fn checked_u32(num: usize) -> Result { + num.try_into().map_err(|_| Error::ArgumentsTooLarge) +} diff --git a/libcrux-hmac/Cargo.toml b/libcrux-hmac/Cargo.toml index a29de12d0..f2cd55674 100644 --- a/libcrux-hmac/Cargo.toml +++ b/libcrux-hmac/Cargo.toml @@ -12,6 +12,14 @@ description = "Libcrux HMAC implementation" [lib] path = "src/hmac.rs" +[features] +default = ["portable_hacl"] +portable_hacl = ["hacl"] +hacl = ["dep:libcrux-sha2", "dep:libcrux-hacl-rs", "dep:libcrux-macros"] + [dependencies] -libcrux-hkdf = { version = "=0.0.2-beta.2", path = "../libcrux-hkdf" } -libcrux-hacl = { version = "=0.0.2-beta.2", path = "../sys/hacl" } +libcrux-hacl-rs = { version = "=0.0.2-beta.2", path = "../hacl-rs/", optional = true } +libcrux-sha2 = { version = "=0.0.2-beta.2", path = "../sha2", optional = true, features = [ + "hacl", +] } +libcrux-macros = { version = "=0.0.2-beta.2", path = "../macros", optional = true } diff --git a/libcrux-hmac/src/hacl/hash_sha1.rs b/libcrux-hmac/src/hacl/hash_sha1.rs new file mode 100644 index 000000000..ff65765b9 --- /dev/null +++ b/libcrux-hmac/src/hacl/hash_sha1.rs @@ -0,0 +1,381 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_hacl_rs::lowstar; +use libcrux_macros as krml; + +const _h0: [u32; 5] = [ + 0x67452301u32, + 0xefcdab89u32, + 0x98badcfeu32, + 0x10325476u32, + 0xc3d2e1f0u32, +]; + +pub(crate) fn init(s: &mut [u32]) { + krml::unroll_for!( + 5, + "i", + 0u32, + 1u32, + s[i as usize] = (&crate::hacl::hash_sha1::_h0)[i as usize] + ) +} + +fn update(h: &mut [u32], l: &[u8]) { + let ha: u32 = h[0usize]; + let hb: u32 = h[1usize]; + let hc: u32 = h[2usize]; + let hd: u32 = h[3usize]; + let he: u32 = h[4usize]; + let mut _w: [u32; 80] = [0u32; 80usize]; + for i in 0u32..80u32 { + let v: u32 = if i < 16u32 { + let b: (&[u8], &[u8]) = l.split_at(i.wrapping_mul(4u32) as usize); + let u: u32 = lowstar::endianness::load32_be(b.1); + u + } else { + let wmit3: u32 = (&_w)[i.wrapping_sub(3u32) as usize]; + let wmit8: u32 = (&_w)[i.wrapping_sub(8u32) as usize]; + let wmit14: u32 = (&_w)[i.wrapping_sub(14u32) as usize]; + let wmit16: u32 = (&_w)[i.wrapping_sub(16u32) as usize]; + (wmit3 ^ (wmit8 ^ (wmit14 ^ wmit16))).wrapping_shl(1u32) + | (wmit3 ^ (wmit8 ^ (wmit14 ^ wmit16))).wrapping_shr(31u32) + }; + (&mut _w)[i as usize] = v + } + for i in 0u32..80u32 { + let _a: u32 = h[0usize]; + let _b: u32 = h[1usize]; + let _c: u32 = h[2usize]; + let _d: u32 = h[3usize]; + let _e: u32 = h[4usize]; + let wmit: u32 = (&_w)[i as usize]; + let ite: u32 = if i < 20u32 { + _b & _c ^ !_b & _d + } else if 39u32 < i && i < 60u32 { + _b & _c ^ (_b & _d ^ _c & _d) + } else { + _b ^ (_c ^ _d) + }; + let ite0: u32 = if i < 20u32 { + 0x5a827999u32 + } else if i < 40u32 { + 0x6ed9eba1u32 + } else if i < 60u32 { + 0x8f1bbcdcu32 + } else { + 0xca62c1d6u32 + }; + let _T: u32 = (_a.wrapping_shl(5u32) | _a.wrapping_shr(27u32)) + .wrapping_add(ite) + .wrapping_add(_e) + .wrapping_add(ite0) + .wrapping_add(wmit); + h[0usize] = _T; + h[1usize] = _a; + h[2usize] = _b.wrapping_shl(30u32) | _b.wrapping_shr(2u32); + h[3usize] = _c; + h[4usize] = _d + } + for i in 0u32..80u32 { + (&mut _w)[i as usize] = 0u32 + } + let sta: u32 = h[0usize]; + let stb: u32 = h[1usize]; + let stc: u32 = h[2usize]; + let std: u32 = h[3usize]; + let ste: u32 = h[4usize]; + h[0usize] = sta.wrapping_add(ha); + h[1usize] = stb.wrapping_add(hb); + h[2usize] = stc.wrapping_add(hc); + h[3usize] = std.wrapping_add(hd); + h[4usize] = ste.wrapping_add(he) +} + +fn pad(len: u64, dst: &mut [u8]) { + let dst1: (&mut [u8], &mut [u8]) = dst.split_at_mut(0usize); + dst1.1[0usize] = 0x80u8; + let dst2: (&mut [u8], &mut [u8]) = dst1.1.split_at_mut(1usize); + for i in 0u32..128u32 + .wrapping_sub(9u32.wrapping_add(len.wrapping_rem(64u32 as u64) as u32)) + .wrapping_rem(64u32) + { + dst2.1[i as usize] = 0u8 + } + let dst3: (&mut [u8], &mut [u8]) = dst2.1.split_at_mut( + 128u32 + .wrapping_sub(9u32.wrapping_add(len.wrapping_rem(64u32 as u64) as u32)) + .wrapping_rem(64u32) as usize, + ); + lowstar::endianness::store64_be(dst3.1, len.wrapping_shl(3u32)) +} + +pub(crate) fn finish(s: &[u32], dst: &mut [u8]) { + krml::unroll_for!( + 5, + "i", + 0u32, + 1u32, + lowstar::endianness::store32_be( + &mut dst[i.wrapping_mul(4u32) as usize..], + (&s[0usize..])[i as usize] + ) + ) +} + +pub(crate) fn update_multi(s: &mut [u32], blocks: &[u8], n_blocks: u32) { + for i in 0u32..n_blocks { + let sz: u32 = 64u32; + let block: (&[u8], &[u8]) = blocks.split_at(sz.wrapping_mul(i) as usize); + crate::hacl::hash_sha1::update(s, block.1) + } +} + +pub(crate) fn update_last(s: &mut [u32], prev_len: u64, input: &[u8], input_len: u32) { + let blocks_n: u32 = input_len.wrapping_div(64u32); + let blocks_len: u32 = blocks_n.wrapping_mul(64u32); + let blocks: (&[u8], &[u8]) = input.split_at(0usize); + let rest_len: u32 = input_len.wrapping_sub(blocks_len); + let rest: (&[u8], &[u8]) = blocks.1.split_at(blocks_len as usize); + crate::hacl::hash_sha1::update_multi(s, rest.0, blocks_n); + let total_input_len: u64 = prev_len.wrapping_add(input_len as u64); + let pad_len: u32 = 1u32 + .wrapping_add( + 128u32 + .wrapping_sub(9u32.wrapping_add(total_input_len.wrapping_rem(64u32 as u64) as u32)) + .wrapping_rem(64u32), + ) + .wrapping_add(8u32); + let tmp_len: u32 = rest_len.wrapping_add(pad_len); + let mut tmp_twoblocks: [u8; 128] = [0u8; 128usize]; + let tmp: (&mut [u8], &mut [u8]) = tmp_twoblocks.split_at_mut(0usize); + let tmp_rest: (&mut [u8], &mut [u8]) = tmp.1.split_at_mut(0usize); + let tmp_pad: (&mut [u8], &mut [u8]) = tmp_rest.1.split_at_mut(rest_len as usize); + (tmp_pad.0[0usize..rest_len as usize]).copy_from_slice(&rest.1[0usize..rest_len as usize]); + crate::hacl::hash_sha1::pad(total_input_len, tmp_pad.1); + crate::hacl::hash_sha1::update_multi(s, tmp.1, tmp_len.wrapping_div(64u32)) +} + +pub(crate) fn hash_oneshot(output: &mut [u8], input: &[u8], input_len: u32) { + let mut s: [u32; 5] = [ + 0x67452301u32, + 0xefcdab89u32, + 0x98badcfeu32, + 0x10325476u32, + 0xc3d2e1f0u32, + ]; + let blocks_n: u32 = input_len.wrapping_div(64u32); + let blocks_n1: u32 = if input_len.wrapping_rem(64u32) == 0u32 && blocks_n > 0u32 { + blocks_n.wrapping_sub(1u32) + } else { + blocks_n + }; + let blocks_len: u32 = blocks_n1.wrapping_mul(64u32); + let blocks: (&[u8], &[u8]) = input.split_at(0usize); + let rest_len: u32 = input_len.wrapping_sub(blocks_len); + let rest: (&[u8], &[u8]) = blocks.1.split_at(blocks_len as usize); + let blocks_n0: u32 = blocks_n1; + let blocks_len0: u32 = blocks_len; + let blocks0: &[u8] = rest.0; + let rest_len0: u32 = rest_len; + let rest0: &[u8] = rest.1; + crate::hacl::hash_sha1::update_multi(&mut s, blocks0, blocks_n0); + crate::hacl::hash_sha1::update_last(&mut s, blocks_len0 as u64, rest0, rest_len0); + crate::hacl::hash_sha1::finish(&s, output) +} + +pub type state_t = libcrux_hacl_rs::streaming_types::state_32; + +pub fn malloc() -> Box<[libcrux_hacl_rs::streaming_types::state_32]> { + let buf: Box<[u8]> = vec![0u8; 64usize].into_boxed_slice(); + let mut block_state: Box<[u32]> = vec![0u32; 5usize].into_boxed_slice(); + crate::hacl::hash_sha1::init(&mut block_state); + let s: libcrux_hacl_rs::streaming_types::state_32 = + libcrux_hacl_rs::streaming_types::state_32 { + block_state, + buf, + total_len: 0u32 as u64, + }; + let p: Box<[libcrux_hacl_rs::streaming_types::state_32]> = vec![s].into_boxed_slice(); + p +} + +pub fn reset(state: &mut [libcrux_hacl_rs::streaming_types::state_32]) { + let block_state: &mut [u32] = &mut (state[0usize]).block_state; + crate::hacl::hash_sha1::init(block_state); + let total_len: u64 = 0u32 as u64; + (state[0usize]).total_len = total_len +} + +/** +0 = success, 1 = max length exceeded +*/ +pub fn update0( + state: &mut [libcrux_hacl_rs::streaming_types::state_32], + chunk: &[u8], + chunk_len: u32, +) -> libcrux_hacl_rs::streaming_types::error_code { + let block_state: &mut [u32] = &mut (state[0usize]).block_state; + let total_len: u64 = (state[0usize]).total_len; + if chunk_len as u64 > 2305843009213693951u64.wrapping_sub(total_len) { + libcrux_hacl_rs::streaming_types::error_code::MaximumLengthExceeded + } else { + let sz: u32 = if total_len.wrapping_rem(64u32 as u64) == 0u64 && total_len > 0u64 { + 64u32 + } else { + total_len.wrapping_rem(64u32 as u64) as u32 + }; + if chunk_len <= 64u32.wrapping_sub(sz) { + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(64u32 as u64) == 0u64 && total_len1 > 0u64 { + 64u32 + } else { + total_len1.wrapping_rem(64u32 as u64) as u32 + }; + let buf2: (&mut [u8], &mut [u8]) = buf.split_at_mut(sz1 as usize); + (buf2.1[0usize..chunk_len as usize]) + .copy_from_slice(&chunk[0usize..chunk_len as usize]); + let total_len2: u64 = total_len1.wrapping_add(chunk_len as u64); + (state[0usize]).total_len = total_len2 + } else if sz == 0u32 { + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(64u32 as u64) == 0u64 && total_len1 > 0u64 { + 64u32 + } else { + total_len1.wrapping_rem(64u32 as u64) as u32 + }; + if sz1 != 0u32 { + crate::hacl::hash_sha1::update_multi(block_state, buf, 1u32) + }; + let ite: u32 = if (chunk_len as u64).wrapping_rem(64u32 as u64) == 0u64 + && chunk_len as u64 > 0u64 + { + 64u32 + } else { + (chunk_len as u64).wrapping_rem(64u32 as u64) as u32 + }; + let n_blocks: u32 = chunk_len.wrapping_sub(ite).wrapping_div(64u32); + let data1_len: u32 = n_blocks.wrapping_mul(64u32); + let data2_len: u32 = chunk_len.wrapping_sub(data1_len); + let data1: (&[u8], &[u8]) = chunk.split_at(0usize); + let data2: (&[u8], &[u8]) = data1.1.split_at(data1_len as usize); + crate::hacl::hash_sha1::update_multi( + block_state, + data2.0, + data1_len.wrapping_div(64u32), + ); + let dst: (&mut [u8], &mut [u8]) = buf.split_at_mut(0usize); + (dst.1[0usize..data2_len as usize]) + .copy_from_slice(&data2.1[0usize..data2_len as usize]); + (state[0usize]).total_len = total_len1.wrapping_add(chunk_len as u64) + } else { + let diff: u32 = 64u32.wrapping_sub(sz); + let chunk1: (&[u8], &[u8]) = chunk.split_at(0usize); + let chunk2: (&[u8], &[u8]) = chunk1.1.split_at(diff as usize); + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(64u32 as u64) == 0u64 && total_len1 > 0u64 { + 64u32 + } else { + total_len1.wrapping_rem(64u32 as u64) as u32 + }; + let buf2: (&mut [u8], &mut [u8]) = buf.split_at_mut(sz1 as usize); + (buf2.1[0usize..diff as usize]).copy_from_slice(&chunk2.0[0usize..diff as usize]); + let total_len2: u64 = total_len1.wrapping_add(diff as u64); + (state[0usize]).total_len = total_len2; + let buf0: &mut [u8] = &mut (state[0usize]).buf; + let total_len10: u64 = (state[0usize]).total_len; + let sz10: u32 = if total_len10.wrapping_rem(64u32 as u64) == 0u64 && total_len10 > 0u64 + { + 64u32 + } else { + total_len10.wrapping_rem(64u32 as u64) as u32 + }; + if sz10 != 0u32 { + crate::hacl::hash_sha1::update_multi(block_state, buf0, 1u32) + }; + let ite: u32 = if (chunk_len.wrapping_sub(diff) as u64).wrapping_rem(64u32 as u64) + == 0u64 + && chunk_len.wrapping_sub(diff) as u64 > 0u64 + { + 64u32 + } else { + (chunk_len.wrapping_sub(diff) as u64).wrapping_rem(64u32 as u64) as u32 + }; + let n_blocks: u32 = chunk_len + .wrapping_sub(diff) + .wrapping_sub(ite) + .wrapping_div(64u32); + let data1_len: u32 = n_blocks.wrapping_mul(64u32); + let data2_len: u32 = chunk_len.wrapping_sub(diff).wrapping_sub(data1_len); + let data1: (&[u8], &[u8]) = chunk2.1.split_at(0usize); + let data2: (&[u8], &[u8]) = data1.1.split_at(data1_len as usize); + crate::hacl::hash_sha1::update_multi( + block_state, + data2.0, + data1_len.wrapping_div(64u32), + ); + let dst: (&mut [u8], &mut [u8]) = buf0.split_at_mut(0usize); + (dst.1[0usize..data2_len as usize]) + .copy_from_slice(&data2.1[0usize..data2_len as usize]); + (state[0usize]).total_len = + total_len10.wrapping_add(chunk_len.wrapping_sub(diff) as u64) + }; + libcrux_hacl_rs::streaming_types::error_code::Success + } +} + +pub fn digest(state: &[libcrux_hacl_rs::streaming_types::state_32], output: &mut [u8]) { + let block_state: &[u32] = &(state[0usize]).block_state; + let buf_: &[u8] = &(state[0usize]).buf; + let total_len: u64 = (state[0usize]).total_len; + let r: u32 = if total_len.wrapping_rem(64u32 as u64) == 0u64 && total_len > 0u64 { + 64u32 + } else { + total_len.wrapping_rem(64u32 as u64) as u32 + }; + let buf_1: (&[u8], &[u8]) = buf_.split_at(0usize); + let mut tmp_block_state: [u32; 5] = [0u32; 5usize]; + ((&mut tmp_block_state)[0usize..5usize]).copy_from_slice(&block_state[0usize..5usize]); + let buf_multi: (&[u8], &[u8]) = buf_1.1.split_at(0usize); + let ite: u32 = if r.wrapping_rem(64u32) == 0u32 && r > 0u32 { + 64u32 + } else { + r.wrapping_rem(64u32) + }; + let buf_last: (&[u8], &[u8]) = buf_multi.1.split_at(r.wrapping_sub(ite) as usize); + crate::hacl::hash_sha1::update_multi(&mut tmp_block_state, buf_last.0, 0u32); + let prev_len_last: u64 = total_len.wrapping_sub(r as u64); + crate::hacl::hash_sha1::update_last(&mut tmp_block_state, prev_len_last, buf_last.1, r); + crate::hacl::hash_sha1::finish(&tmp_block_state, output) +} + +pub fn copy( + state: &[libcrux_hacl_rs::streaming_types::state_32], +) -> Box<[libcrux_hacl_rs::streaming_types::state_32]> { + let block_state0: &[u32] = &(state[0usize]).block_state; + let buf0: &[u8] = &(state[0usize]).buf; + let total_len0: u64 = (state[0usize]).total_len; + let mut buf: Box<[u8]> = vec![0u8; 64usize].into_boxed_slice(); + ((&mut buf)[0usize..64usize]).copy_from_slice(&buf0[0usize..64usize]); + let mut block_state: Box<[u32]> = vec![0u32; 5usize].into_boxed_slice(); + ((&mut block_state)[0usize..5usize]).copy_from_slice(&block_state0[0usize..5usize]); + let s: libcrux_hacl_rs::streaming_types::state_32 = + libcrux_hacl_rs::streaming_types::state_32 { + block_state, + buf, + total_len: total_len0, + }; + let p: Box<[libcrux_hacl_rs::streaming_types::state_32]> = vec![s].into_boxed_slice(); + p +} + +pub fn hash(output: &mut [u8], input: &[u8], input_len: u32) { + crate::hacl::hash_sha1::hash_oneshot(output, input, input_len) +} diff --git a/libcrux-hmac/src/hacl/hmac.rs b/libcrux-hmac/src/hacl/hmac.rs new file mode 100644 index 000000000..2f65574e9 --- /dev/null +++ b/libcrux-hmac/src/hacl/hmac.rs @@ -0,0 +1,761 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_hacl_rs::fstar; +use libcrux_hacl_rs::lowstar; +use libcrux_macros as krml; +use libcrux_sha2::hacl as hash_sha2; + +#[derive(PartialEq, Clone, Copy)] +pub(crate) struct __uint32_t_uint32_t { + pub fst: u32, + pub snd: u32, +} + +/** +Write the HMAC-SHA-1 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 byte. +`dst` must point to 20 bytes of memory. +*/ +pub fn compute_sha1(dst: &mut [u8], key: &[u8], key_len: u32, data: &[u8], data_len: u32) { + let l: u32 = 64u32; + let mut key_block: Box<[u8]> = vec![0x00u8; l as usize].into_boxed_slice(); + let nkey: (&mut [u8], &mut [u8]) = key_block.split_at_mut(0usize); + let ite: u32 = if key_len <= 64u32 { key_len } else { 20u32 }; + let zeroes: (&mut [u8], &mut [u8]) = nkey.1.split_at_mut(ite as usize); + lowstar::ignore::ignore::<&[u8]>(zeroes.1); + if key_len <= 64u32 { + (zeroes.0[0usize..key_len as usize]).copy_from_slice(&key[0usize..key_len as usize]) + } else { + super::hash_sha1::hash_oneshot(zeroes.0, key, key_len) + }; + let mut ipad: Box<[u8]> = vec![0x36u8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&ipad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut ipad)[i as usize] = xi ^ yi + } + let mut opad: Box<[u8]> = vec![0x5cu8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&opad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut opad)[i as usize] = xi ^ yi + } + let mut s: [u32; 5] = [ + 0x67452301u32, + 0xefcdab89u32, + 0x98badcfeu32, + 0x10325476u32, + 0xc3d2e1f0u32, + ]; + if data_len == 0u32 { + super::hash_sha1::update_last(&mut s, 0u64, &ipad, 64u32) + } else { + let block_len: u32 = 64u32; + let n_blocks: u32 = data_len.wrapping_div(block_len); + let rem: u32 = data_len.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: data_len.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = data.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + super::hash_sha1::update_multi(&mut s, &ipad, 1u32); + super::hash_sha1::update_multi(&mut s, rem0.0, n_blocks0); + super::hash_sha1::update_last( + &mut s, + (64u32 as u64).wrapping_add(full_blocks_len as u64), + rem0.1, + rem_len, + ) + }; + let dst1: (&mut [u8], &mut [u8]) = ipad.split_at_mut(0usize); + super::hash_sha1::finish(&s, dst1.1); + let hash1: (&[u8], &[u8]) = dst1.1.split_at(0usize); + super::hash_sha1::init(&mut s); + let block_len: u32 = 64u32; + let n_blocks: u32 = 20u32.wrapping_div(block_len); + let rem: u32 = 20u32.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: 20u32.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = hash1.1.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + super::hash_sha1::update_multi(&mut s, &opad, 1u32); + super::hash_sha1::update_multi(&mut s, rem0.0, n_blocks0); + super::hash_sha1::update_last( + &mut s, + (64u32 as u64).wrapping_add(full_blocks_len as u64), + rem0.1, + rem_len, + ); + super::hash_sha1::finish(&s, dst) +} + +/** +Write the HMAC-SHA-2-256 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 bytes. +`dst` must point to 32 bytes of memory. +*/ +pub fn compute_sha2_256(dst: &mut [u8], key: &[u8], key_len: u32, data: &[u8], data_len: u32) { + let l: u32 = 64u32; + let mut key_block: Box<[u8]> = vec![0x00u8; l as usize].into_boxed_slice(); + let nkey: (&mut [u8], &mut [u8]) = key_block.split_at_mut(0usize); + let ite: u32 = if key_len <= 64u32 { key_len } else { 32u32 }; + let zeroes: (&mut [u8], &mut [u8]) = nkey.1.split_at_mut(ite as usize); + lowstar::ignore::ignore::<&[u8]>(zeroes.1); + if key_len <= 64u32 { + (zeroes.0[0usize..key_len as usize]).copy_from_slice(&key[0usize..key_len as usize]) + } else { + hash_sha2::hash_256(zeroes.0, key, key_len) + }; + let mut ipad: Box<[u8]> = vec![0x36u8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&ipad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut ipad)[i as usize] = xi ^ yi + } + let mut opad: Box<[u8]> = vec![0x5cu8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&opad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut opad)[i as usize] = xi ^ yi + } + let mut st: [u32; 8] = [0u32; 8usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u32 = (&hash_sha2::h256)[i as usize]; + let os: (&mut [u32], &mut [u32]) = st.split_at_mut(0usize); + os.1[i as usize] = x + }); + let s: &mut [u32] = &mut st; + if data_len == 0u32 { + hash_sha2::sha256_update_last(0u64.wrapping_add(64u32 as u64), 64u32, &ipad, s) + } else { + let block_len: u32 = 64u32; + let n_blocks: u32 = data_len.wrapping_div(block_len); + let rem: u32 = data_len.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: data_len.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = data.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + hash_sha2::sha256_update_nblocks(64u32, &ipad, s); + hash_sha2::sha256_update_nblocks(n_blocks0.wrapping_mul(64u32), rem0.0, s); + hash_sha2::sha256_update_last( + (64u32 as u64) + .wrapping_add(full_blocks_len as u64) + .wrapping_add(rem_len as u64), + rem_len, + rem0.1, + s, + ) + }; + let dst1: (&mut [u8], &mut [u8]) = ipad.split_at_mut(0usize); + hash_sha2::sha256_finish(s, dst1.1); + let hash1: (&[u8], &[u8]) = dst1.1.split_at(0usize); + hash_sha2::sha256_init(s); + let block_len: u32 = 64u32; + let n_blocks: u32 = 32u32.wrapping_div(block_len); + let rem: u32 = 32u32.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: 32u32.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = hash1.1.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + hash_sha2::sha256_update_nblocks(64u32, &opad, s); + hash_sha2::sha256_update_nblocks(n_blocks0.wrapping_mul(64u32), rem0.0, s); + hash_sha2::sha256_update_last( + (64u32 as u64) + .wrapping_add(full_blocks_len as u64) + .wrapping_add(rem_len as u64), + rem_len, + rem0.1, + s, + ); + hash_sha2::sha256_finish(s, dst) +} + +/** +Write the HMAC-SHA-2-384 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 48 bytes of memory. +*/ +pub fn compute_sha2_384(dst: &mut [u8], key: &[u8], key_len: u32, data: &[u8], data_len: u32) { + let l: u32 = 128u32; + let mut key_block: Box<[u8]> = vec![0x00u8; l as usize].into_boxed_slice(); + let nkey: (&mut [u8], &mut [u8]) = key_block.split_at_mut(0usize); + let ite: u32 = if key_len <= 128u32 { key_len } else { 48u32 }; + let zeroes: (&mut [u8], &mut [u8]) = nkey.1.split_at_mut(ite as usize); + lowstar::ignore::ignore::<&[u8]>(zeroes.1); + if key_len <= 128u32 { + (zeroes.0[0usize..key_len as usize]).copy_from_slice(&key[0usize..key_len as usize]) + } else { + hash_sha2::hash_384(zeroes.0, key, key_len) + }; + let mut ipad: Box<[u8]> = vec![0x36u8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&ipad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut ipad)[i as usize] = xi ^ yi + } + let mut opad: Box<[u8]> = vec![0x5cu8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&opad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut opad)[i as usize] = xi ^ yi + } + let mut st: [u64; 8] = [0u64; 8usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u64 = (&hash_sha2::h384)[i as usize]; + let os: (&mut [u64], &mut [u64]) = st.split_at_mut(0usize); + os.1[i as usize] = x + }); + let s: &mut [u64] = &mut st; + if data_len == 0u32 { + hash_sha2::sha384_update_last( + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(0u64), + fstar::uint128::uint64_to_uint128(128u32 as u64), + ), + 128u32, + &ipad, + s, + ) + } else { + let block_len: u32 = 128u32; + let n_blocks: u32 = data_len.wrapping_div(block_len); + let rem: u32 = data_len.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: data_len.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = data.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + hash_sha2::sha384_update_nblocks(128u32, &ipad, s); + hash_sha2::sha384_update_nblocks(n_blocks0.wrapping_mul(128u32), rem0.0, s); + hash_sha2::sha384_update_last( + fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(128u32 as u64), + fstar::uint128::uint64_to_uint128(full_blocks_len as u64), + ), + fstar::uint128::uint64_to_uint128(rem_len as u64), + ), + rem_len, + rem0.1, + s, + ) + }; + let dst1: (&mut [u8], &mut [u8]) = ipad.split_at_mut(0usize); + hash_sha2::sha384_finish(s, dst1.1); + let hash1: (&[u8], &[u8]) = dst1.1.split_at(0usize); + hash_sha2::sha384_init(s); + let block_len: u32 = 128u32; + let n_blocks: u32 = 48u32.wrapping_div(block_len); + let rem: u32 = 48u32.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: 48u32.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = hash1.1.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + hash_sha2::sha384_update_nblocks(128u32, &opad, s); + hash_sha2::sha384_update_nblocks(n_blocks0.wrapping_mul(128u32), rem0.0, s); + hash_sha2::sha384_update_last( + fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(128u32 as u64), + fstar::uint128::uint64_to_uint128(full_blocks_len as u64), + ), + fstar::uint128::uint64_to_uint128(rem_len as u64), + ), + rem_len, + rem0.1, + s, + ); + hash_sha2::sha384_finish(s, dst) +} + +/** +Write the HMAC-SHA-2-512 MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 64 bytes of memory. +*/ +pub fn compute_sha2_512(dst: &mut [u8], key: &[u8], key_len: u32, data: &[u8], data_len: u32) { + let l: u32 = 128u32; + let mut key_block: Box<[u8]> = vec![0x00u8; l as usize].into_boxed_slice(); + let nkey: (&mut [u8], &mut [u8]) = key_block.split_at_mut(0usize); + let ite: u32 = if key_len <= 128u32 { key_len } else { 64u32 }; + let zeroes: (&mut [u8], &mut [u8]) = nkey.1.split_at_mut(ite as usize); + lowstar::ignore::ignore::<&[u8]>(zeroes.1); + if key_len <= 128u32 { + (zeroes.0[0usize..key_len as usize]).copy_from_slice(&key[0usize..key_len as usize]) + } else { + hash_sha2::hash_512(zeroes.0, key, key_len) + }; + let mut ipad: Box<[u8]> = vec![0x36u8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&ipad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut ipad)[i as usize] = xi ^ yi + } + let mut opad: Box<[u8]> = vec![0x5cu8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&opad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut opad)[i as usize] = xi ^ yi + } + let mut st: [u64; 8] = [0u64; 8usize]; + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u64 = (&hash_sha2::h512)[i as usize]; + let os: (&mut [u64], &mut [u64]) = st.split_at_mut(0usize); + os.1[i as usize] = x + }); + let s: &mut [u64] = &mut st; + if data_len == 0u32 { + hash_sha2::sha512_update_last( + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(0u64), + fstar::uint128::uint64_to_uint128(128u32 as u64), + ), + 128u32, + &ipad, + s, + ) + } else { + let block_len: u32 = 128u32; + let n_blocks: u32 = data_len.wrapping_div(block_len); + let rem: u32 = data_len.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: data_len.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = data.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + hash_sha2::sha512_update_nblocks(128u32, &ipad, s); + hash_sha2::sha512_update_nblocks(n_blocks0.wrapping_mul(128u32), rem0.0, s); + hash_sha2::sha512_update_last( + fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(128u32 as u64), + fstar::uint128::uint64_to_uint128(full_blocks_len as u64), + ), + fstar::uint128::uint64_to_uint128(rem_len as u64), + ), + rem_len, + rem0.1, + s, + ) + }; + let dst1: (&mut [u8], &mut [u8]) = ipad.split_at_mut(0usize); + hash_sha2::sha512_finish(s, dst1.1); + let hash1: (&[u8], &[u8]) = dst1.1.split_at(0usize); + hash_sha2::sha512_init(s); + let block_len: u32 = 128u32; + let n_blocks: u32 = 64u32.wrapping_div(block_len); + let rem: u32 = 64u32.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: 64u32.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = hash1.1.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + hash_sha2::sha512_update_nblocks(128u32, &opad, s); + hash_sha2::sha512_update_nblocks(n_blocks0.wrapping_mul(128u32), rem0.0, s); + hash_sha2::sha512_update_last( + fstar::uint128::add( + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(128u32 as u64), + fstar::uint128::uint64_to_uint128(full_blocks_len as u64), + ), + fstar::uint128::uint64_to_uint128(rem_len as u64), + ), + rem_len, + rem0.1, + s, + ); + hash_sha2::sha512_finish(s, dst) +} + +/* no blake2 for now + +/** +Write the HMAC-BLAKE2s MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 64 bytes. +`dst` must point to 32 bytes of memory. +*/ +pub fn compute_blake2s_32(dst: &mut [u8], key: &[u8], key_len: u32, data: &[u8], data_len: u32) { + let l: u32 = 64u32; + let mut key_block: Box<[u8]> = vec![0x00u8; l as usize].into_boxed_slice(); + let nkey: (&mut [u8], &mut [u8]) = key_block.split_at_mut(0usize); + let ite: u32 = if key_len <= 64u32 { key_len } else { 32u32 }; + let zeroes: (&mut [u8], &mut [u8]) = nkey.1.split_at_mut(ite as usize); + lowstar::ignore::ignore::<&[u8]>(zeroes.1); + if key_len <= 64u32 { + (zeroes.0[0usize..key_len as usize]).copy_from_slice(&key[0usize..key_len as usize]) + } else { + crate::hash_blake2s::hash_with_key(zeroes.0, 32u32, key, key_len, &[], 0u32) + }; + let mut ipad: Box<[u8]> = vec![0x36u8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&ipad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut ipad)[i as usize] = xi ^ yi + } + let mut opad: Box<[u8]> = vec![0x5cu8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&opad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut opad)[i as usize] = xi ^ yi + } + let mut s: [u32; 16] = [0u32; 16usize]; + crate::hash_blake2s::init(&mut s, 0u32, 32u32); + let s0: &mut [u32] = &mut s; + if data_len == 0u32 { + let mut wv: [u32; 16] = [0u32; 16usize]; + crate::hash_blake2s::update_last(64u32, &mut wv, s0, false, 0u64, 64u32, &ipad) + } else { + let block_len: u32 = 64u32; + let n_blocks: u32 = data_len.wrapping_div(block_len); + let rem: u32 = data_len.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: data_len.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = data.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + let mut wv: [u32; 16] = [0u32; 16usize]; + crate::hash_blake2s::update_multi(64u32, &mut wv, s0, 0u64, &ipad, 1u32); + let mut wv0: [u32; 16] = [0u32; 16usize]; + crate::hash_blake2s::update_multi( + n_blocks0.wrapping_mul(64u32), + &mut wv0, + s0, + block_len as u64, + rem0.0, + n_blocks0, + ); + let mut wv1: [u32; 16] = [0u32; 16usize]; + crate::hash_blake2s::update_last( + rem_len, + &mut wv1, + s0, + false, + (64u32 as u64).wrapping_add(full_blocks_len as u64), + rem_len, + rem0.1, + ) + }; + let dst1: (&mut [u8], &mut [u8]) = ipad.split_at_mut(0usize); + crate::hash_blake2s::finish(32u32, dst1.1, s0); + let hash1: (&[u8], &[u8]) = dst1.1.split_at(0usize); + crate::hash_blake2s::init(s0, 0u32, 32u32); + let block_len: u32 = 64u32; + let n_blocks: u32 = 32u32.wrapping_div(block_len); + let rem: u32 = 32u32.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: 32u32.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = hash1.1.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + let mut wv: [u32; 16] = [0u32; 16usize]; + crate::hash_blake2s::update_multi(64u32, &mut wv, s0, 0u64, &opad, 1u32); + let mut wv0: [u32; 16] = [0u32; 16usize]; + crate::hash_blake2s::update_multi( + n_blocks0.wrapping_mul(64u32), + &mut wv0, + s0, + block_len as u64, + rem0.0, + n_blocks0, + ); + let mut wv1: [u32; 16] = [0u32; 16usize]; + crate::hash_blake2s::update_last( + rem_len, + &mut wv1, + s0, + false, + (64u32 as u64).wrapping_add(full_blocks_len as u64), + rem_len, + rem0.1, + ); + crate::hash_blake2s::finish(32u32, dst, s0) +} + +/** +Write the HMAC-BLAKE2b MAC of a message (`data`) by using a key (`key`) into `dst`. + +The key can be any length and will be hashed if it is longer and padded if it is shorter than 128 bytes. +`dst` must point to 64 bytes of memory. +*/ +pub fn compute_blake2b_32(dst: &mut [u8], key: &[u8], key_len: u32, data: &[u8], data_len: u32) { + let l: u32 = 128u32; + let mut key_block: Box<[u8]> = vec![0x00u8; l as usize].into_boxed_slice(); + let nkey: (&mut [u8], &mut [u8]) = key_block.split_at_mut(0usize); + let ite: u32 = if key_len <= 128u32 { key_len } else { 64u32 }; + let zeroes: (&mut [u8], &mut [u8]) = nkey.1.split_at_mut(ite as usize); + lowstar::ignore::ignore::<&[u8]>(zeroes.1); + if key_len <= 128u32 { + (zeroes.0[0usize..key_len as usize]).copy_from_slice(&key[0usize..key_len as usize]) + } else { + crate::hash_blake2b::hash_with_key(zeroes.0, 64u32, key, key_len, &[], 0u32) + }; + let mut ipad: Box<[u8]> = vec![0x36u8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&ipad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut ipad)[i as usize] = xi ^ yi + } + let mut opad: Box<[u8]> = vec![0x5cu8; l as usize].into_boxed_slice(); + for i in 0u32..l { + let xi: u8 = (&opad)[i as usize]; + let yi: u8 = (&key_block)[i as usize]; + (&mut opad)[i as usize] = xi ^ yi + } + let mut s: [u64; 16] = [0u64; 16usize]; + crate::hash_blake2b::init(&mut s, 0u32, 64u32); + let s0: &mut [u64] = &mut s; + if data_len == 0u32 { + let mut wv: [u64; 16] = [0u64; 16usize]; + crate::hash_blake2b::update_last( + 128u32, + &mut wv, + s0, + false, + fstar::uint128::uint64_to_uint128(0u64), + 128u32, + &ipad, + ) + } else { + let block_len: u32 = 128u32; + let n_blocks: u32 = data_len.wrapping_div(block_len); + let rem: u32 = data_len.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: data_len.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = data.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + let mut wv: [u64; 16] = [0u64; 16usize]; + crate::hash_blake2b::update_multi( + 128u32, + &mut wv, + s0, + fstar::uint128::uint64_to_uint128(0u64), + &ipad, + 1u32, + ); + let mut wv0: [u64; 16] = [0u64; 16usize]; + crate::hash_blake2b::update_multi( + n_blocks0.wrapping_mul(128u32), + &mut wv0, + s0, + fstar::uint128::uint64_to_uint128(block_len as u64), + rem0.0, + n_blocks0, + ); + let mut wv1: [u64; 16] = [0u64; 16usize]; + crate::hash_blake2b::update_last( + rem_len, + &mut wv1, + s0, + false, + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(128u32 as u64), + fstar::uint128::uint64_to_uint128(full_blocks_len as u64), + ), + rem_len, + rem0.1, + ) + }; + let dst1: (&mut [u8], &mut [u8]) = ipad.split_at_mut(0usize); + crate::hash_blake2b::finish(64u32, dst1.1, s0); + let hash1: (&[u8], &[u8]) = dst1.1.split_at(0usize); + crate::hash_blake2b::init(s0, 0u32, 64u32); + let block_len: u32 = 128u32; + let n_blocks: u32 = 64u32.wrapping_div(block_len); + let rem: u32 = 64u32.wrapping_rem(block_len); + let scrut: __uint32_t_uint32_t = if n_blocks > 0u32 && rem == 0u32 { + let n_blocks·: u32 = n_blocks.wrapping_sub(1u32); + __uint32_t_uint32_t { + fst: n_blocks·, + snd: 64u32.wrapping_sub(n_blocks·.wrapping_mul(block_len)), + } + } else { + __uint32_t_uint32_t { + fst: n_blocks, + snd: rem, + } + }; + let n_blocks0: u32 = scrut.fst; + let rem_len: u32 = scrut.snd; + let full_blocks_len: u32 = n_blocks0.wrapping_mul(block_len); + let full_blocks: (&[u8], &[u8]) = hash1.1.split_at(0usize); + let rem0: (&[u8], &[u8]) = full_blocks.1.split_at(full_blocks_len as usize); + let mut wv: [u64; 16] = [0u64; 16usize]; + crate::hash_blake2b::update_multi( + 128u32, + &mut wv, + s0, + fstar::uint128::uint64_to_uint128(0u64), + &opad, + 1u32, + ); + let mut wv0: [u64; 16] = [0u64; 16usize]; + crate::hash_blake2b::update_multi( + n_blocks0.wrapping_mul(128u32), + &mut wv0, + s0, + fstar::uint128::uint64_to_uint128(block_len as u64), + rem0.0, + n_blocks0, + ); + let mut wv1: [u64; 16] = [0u64; 16usize]; + crate::hash_blake2b::update_last( + rem_len, + &mut wv1, + s0, + false, + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(128u32 as u64), + fstar::uint128::uint64_to_uint128(full_blocks_len as u64), + ), + rem_len, + rem0.1, + ); + crate::hash_blake2b::finish(64u32, dst, s0) +} +*/ diff --git a/libcrux-hmac/src/hacl_hmac.rs b/libcrux-hmac/src/hacl_hmac.rs deleted file mode 100644 index 65136aa26..000000000 --- a/libcrux-hmac/src/hacl_hmac.rs +++ /dev/null @@ -1,30 +0,0 @@ -use libcrux_hacl::{ - Hacl_HMAC_compute_sha1, Hacl_HMAC_compute_sha2_256, Hacl_HMAC_compute_sha2_384, - Hacl_HMAC_compute_sha2_512, -}; - -macro_rules! impl_hmac { - ($name:ident,$fun:expr,$tag_len:literal) => { - /// Compute HMAC. - /// - /// Note that this function panics if `key` or `data` is larger than 2**32 bytes. - pub fn $name(key: &[u8], data: &[u8]) -> [u8; $tag_len] { - let mut dst = [0u8; $tag_len]; - unsafe { - $fun( - dst.as_mut_ptr(), - key.as_ptr() as _, - key.len().try_into().unwrap(), - data.as_ptr() as _, - data.len().try_into().unwrap(), - ) - } - dst - } - }; -} - -impl_hmac!(sha1, Hacl_HMAC_compute_sha1, 20); -impl_hmac!(sha2_256, Hacl_HMAC_compute_sha2_256, 32); -impl_hmac!(sha2_384, Hacl_HMAC_compute_sha2_384, 48); -impl_hmac!(sha2_512, Hacl_HMAC_compute_sha2_512, 64); diff --git a/libcrux-hmac/src/hmac.rs b/libcrux-hmac/src/hmac.rs index 3eea90a22..8d6f0262e 100644 --- a/libcrux-hmac/src/hmac.rs +++ b/libcrux-hmac/src/hmac.rs @@ -2,8 +2,19 @@ //! //! This crate implements HMAC on SHA 1 and SHA 2 (except for SHA 224). -use libcrux_hkdf as hkdf; -pub(crate) mod hacl_hmac; +//use libcrux_hkdf as hkdf; + +#[cfg(feature = "hacl")] +pub mod hacl { + pub mod hash_sha1; + pub mod hmac; +} + +#[cfg(feature = "hacl")] +mod impl_hacl; + +#[cfg(feature = "portable_hacl")] +pub use impl_hacl::*; /// The HMAC algorithm defining the used hash function. #[derive(Copy, Clone, Debug, PartialEq)] @@ -16,6 +27,7 @@ pub enum Algorithm { Sha512, } +/* impl From for Algorithm { fn from(value: hkdf::Algorithm) -> Self { match value { @@ -25,6 +37,7 @@ impl From for Algorithm { } } } +*/ /// Get the tag size for a given algorithm. pub const fn tag_size(alg: Algorithm) -> usize { @@ -39,6 +52,7 @@ pub const fn tag_size(alg: Algorithm) -> usize { /// Compute the HMAC value with the given `alg` and `key` on `data` with an /// output tag length of `tag_length`. /// Returns a vector of length `tag_length`. +/// Panics if either `key` or `data` are longer than `u32::MAX`. pub fn hmac(alg: Algorithm, key: &[u8], data: &[u8], tag_length: Option) -> Vec { let native_tag_length = tag_size(alg); let tag_length = match tag_length { @@ -46,11 +60,17 @@ pub fn hmac(alg: Algorithm, key: &[u8], data: &[u8], tag_length: Option) None => native_tag_length, }; let mut dst: Vec<_> = match alg { - Algorithm::Sha1 => crate::hacl_hmac::sha1(key, data).into(), - Algorithm::Sha256 => crate::hacl_hmac::sha2_256(key, data).into(), - Algorithm::Sha384 => crate::hacl_hmac::sha2_384(key, data).into(), - Algorithm::Sha512 => crate::hacl_hmac::sha2_512(key, data).into(), + Algorithm::Sha1 => wrap_bufalloc(|buf| hmac_sha1(buf, key, data)), + Algorithm::Sha256 => wrap_bufalloc(|buf| hmac_sha2_256(buf, key, data)), + Algorithm::Sha384 => wrap_bufalloc(|buf| hmac_sha2_384(buf, key, data)), + Algorithm::Sha512 => wrap_bufalloc(|buf| hmac_sha2_512(buf, key, data)), }; dst.truncate(tag_length); dst } + +fn wrap_bufalloc(f: F) -> Vec { + let mut buf = [0u8; N]; + f(&mut buf); + buf.to_vec() +} diff --git a/libcrux-hmac/src/impl_hacl.rs b/libcrux-hmac/src/impl_hacl.rs new file mode 100644 index 000000000..a5d90d31a --- /dev/null +++ b/libcrux-hmac/src/impl_hacl.rs @@ -0,0 +1,22 @@ +macro_rules! impl_hmac { + ($name:ident,$fun:path,$tag_len:literal) => { + /// Compute HMAC. + /// + /// Note that this function panics if `key` or `data` is larger than 2**32 bytes. + /// This ensures that all values are in the range valid to be consumed by hacl-rs. + pub fn $name(dst: &mut [u8; $tag_len], key: &[u8], data: &[u8]) { + $fun( + dst, + key, + key.len().try_into().unwrap(), + data, + data.len().try_into().unwrap(), + ) + } + }; +} + +impl_hmac!(hmac_sha1, crate::hacl::hmac::compute_sha1, 20); +impl_hmac!(hmac_sha2_256, crate::hacl::hmac::compute_sha2_256, 32); +impl_hmac!(hmac_sha2_384, crate::hacl::hmac::compute_sha2_384, 48); +impl_hmac!(hmac_sha2_512, crate::hacl::hmac::compute_sha2_512, 64); diff --git a/libcrux-intrinsics/Cargo.toml b/libcrux-intrinsics/Cargo.toml index 5cacc5bee..f0126871a 100644 --- a/libcrux-intrinsics/Cargo.toml +++ b/libcrux-intrinsics/Cargo.toml @@ -11,7 +11,7 @@ description = "Libcrux intrinsics crate" exclude = ["/proofs"] [dependencies] -hax-lib.workspace = true +hax-lib = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax/" } [features] simd128 = [] diff --git a/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Arm64_extract.fsti b/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Arm64_extract.fsti index d4014e6a8..a03c287ec 100644 --- a/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Arm64_extract.fsti +++ b/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Arm64_extract.fsti @@ -1,5 +1,5 @@ module Libcrux_intrinsics.Arm64_extract -#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" open Core open FStar.Mul diff --git a/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2_extract.fst b/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2_extract.fst deleted file mode 100644 index 167d0b324..000000000 --- a/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2_extract.fst +++ /dev/null @@ -1,1214 +0,0 @@ -module Libcrux_intrinsics.Avx2_extract -#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" -open Core -open FStar.Mul - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 3091; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 3091; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 3091; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 3091; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm256_and_si256"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 3580; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 3580; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 3580; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 3580; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm256_castsi128_si256"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 3681; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 3681; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 3681; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 3681; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm256_extracti128_si256"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 2293; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 2293; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 2293; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 2293; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm256_madd_epi16"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 2613; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 2613; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 2613; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 2613; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm256_mullo_epi16"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 3439; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 3439; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 3439; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 3439; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm256_slli_epi16"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 3378; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 3378; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 3378; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 3378; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm256_srli_epi16"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 3719; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 3719; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 3719; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 3719; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm_movemask_epi8"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 3630; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 3630; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 3630; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 3630; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm_packs_epi16"); disambiguator = 0 - } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (TransformHaxLibInline) Fatal error: something we considered as impossible occurred! Please report this by submitting an issue on GitHub! -Details: Malformed `Quote` item: `quote_of_expr` failed. Expression was: -{ Ast.Make.e = - Ast.Make.App { - f = - { Ast.Make.e = - (Ast.Make.GlobalVar - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "failure"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value })); - span = - { Span.id = 1423; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - (Ast.Make.TArrow ([Ast.Make.TStr; Ast.Make.TStr], - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - )) - }; - args = - [{ Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "(AST import) Fatal error: something we considered as impossible occurred! \027[1mPlease report this by submitting an issue on GitHub!\027[0m\nDetails: [import_thir:literal] got an error literal: this means the Rust compiler or Hax's frontend probably reported errors above.")); - span = - { Span.id = 1423; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr }; - { Ast.Make.e = - (Ast.Make.Literal - (Ast.String - "{ Types.attributes = [];\n contents =\n Types.Literal {\n lit =\n { Types.node =\n (Types.Err Types.ErrorGuaranteed {todo = \"ErrorGuaranteed(())\"});\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/lib.rs\"));\n hi = { Types.col = \"0\"; line = \"1\" };\n lo = { Types.col = \"0\"; line = \"1\" } }\n };\n neg = false};\n hir_id = None;\n span =\n { Types.filename =\n (Types.Real (Types.LocalPath \"libcrux-intrinsics/src/avx2_extract.rs\"));\n hi = { Types.col = \"14\"; line = \"50\" };\n lo = { Types.col = \"12\"; line = \"39\" } };\n ty = Types.Never }")); - span = - { Span.id = 1423; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath - "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = Ast.Make.TStr } - ]; - generic_args = []; bounds_impls = []; trait = None}; - span = - { Span.id = 1423; - data = - [{ Span.Imported.filename = - (Span.Imported.Real - (Span.Imported.LocalPath "libcrux-intrinsics/src/avx2_extract.rs")); - hi = { Span.Imported.col = 14; line = 50 }; - lo = { Span.Imported.col = 12; line = 39 } } - ] - }; - typ = - Ast.Make.TApp { - ident = - `Concrete ({ Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "rust_primitives"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "hax"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "Never"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Type }); - args = []} - } - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_intrinsics"; - path = - [{ Concrete_ident.Imported.data = - (Concrete_ident.Imported.TypeNs "avx2_extract"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "mm_storeu_bytes_si128"); - disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) diff --git a/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2_extract.fsti b/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2_extract.fsti index 16d93fb14..290b679a5 100644 --- a/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2_extract.fsti +++ b/libcrux-intrinsics/proofs/fstar/extraction/Libcrux_intrinsics.Avx2_extract.fsti @@ -1,5 +1,5 @@ module Libcrux_intrinsics.Avx2_extract -#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" open Core open FStar.Mul diff --git a/libcrux-intrinsics/proofs/fstar/extraction/Makefile b/libcrux-intrinsics/proofs/fstar/extraction/Makefile deleted file mode 100644 index b4ce70a38..000000000 --- a/libcrux-intrinsics/proofs/fstar/extraction/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.base diff --git a/libcrux-intrinsics/src/avx2.rs b/libcrux-intrinsics/src/avx2.rs index 0ee9467e8..da3dacfaf 100644 --- a/libcrux-intrinsics/src/avx2.rs +++ b/libcrux-intrinsics/src/avx2.rs @@ -549,8 +549,8 @@ pub fn mm256_set_epi64x(input3: i64, input2: i64, input1: i64, input0: i64) -> V } #[inline(always)] -pub fn mm256_unpacklo_epi64(a: Vec256, b: Vec256) -> Vec256 { - unsafe { _mm256_unpacklo_epi64(a, b) } +pub fn mm256_unpacklo_epi64(lhs: Vec256, rhs: Vec256) -> Vec256 { + unsafe { _mm256_unpacklo_epi64(lhs, rhs) } } #[inline(always)] diff --git a/libcrux-intrinsics/src/avx2_extract.rs b/libcrux-intrinsics/src/avx2_extract.rs index ce78d81e5..7954efeb1 100644 --- a/libcrux-intrinsics/src/avx2_extract.rs +++ b/libcrux-intrinsics/src/avx2_extract.rs @@ -33,63 +33,81 @@ pub type Vec256 = u8; pub type Vec128 = u8; pub type Vec256Float = u8; +#[inline(always)] pub fn mm256_storeu_si256_u8(output: &mut [u8], vector: Vec256) { debug_assert_eq!(output.len(), 32); unimplemented!() } #[hax_lib::ensures(|()| future(output).len() == output.len())] +#[inline(always)] pub fn mm256_storeu_si256_i16(output: &mut [i16], vector: Vec256) { debug_assert_eq!(output.len(), 16); unimplemented!() } + +#[inline(always)] pub fn mm256_storeu_si256_i32(output: &mut [i32], vector: Vec256) { debug_assert_eq!(output.len(), 8); unimplemented!() } +#[inline(always)] pub fn mm_storeu_si128(output: &mut [i16], vector: Vec128) { debug_assert!(output.len() >= 8); unimplemented!() } + +#[inline(always)] pub fn mm_storeu_si128_i32(output: &mut [i32], vector: Vec128) { debug_assert_eq!(output.len(), 4); unimplemented!() } #[hax_lib::fstar::replace(interface, "include BitVec.Intrinsics {mm_storeu_bytes_si128}")] +#[inline(always)] pub fn mm_storeu_bytes_si128(output: &mut [u8], vector: Vec128) { debug_assert_eq!(output.len(), 16); unimplemented!() } #[hax_lib::fstar::replace(interface, "include BitVec.Intrinsics {mm_loadu_si128}")] +#[inline(always)] pub fn mm_loadu_si128(input: &[u8]) -> Vec128 { debug_assert_eq!(input.len(), 16); unimplemented!() } +#[inline(always)] pub fn mm256_loadu_si256_u8(input: &[u8]) -> Vec256 { debug_assert_eq!(input.len(), 32); unimplemented!() } + +#[inline(always)] pub fn mm256_loadu_si256_i16(input: &[i16]) -> Vec256 { debug_assert_eq!(input.len(), 16); unimplemented!() } + +#[inline(always)] pub fn mm256_loadu_si256_i32(input: &[i32]) -> Vec256 { debug_assert_eq!(input.len(), 8); unimplemented!() } +#[inline(always)] pub fn mm256_setzero_si256() -> Vec256 { unimplemented!() } + +#[inline(always)] pub fn mm256_set_m128i(hi: Vec128, lo: Vec128) -> Vec256 { unimplemented!() } #[hax_lib::fstar::replace(interface, "include BitVec.Intrinsics {mm_set_epi8}")] +#[inline(always)] pub fn mm_set_epi8( byte15: u8, byte14: u8, @@ -112,6 +130,7 @@ pub fn mm_set_epi8( } #[hax_lib::fstar::replace(interface, "include BitVec.Intrinsics {mm256_set_epi8}")] +#[inline(always)] pub fn mm256_set_epi8( byte31: i8, byte30: i8, @@ -162,6 +181,7 @@ val lemma_mm256_set1_epi16 constant [SMTPat (vec256_as_i16x16 (mm256_set1_epi16 constant))] "# )] +#[inline(always)] pub fn mm256_set1_epi16(constant: i16) -> Vec256 { unimplemented!() } @@ -231,25 +251,30 @@ pub fn mm256_set_epi32( #[hax_lib::ensures(|result| fstar!("vec128_as_i16x8 $result == Spec.Utils.map2 (+.) (vec128_as_i16x8 $lhs) (vec128_as_i16x8 $rhs)"))] +#[inline(always)] pub fn mm_add_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { unimplemented!() } #[hax_lib::ensures(|result| fstar!("vec128_as_i16x8 $result == Spec.Utils.map2 (-.) (vec128_as_i16x8 $lhs) (vec128_as_i16x8 $rhs)"))] +#[inline(always)] pub fn mm_sub_epi16(lhs: Vec128, rhs: Vec128) -> Vec128 { unimplemented!() } #[hax_lib::ensures(|result| fstar!("vec256_as_i16x16 $result == Spec.Utils.map2 (+.) (vec256_as_i16x16 $lhs) (vec256_as_i16x16 $rhs)"))] +#[inline(always)] pub fn mm256_add_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { unimplemented!() } + #[hax_lib::fstar::replace( interface, "include BitVec.Intrinsics {mm256_madd_epi16 as ${mm256_madd_epi16}}" )] +#[inline(always)] pub fn mm256_madd_epi16(lhs: Vec256, rhs: Vec256) -> Vec256 { unimplemented!() } @@ -538,9 +563,11 @@ pub fn mm256_permutevar8x32_epi32(vector: Vec256, control: Vec256) -> Vec256 { unimplemented!() } +#[inline(always)] pub fn mm256_srlv_epi32(vector: Vec256, counts: Vec256) -> Vec256 { unimplemented!() } + #[inline(always)] pub fn mm256_srlv_epi64(vector: Vec256, counts: Vec256) -> Vec256 { unimplemented!() diff --git a/libcrux-kem/Cargo.toml b/libcrux-kem/Cargo.toml index 1547958b1..8e8cdfaa6 100644 --- a/libcrux-kem/Cargo.toml +++ b/libcrux-kem/Cargo.toml @@ -14,9 +14,9 @@ exclude = ["/tests"] path = "src/kem.rs" [dependencies] -libcrux-ml-kem = { version = "0.0.2-beta.2", path = "../libcrux-ml-kem" } -libcrux-sha3 = { version = "0.0.2-beta.2", path = "../libcrux-sha3" } -libcrux-ecdh = { version = "0.0.2-beta.2", path = "../libcrux-ecdh" } +libcrux-ml-kem = { version = "=0.0.2-beta.2", path = "../libcrux-ml-kem" } +libcrux-sha3 = { version = "=0.0.2-beta.2", path = "../libcrux-sha3" } +libcrux-ecdh = { version = "=0.0.2-beta.2", path = "../libcrux-ecdh" } rand = { version = "0.8" } [features] diff --git a/libcrux-kem/src/kem.rs b/libcrux-kem/src/kem.rs index b8874ffba..7ad465ce4 100644 --- a/libcrux-kem/src/kem.rs +++ b/libcrux-kem/src/kem.rs @@ -33,9 +33,11 @@ use rand::{CryptoRng, Rng}; -use libcrux_ecdh; use libcrux_ecdh::{p256_derive, x25519_derive}; -use libcrux_ecdh::{P256PrivateKey, P256PublicKey, X25519PrivateKey, X25519PublicKey}; +use libcrux_ecdh::{ + P256PrivateKey, P256PublicKey, P256SharedSecret, X25519PrivateKey, X25519PublicKey, + X25519SharedSecret, +}; use libcrux_sha3 as sha3; use libcrux_ml_kem::{mlkem1024, mlkem512, mlkem768}; @@ -370,8 +372,8 @@ impl Ct { Ok(Ss::XWingKemDraft02( ss_m, ss_x, - X25519PublicKey(ct_x.0.clone()), - X25519PublicKey(pk_x.0.clone()), + X25519PublicKey(ct_x.0), + X25519PublicKey(pk_x.0), )) } Ct::MlKem1024(ct) => { @@ -430,25 +432,25 @@ impl Ct { /// A KEM shared secret pub enum Ss { - X25519(X25519PublicKey), - P256(P256PublicKey), + X25519(X25519SharedSecret), + P256(P256SharedSecret), MlKem512(MlKemSharedSecret), MlKem768(MlKemSharedSecret), - X25519MlKem768Draft00(MlKemSharedSecret, X25519PublicKey), + X25519MlKem768Draft00(MlKemSharedSecret, X25519SharedSecret), XWingKemDraft02( - MlKemSharedSecret, // ss_M - X25519PublicKey, // ss_X - X25519PublicKey, // ct_X - X25519PublicKey, // pk_X + MlKemSharedSecret, // ss_M + X25519SharedSecret, // ss_X + X25519PublicKey, // ct_X + X25519PublicKey, // pk_X ), #[cfg(feature = "kyber")] X25519Kyber768Draft00(MlKemSharedSecret, X25519PublicKey), #[cfg(feature = "kyber")] XWingKyberDraft02( - MlKemSharedSecret, // ss_M - X25519PublicKey, // ss_X - X25519PublicKey, // ct_X - X25519PublicKey, // pk_X + MlKemSharedSecret, // ss_M + X25519SharedSecret, // ss_X + X25519PublicKey, // ct_X + X25519PublicKey, // pk_X ), MlKem1024(MlKemSharedSecret), } diff --git a/libcrux-ml-dsa/Cargo.toml b/libcrux-ml-dsa/Cargo.toml index 9c1d52fea..63ab2a72b 100644 --- a/libcrux-ml-dsa/Cargo.toml +++ b/libcrux-ml-dsa/Cargo.toml @@ -19,6 +19,7 @@ bench = false # so libtest doesn't eat the arguments to criterion libcrux-sha3 = { version = "0.0.2-beta.2", path = "../libcrux-sha3" } libcrux-intrinsics = { version = "0.0.2-beta.2", path = "../libcrux-intrinsics" } libcrux-platform = { version = "0.0.2-beta.2", path = "../sys/platform" } +hax-lib = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax/" } [dev-dependencies] rand = { version = "0.8" } @@ -29,8 +30,8 @@ criterion = "0.5" pqcrypto-dilithium = { version = "0.5.0" } #, default-features = false [features] -simd128 = [] -simd256 = [] +simd128 = ["libcrux-sha3/simd128", "libcrux-intrinsics/simd128"] +simd256 = ["libcrux-sha3/simd256", "libcrux-intrinsics/simd256"] acvp = [] # expose internal API for ACVP testing [[bench]] @@ -48,3 +49,8 @@ harness = false [[bench]] name = "ml-dsa" harness = false + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = [ + 'cfg(hax)', +] } diff --git a/libcrux-ml-dsa/hax.py b/libcrux-ml-dsa/hax.py new file mode 100755 index 000000000..e8d2ba309 --- /dev/null +++ b/libcrux-ml-dsa/hax.py @@ -0,0 +1,172 @@ +#! /usr/bin/env python3 + +import os +import argparse +import subprocess +import sys + + +def shell(command, expect=0, cwd=None, env={}): + subprocess_stdout = subprocess.DEVNULL + + print("Env:", env) + print("Command: ", end="") + for i, word in enumerate(command): + if i == 4: + print("'{}' ".format(word), end="") + else: + print("{} ".format(word), end="") + + print("\nDirectory: {}".format(cwd)) + + os_env = os.environ + os_env.update(env) + + ret = subprocess.run(command, cwd=cwd, env=os_env) + if ret.returncode != expect: + raise Exception("Error {}. Expected {}.".format(ret, expect)) + + +class extractAction(argparse.Action): + + def __call__(self, parser, args, values, option_string=None) -> None: + # Extract platform interfaces + include_str = "+:** -**::x86::init::cpuid -**::x86::init::cpuid_count" + interface_include = "+**" + cargo_hax_into = [ + "cargo", + "hax", + "into", + "-i", + include_str, + "fstar", + "--z3rlimit", + "80", + "--interfaces", + interface_include, + ] + hax_env = {} + shell( + cargo_hax_into, + cwd="../sys/platform", + env=hax_env, + ) + + # Extract intrinsics interfaces + include_str = "+:**" + interface_include = "+**" + cargo_hax_into = [ + "cargo", + "hax", + "-C", + "--features", + "simd128,simd256", + ";", + "into", + "-i", + include_str, + "fstar", + "--z3rlimit", + "80", + "--interfaces", + interface_include, + ] + hax_env = {} + shell( + cargo_hax_into, + cwd="../libcrux-intrinsics", + env=hax_env, + ) + + # Extract ml-dsa + includes = [ + "+**", + "-libcrux_ml_dsa::hash_functions::portable::*", + "-libcrux_ml_dsa::hash_functions::simd256::*", + "-libcrux_ml_dsa::hash_functions::neon::*", + "+:libcrux_ml_dsa::hash_functions::*::*", + ] + include_str = " ".join(includes) + interface_include = "+**" + cargo_hax_into = [ + "cargo", + "hax", + "-C", + "--features", + "simd128,simd256", + ";", + "into", + "-i", + include_str, + "fstar", + "--z3rlimit", + "100", + "--interfaces", + interface_include, + ] + hax_env = {} + shell( + cargo_hax_into, + cwd=".", + env=hax_env, + ) + return None + + +class proveAction(argparse.Action): + + def __call__(self, parser, args, values, option_string=None) -> None: + admit_env = {} + if args.admit: + admit_env = {"OTHERFLAGS": "--admit_smt_queries true"} + shell(["make", "-C", "proofs/fstar/extraction/"], env=admit_env) + return None + + +def parse_arguments(): + parser = argparse.ArgumentParser( + description="Libcrux prove script. " + + "Make sure to separate sub-command arguments with --." + ) + subparsers = parser.add_subparsers() + + extract_parser = subparsers.add_parser( + "extract", help="Extract the F* code for the proofs." + ) + extract_parser.add_argument("extract", nargs="*", action=extractAction) + + prover_parser = subparsers.add_parser( + "prove", + help=""" + Run F*. + + This typechecks the extracted code. + To lax-typecheck use --admit. + """, + ) + prover_parser.add_argument( + "--admit", + help="Admit all smt queries to lax typecheck.", + action="store_true", + ) + prover_parser.add_argument( + "prove", + nargs="*", + action=proveAction, + ) + + if len(sys.argv) == 1: + parser.print_help(sys.stderr) + sys.exit(1) + + return parser.parse_args() + + +def main(): + # Don't print unnecessary Python stack traces. + sys.tracebacklimit = 0 + parse_arguments() + + +if __name__ == "__main__": + main() diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Arithmetic.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Arithmetic.fst new file mode 100644 index 000000000..787aefa44 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Arithmetic.fst @@ -0,0 +1,544 @@ +module Libcrux_ml_dsa.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let decompose_vector + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (v_GAMMA2: i32) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (t: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + = + let vector_low:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let vector_high:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let vector_high, vector_low:(t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_DIMENSION + (fun temp_0_ temp_1_ -> + let vector_high, vector_low:(t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (vector_high, vector_low + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION)) + (fun temp_0_ i -> + let vector_high, vector_low:(t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) = + temp_0_ + in + let i:usize = i in + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit + ((vector_low.[ sz 0 ]).Libcrux_ml_dsa.Polynomial.f_simd_units <: t_Slice v_SIMDUnit) + <: + usize) + (fun temp_0_ temp_1_ -> + let vector_high, vector_low:(t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + ) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (vector_high, vector_low + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION)) + (fun temp_0_ j -> + let vector_high, vector_low:(t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + ) = + temp_0_ + in + let j:usize = j in + let low, high:(v_SIMDUnit & v_SIMDUnit) = + Libcrux_ml_dsa.Simd.Traits.f_decompose #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + v_GAMMA2 + ((t.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units.[ j ] + <: + v_SIMDUnit) + in + let vector_low:t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize vector_low + i + ({ + (vector_low.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (vector_low.[ i + ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units + j + low + <: + t_Array v_SIMDUnit (sz 32) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let vector_high:t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize vector_high + i + ({ + (vector_high.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (vector_high.[ i + ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units + j + high + <: + t_Array v_SIMDUnit (sz 32) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + vector_high, vector_low + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + )) + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION)) + in + vector_low, vector_high + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + +let power2round_vector + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (t: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + = + let t0:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let t1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let t0, t1:(t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) = + Rust_primitives.Hax.Folds.fold_enumerated_slice (t + <: + t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (fun temp_0_ temp_1_ -> + let t0, t1:(t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (t0, t1 + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION)) + (fun temp_0_ temp_1_ -> + let t0, t1:(t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) = + temp_0_ + in + let i, ring_element:(usize & Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + temp_1_ + in + Rust_primitives.Hax.Folds.fold_enumerated_slice (ring_element + .Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun temp_0_ temp_1_ -> + let t0, t1:(t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + ) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (t0, t1 + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION)) + (fun temp_0_ temp_1_ -> + let t0, t1:(t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + ) = + temp_0_ + in + let j, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + let t0_unit, t1_unit:(v_SIMDUnit & v_SIMDUnit) = + Libcrux_ml_dsa.Simd.Traits.f_power2round #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + simd_unit + in + let t0:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize t0 + i + ({ + (t0.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (t0.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units + j + t0_unit + <: + t_Array v_SIMDUnit (sz 32) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let t1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize t1 + i + ({ + (t1.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (t1.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units + j + t1_unit + <: + t_Array v_SIMDUnit (sz 32) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + t0, t1 + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + )) + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION)) + in + t0, t1 + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + +let shift_left_then_reduce + (#v_SIMDUnit: Type0) + (v_SHIFT_BY: i32) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + let out:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + in + let out:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun out temp_1_ -> + let out:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = out in + let _:usize = temp_1_ in + true) + out + (fun out temp_1_ -> + let out:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = out in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + { + out with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_dsa.Polynomial.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_shift_left_then_reduce #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + v_SHIFT_BY + simd_unit + <: + v_SIMDUnit) + <: + t_Array v_SIMDUnit (sz 32) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + out + +let use_hint + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (v_GAMMA2: i32) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (hint: t_Array (t_Array i32 (sz 256)) v_DIMENSION) + (re_vector: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + = + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_DIMENSION + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let _:usize = temp_1_ in + true) + result + (fun result i -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let i:usize = i in + let hint_simd:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (hint.[ i ] <: t_Slice i32) + in + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit + ((result.[ sz 0 ]).Libcrux_ml_dsa.Polynomial.f_simd_units <: t_Slice v_SIMDUnit) + <: + usize) + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let _:usize = temp_1_ in + true) + result + (fun result j -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let j:usize = j in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + ({ + (result.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (result.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units + j + (Libcrux_ml_dsa.Simd.Traits.f_use_hint #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + v_GAMMA2 + ((re_vector.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units.[ j ] + <: + v_SIMDUnit) + (hint_simd.Libcrux_ml_dsa.Polynomial.f_simd_units.[ j ] <: v_SIMDUnit) + <: + v_SIMDUnit) + <: + t_Array v_SIMDUnit (sz 32) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION)) + in + result + +let vector_infinity_norm_exceeds + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (vector: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + (bound: i32) + = + let exceeds:bool = false in + let exceeds:bool = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Iter + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__iter #(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (vector <: t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + exceeds + (fun exceeds ring_element -> + let exceeds:bool = exceeds in + let ring_element:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + ring_element + in + exceeds || + (Libcrux_ml_dsa.Polynomial.impl__infinity_norm_exceeds #v_SIMDUnit ring_element bound + <: + bool)) + in + exceeds + +let make_hint + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (v_GAMMA2: i32) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (low high: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + = + let hint:t_Array (t_Array i32 (sz 256)) v_DIMENSION = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0l (sz 256) <: t_Array i32 (sz 256)) + v_DIMENSION + in + let true_hints:usize = sz 0 in + let hint, true_hints:(t_Array (t_Array i32 (sz 256)) v_DIMENSION & usize) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_DIMENSION + (fun temp_0_ temp_1_ -> + let hint, true_hints:(t_Array (t_Array i32 (sz 256)) v_DIMENSION & usize) = temp_0_ in + let _:usize = temp_1_ in + true) + (hint, true_hints <: (t_Array (t_Array i32 (sz 256)) v_DIMENSION & usize)) + (fun temp_0_ i -> + let hint, true_hints:(t_Array (t_Array i32 (sz 256)) v_DIMENSION & usize) = temp_0_ in + let i:usize = i in + let hint_simd:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + in + let hint_simd, true_hints:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + usize) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit + (hint_simd.Libcrux_ml_dsa.Polynomial.f_simd_units <: t_Slice v_SIMDUnit) + <: + usize) + (fun temp_0_ temp_1_ -> + let hint_simd, true_hints:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + usize) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (hint_simd, true_hints + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & usize)) + (fun temp_0_ j -> + let hint_simd, true_hints:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + usize) = + temp_0_ + in + let j:usize = j in + let one_hints_count, current_hint:(usize & v_SIMDUnit) = + Libcrux_ml_dsa.Simd.Traits.f_compute_hint #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + v_GAMMA2 + ((low.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units.[ j ] + <: + v_SIMDUnit) + ((high.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + .Libcrux_ml_dsa.Polynomial.f_simd_units.[ j ] + <: + v_SIMDUnit) + in + let hint_simd:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + { + hint_simd with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize hint_simd + .Libcrux_ml_dsa.Polynomial.f_simd_units + j + current_hint + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit + in + let true_hints:usize = true_hints +! one_hints_count in + hint_simd, true_hints + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & usize)) + in + let hint:t_Array (t_Array i32 (sz 256)) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize hint + i + (Libcrux_ml_dsa.Polynomial.impl__to_i32_array #v_SIMDUnit hint_simd + <: + t_Array i32 (sz 256)) + in + hint, true_hints <: (t_Array (t_Array i32 (sz 256)) v_DIMENSION & usize)) + in + hint, true_hints <: (t_Array (t_Array i32 (sz 256)) v_DIMENSION & usize) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Arithmetic.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Arithmetic.fsti new file mode 100644 index 000000000..aa749b797 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Arithmetic.fsti @@ -0,0 +1,73 @@ +module Libcrux_ml_dsa.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +val decompose_vector + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (v_GAMMA2: i32) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (t: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val power2round_vector + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (t: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val shift_left_then_reduce + (#v_SIMDUnit: Type0) + (v_SHIFT_BY: i32) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val use_hint + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (v_GAMMA2: i32) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (hint: t_Array (t_Array i32 (sz 256)) v_DIMENSION) + (re_vector: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION + ) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val vector_infinity_norm_exceeds + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (vector: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + (bound: i32) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + +val make_hint + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (v_GAMMA2: i32) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (low high: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + : Prims.Pure (t_Array (t_Array i32 (sz 256)) v_DIMENSION & usize) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Constants.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Constants.fsti new file mode 100644 index 000000000..6263c2610 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Constants.fsti @@ -0,0 +1,44 @@ +module Libcrux_ml_dsa.Constants +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let v_BITS_IN_LOWER_PART_OF_T: usize = sz 13 + +let v_BYTES_FOR_VERIFICATION_KEY_HASH: usize = sz 64 + +let v_COEFFICIENTS_IN_RING_ELEMENT: usize = sz 256 + +/// The length of `context` is serialized to a single `u8`. +let v_CONTEXT_MAX_LEN: usize = sz 255 + +let v_FIELD_MODULUS: i32 = 8380417l + +let v_FIELD_MODULUS_MINUS_ONE_BIT_LENGTH: usize = sz 23 + +let v_BITS_IN_UPPER_PART_OF_T: usize = + v_FIELD_MODULUS_MINUS_ONE_BIT_LENGTH -! v_BITS_IN_LOWER_PART_OF_T + +/// Number of bytes of entropy required for key generation. +let v_KEY_GENERATION_RANDOMNESS_SIZE: usize = sz 32 + +let v_MASK_SEED_SIZE: usize = sz 64 + +let v_MESSAGE_REPRESENTATIVE_SIZE: usize = sz 64 + +let v_REJECTION_SAMPLE_BOUND_SIGN: usize = sz 814 + +let v_RING_ELEMENT_OF_T0S_SIZE: usize = + (v_BITS_IN_LOWER_PART_OF_T *! v_COEFFICIENTS_IN_RING_ELEMENT <: usize) /! sz 8 + +let v_RING_ELEMENT_OF_T1S_SIZE: usize = + (v_BITS_IN_UPPER_PART_OF_T *! v_COEFFICIENTS_IN_RING_ELEMENT <: usize) /! sz 8 + +let v_SEED_FOR_A_SIZE: usize = sz 32 + +let v_SEED_FOR_ERROR_VECTORS_SIZE: usize = sz 64 + +let v_SEED_FOR_SIGNING_SIZE: usize = sz 32 + +/// Number of bytes of entropy required for signing. +let v_SIGNING_RANDOMNESS_SIZE: usize = sz 32 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Commitment.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Commitment.fst new file mode 100644 index 000000000..8634dfbe9 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Commitment.fst @@ -0,0 +1,170 @@ +module Libcrux_ml_dsa.Encoding.Commitment +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let serialize + (#v_SIMDUnit: Type0) + (v_OUTPUT_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + let serialized:t_Array u8 v_OUTPUT_SIZE = Rust_primitives.Hax.repeat 0uy v_OUTPUT_SIZE in + match cast (v_OUTPUT_SIZE <: usize) <: u8 with + | 128uy -> + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Simd.Traits.f_commitment_serialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (sz 4) + simd_unit + <: + t_Slice u8) + <: + t_Slice u8) + <: + t_Array u8 v_OUTPUT_SIZE) + in + serialized + | 192uy -> + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start + = + i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Simd.Traits.f_commitment_serialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (sz 6) + simd_unit + <: + t_Slice u8) + <: + t_Slice u8) + <: + t_Array u8 v_OUTPUT_SIZE) + in + serialized + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let serialize_vector + (#v_SIMDUnit: Type0) + (v_DIMENSION v_RING_ELEMENT_SIZE v_OUTPUT_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (vector: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + = + let serialized:t_Array u8 v_OUTPUT_SIZE = Rust_primitives.Hax.repeat 0uy v_OUTPUT_SIZE in + let (offset: usize):usize = sz 0 in + let offset, serialized:(usize & t_Array u8 v_OUTPUT_SIZE) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Iter + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__iter #(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (vector <: t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (offset, serialized <: (usize & t_Array u8 v_OUTPUT_SIZE)) + (fun temp_0_ ring_element -> + let offset, serialized:(usize & t_Array u8 v_OUTPUT_SIZE) = temp_0_ in + let ring_element:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + ring_element + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (serialize #v_SIMDUnit v_RING_ELEMENT_SIZE ring_element <: t_Slice u8) + <: + t_Slice u8) + in + let offset:usize = offset +! v_RING_ELEMENT_SIZE in + offset, serialized <: (usize & t_Array u8 v_OUTPUT_SIZE)) + in + serialized diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Commitment.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Commitment.fsti new file mode 100644 index 000000000..0becaf037 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Commitment.fsti @@ -0,0 +1,28 @@ +module Libcrux_ml_dsa.Encoding.Commitment +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let serialize__OUTPUT_BYTES_PER_SIMD_UNIT: usize = sz 4 + +let serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1: usize = sz 6 + +val serialize + (#v_SIMDUnit: Type0) + (v_OUTPUT_SIZE: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_vector + (#v_SIMDUnit: Type0) + (v_DIMENSION v_RING_ELEMENT_SIZE v_OUTPUT_SIZE: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (vector: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Error.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Error.fst new file mode 100644 index 000000000..84a413aa5 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Error.fst @@ -0,0 +1,243 @@ +module Libcrux_ml_dsa.Encoding.Error +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let deserialize + (#v_SIMDUnit: Type0) + (v_ETA: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Slice u8) + = + let serialized_chunks:Core.Slice.Iter.t_Chunks u8 = + match cast (v_ETA <: usize) <: u8 with + | 2uy -> Core.Slice.impl__chunks #u8 serialized (sz 3) + | 4uy -> Core.Slice.impl__chunks #u8 serialized (sz 4) + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + in + let result:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + in + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit + (result.Libcrux_ml_dsa.Polynomial.f_simd_units <: t_Slice v_SIMDUnit) + <: + usize) + (fun temp_0_ temp_1_ -> + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (result, serialized_chunks + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & Core.Slice.Iter.t_Chunks u8) + ) + (fun temp_0_ i -> + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + temp_0_ + in + let i:usize = i in + let tmp0, out:(Core.Slice.Iter.t_Chunks u8 & Core.Option.t_Option (t_Slice u8)) = + Core.Iter.Traits.Iterator.f_next #(Core.Slice.Iter.t_Chunks u8) + #FStar.Tactics.Typeclasses.solve + serialized_chunks + in + let serialized_chunks:Core.Slice.Iter.t_Chunks u8 = tmp0 in + ({ + result with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_dsa.Polynomial.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_error_deserialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + v_ETA + (Core.Option.impl__unwrap #(t_Slice u8) out <: t_Slice u8) + <: + v_SIMDUnit) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit), + serialized_chunks + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8)) + in + result + +let deserialize_to_vector_then_ntt + (#v_SIMDUnit: Type0) + (v_DIMENSION v_ETA v_RING_ELEMENT_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Slice u8) + = + let ring_elements:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let ring_elements:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_Chunks u8)) + #FStar.Tactics.Typeclasses.solve + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_Chunks u8) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__chunks #u8 serialized v_RING_ELEMENT_SIZE + <: + Core.Slice.Iter.t_Chunks u8) + <: + Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Chunks u8)) + <: + Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Chunks u8)) + ring_elements + (fun ring_elements temp_1_ -> + let ring_elements:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + ring_elements + in + let i, bytes:(usize & t_Slice u8) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize ring_elements + i + (Libcrux_ml_dsa.Ntt.ntt #v_SIMDUnit + (deserialize #v_SIMDUnit v_ETA bytes + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + in + ring_elements + +let serialize + (#v_SIMDUnit: Type0) + (v_ETA v_OUTPUT_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + let serialized:t_Array u8 v_OUTPUT_SIZE = Rust_primitives.Hax.repeat 0uy v_OUTPUT_SIZE in + match cast (v_ETA <: usize) <: u8 with + | 2uy -> + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Simd.Traits.f_error_serialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (sz 3) + simd_unit + <: + t_Slice u8) + <: + t_Slice u8) + <: + t_Array u8 v_OUTPUT_SIZE) + in + serialized + | 4uy -> + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start + = + i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Simd.Traits.f_error_serialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (sz 4) + simd_unit + <: + t_Slice u8) + <: + t_Slice u8) + <: + t_Array u8 v_OUTPUT_SIZE) + in + serialized + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Error.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Error.fsti new file mode 100644 index 000000000..199d62d48 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Error.fsti @@ -0,0 +1,40 @@ +module Libcrux_ml_dsa.Encoding.Error +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let serialize__OUTPUT_BYTES_PER_SIMD_UNIT: usize = sz 3 + +let serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1: usize = sz 4 + +val deserialize + (#v_SIMDUnit: Type0) + (v_ETA: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Slice u8) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_to_vector_then_ntt + (#v_SIMDUnit: Type0) + (v_DIMENSION v_ETA v_RING_ELEMENT_SIZE: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Slice u8) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val serialize + (#v_SIMDUnit: Type0) + (v_ETA v_OUTPUT_SIZE: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Gamma1.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Gamma1.fst new file mode 100644 index 000000000..470cf8ab6 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Gamma1.fst @@ -0,0 +1,194 @@ +module Libcrux_ml_dsa.Encoding.Gamma1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let deserialize + (#v_SIMDUnit: Type0) + (v_GAMMA1_EXPONENT: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Slice u8) + = + let serialized_chunks:Core.Slice.Iter.t_Chunks u8 = + match cast (v_GAMMA1_EXPONENT <: usize) <: u8 with + | 17uy -> Core.Slice.impl__chunks #u8 serialized (sz 18) + | 19uy -> Core.Slice.impl__chunks #u8 serialized (sz 20) + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + in + let result:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + in + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit + (result.Libcrux_ml_dsa.Polynomial.f_simd_units <: t_Slice v_SIMDUnit) + <: + usize) + (fun temp_0_ temp_1_ -> + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (result, serialized_chunks + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & Core.Slice.Iter.t_Chunks u8) + ) + (fun temp_0_ i -> + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + temp_0_ + in + let i:usize = i in + let tmp0, out:(Core.Slice.Iter.t_Chunks u8 & Core.Option.t_Option (t_Slice u8)) = + Core.Iter.Traits.Iterator.f_next #(Core.Slice.Iter.t_Chunks u8) + #FStar.Tactics.Typeclasses.solve + serialized_chunks + in + let serialized_chunks:Core.Slice.Iter.t_Chunks u8 = tmp0 in + ({ + result with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_dsa.Polynomial.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_gamma1_deserialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + v_GAMMA1_EXPONENT + (Core.Option.impl__unwrap #(t_Slice u8) out <: t_Slice u8) + <: + v_SIMDUnit) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit), + serialized_chunks + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8)) + in + result + +let serialize + (#v_SIMDUnit: Type0) + (v_GAMMA1_EXPONENT v_OUTPUT_BYTES: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + let serialized:t_Array u8 v_OUTPUT_BYTES = Rust_primitives.Hax.repeat 0uy v_OUTPUT_BYTES in + match cast (v_GAMMA1_EXPONENT <: usize) <: u8 with + | 17uy -> + let serialized:t_Array u8 v_OUTPUT_BYTES = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_BYTES = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_BYTES = serialized in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Simd.Traits.f_gamma1_serialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (sz 18) + simd_unit + <: + t_Slice u8) + <: + t_Slice u8) + <: + t_Array u8 v_OUTPUT_BYTES) + in + serialized + | 19uy -> + let serialized:t_Array u8 v_OUTPUT_BYTES = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_BYTES = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_BYTES = serialized in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start + = + i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1 <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Simd.Traits.f_gamma1_serialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (sz 20) + simd_unit + <: + t_Slice u8) + <: + t_Slice u8) + <: + t_Array u8 v_OUTPUT_BYTES) + in + serialized + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Gamma1.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Gamma1.fsti new file mode 100644 index 000000000..c6b16420b --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Gamma1.fsti @@ -0,0 +1,30 @@ +module Libcrux_ml_dsa.Encoding.Gamma1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let serialize__OUTPUT_BYTES_PER_SIMD_UNIT: usize = sz 18 + +let serialize__OUTPUT_BYTES_PER_SIMD_UNIT_1: usize = sz 20 + +val deserialize + (#v_SIMDUnit: Type0) + (v_GAMMA1_EXPONENT: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Slice u8) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val serialize + (#v_SIMDUnit: Type0) + (v_GAMMA1_EXPONENT v_OUTPUT_BYTES: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_BYTES) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signature.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signature.fst new file mode 100644 index 000000000..974a66ac7 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signature.fst @@ -0,0 +1,348 @@ +module Libcrux_ml_dsa.Encoding.Signature +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let impl__deserialize + (#v_SIMDUnit: Type0) + (v_COMMITMENT_HASH_SIZE v_COLUMNS_IN_A v_ROWS_IN_A v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_MAX_ONES_IN_HINT v_SIGNATURE_SIZE: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Array u8 v_SIGNATURE_SIZE) + = + let commitment_hash, rest_of_serialized:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 (serialized <: t_Slice u8) v_COMMITMENT_HASH_SIZE + in + let signer_response_serialized, hint_serialized:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + rest_of_serialized + (v_GAMMA1_RING_ELEMENT_SIZE *! v_COLUMNS_IN_A <: usize) + in + let signer_response:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A + in + let signer_response:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_COLUMNS_IN_A + (fun signer_response temp_1_ -> + let signer_response:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A = + signer_response + in + let _:usize = temp_1_ in + true) + signer_response + (fun signer_response i -> + let signer_response:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A = + signer_response + in + let i:usize = i in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize signer_response + i + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (signer_response_serialized.[ { + Core.Ops.Range.f_start = i *! v_GAMMA1_RING_ELEMENT_SIZE <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! v_GAMMA1_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + in + let hint:t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0l (sz 256) <: t_Array i32 (sz 256)) + v_ROWS_IN_A + in + let previous_true_hints_seen:usize = sz 0 in + let i:usize = sz 0 in + let malformed_hint:bool = false in + let hint, i, malformed_hint, previous_true_hints_seen:(t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & + usize & + bool & + usize) = + Rust_primitives.f_while_loop (fun temp_0_ -> + let hint, i, malformed_hint, previous_true_hints_seen:(t_Array (t_Array i32 (sz 256)) + v_ROWS_IN_A & + usize & + bool & + usize) = + temp_0_ + in + (i <. v_ROWS_IN_A <: bool) && (~.malformed_hint <: bool)) + (hint, i, malformed_hint, previous_true_hints_seen + <: + (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & bool & usize)) + (fun temp_0_ -> + let hint, i, malformed_hint, previous_true_hints_seen:(t_Array (t_Array i32 (sz 256)) + v_ROWS_IN_A & + usize & + bool & + usize) = + temp_0_ + in + let current_true_hints_seen:usize = + cast (hint_serialized.[ v_MAX_ONES_IN_HINT +! i <: usize ] <: u8) <: usize + in + let malformed_hint:bool = + if + current_true_hints_seen <. previous_true_hints_seen || + previous_true_hints_seen >. v_MAX_ONES_IN_HINT + then + let malformed_hint:bool = true in + malformed_hint + else malformed_hint + in + let j:usize = previous_true_hints_seen in + let hint, j, malformed_hint:(t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & bool) = + Rust_primitives.f_while_loop (fun temp_0_ -> + let hint, j, malformed_hint:(t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & + bool) = + temp_0_ + in + (~.malformed_hint <: bool) && (j <. current_true_hints_seen <: bool)) + (hint, j, malformed_hint + <: + (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & bool)) + (fun temp_0_ -> + let hint, j, malformed_hint:(t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & + bool) = + temp_0_ + in + let malformed_hint:bool = + if + j >. previous_true_hints_seen && + (hint_serialized.[ j ] <: u8) <=. + (hint_serialized.[ j -! sz 1 <: usize ] <: u8) + then + let malformed_hint:bool = true in + malformed_hint + else malformed_hint + in + if ~.malformed_hint + then + let hint:t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize hint + i + (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (hint.[ i ] + <: + t_Array i32 (sz 256)) + (cast (hint_serialized.[ j ] <: u8) <: usize) + 1l + <: + t_Array i32 (sz 256)) + in + let j:usize = j +! sz 1 in + hint, j, malformed_hint + <: + (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & bool) + else + hint, j, malformed_hint + <: + (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & bool)) + in + if ~.malformed_hint + then + let previous_true_hints_seen:usize = current_true_hints_seen in + let i:usize = i +! sz 1 in + hint, i, malformed_hint, previous_true_hints_seen + <: + (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & bool & usize) + else + hint, i, malformed_hint, previous_true_hints_seen + <: + (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A & usize & bool & usize)) + in + let i:usize = previous_true_hints_seen in + let i, malformed_hint:(usize & bool) = + Rust_primitives.f_while_loop (fun temp_0_ -> + let i, malformed_hint:(usize & bool) = temp_0_ in + (i <. v_MAX_ONES_IN_HINT <: bool) && (~.malformed_hint <: bool)) + (i, malformed_hint <: (usize & bool)) + (fun temp_0_ -> + let i, malformed_hint:(usize & bool) = temp_0_ in + let malformed_hint:bool = + if (hint_serialized.[ i ] <: u8) <>. 0uy + then + let malformed_hint:bool = true in + malformed_hint + else malformed_hint + in + let i:usize = i +! sz 1 in + i, malformed_hint <: (usize & bool)) + in + if malformed_hint + then + Core.Result.Result_Err + (Libcrux_ml_dsa.Types.VerificationError_MalformedHintError + <: + Libcrux_ml_dsa.Types.t_VerificationError) + <: + Core.Result.t_Result + (Libcrux_ml_dsa.Types.t_Signature v_SIMDUnit v_COMMITMENT_HASH_SIZE v_COLUMNS_IN_A v_ROWS_IN_A + ) Libcrux_ml_dsa.Types.t_VerificationError + else + Core.Result.Result_Ok + ({ + Libcrux_ml_dsa.Types.f_commitment_hash + = + Core.Result.impl__unwrap #(t_Array u8 v_COMMITMENT_HASH_SIZE) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 v_COMMITMENT_HASH_SIZE) + #FStar.Tactics.Typeclasses.solve + commitment_hash + <: + Core.Result.t_Result (t_Array u8 v_COMMITMENT_HASH_SIZE) Core.Array.t_TryFromSliceError); + Libcrux_ml_dsa.Types.f_signer_response = signer_response; + Libcrux_ml_dsa.Types.f_hint = hint + } + <: + Libcrux_ml_dsa.Types.t_Signature v_SIMDUnit v_COMMITMENT_HASH_SIZE v_COLUMNS_IN_A v_ROWS_IN_A) + <: + Core.Result.t_Result + (Libcrux_ml_dsa.Types.t_Signature v_SIMDUnit v_COMMITMENT_HASH_SIZE v_COLUMNS_IN_A v_ROWS_IN_A + ) Libcrux_ml_dsa.Types.t_VerificationError + +let impl__serialize + (#v_SIMDUnit: Type0) + (v_COMMITMENT_HASH_SIZE v_COLUMNS_IN_A v_ROWS_IN_A v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_MAX_ONES_IN_HINT v_SIGNATURE_SIZE: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (self: + Libcrux_ml_dsa.Types.t_Signature v_SIMDUnit + v_COMMITMENT_HASH_SIZE + v_COLUMNS_IN_A + v_ROWS_IN_A) + = + let signature:t_Array u8 v_SIGNATURE_SIZE = Rust_primitives.Hax.repeat 0uy v_SIGNATURE_SIZE in + let offset:usize = sz 0 in + let signature:t_Array u8 v_SIGNATURE_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range signature + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_COMMITMENT_HASH_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (signature.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_COMMITMENT_HASH_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (self.Libcrux_ml_dsa.Types.f_commitment_hash <: t_Slice u8) + <: + t_Slice u8) + in + let offset:usize = offset +! v_COMMITMENT_HASH_SIZE in + let offset, signature:(usize & t_Array u8 v_SIGNATURE_SIZE) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_COLUMNS_IN_A + (fun temp_0_ temp_1_ -> + let offset, signature:(usize & t_Array u8 v_SIGNATURE_SIZE) = temp_0_ in + let _:usize = temp_1_ in + true) + (offset, signature <: (usize & t_Array u8 v_SIGNATURE_SIZE)) + (fun temp_0_ i -> + let offset, signature:(usize & t_Array u8 v_SIGNATURE_SIZE) = temp_0_ in + let i:usize = i in + let signature:t_Array u8 v_SIGNATURE_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range signature + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_GAMMA1_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (signature.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_GAMMA1_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Encoding.Gamma1.serialize #v_SIMDUnit + v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE + (self.Libcrux_ml_dsa.Types.f_signer_response.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Slice u8) + <: + t_Slice u8) + in + let offset:usize = offset +! v_GAMMA1_RING_ELEMENT_SIZE in + offset, signature <: (usize & t_Array u8 v_SIGNATURE_SIZE)) + in + let true_hints_seen:usize = sz 0 in + let signature, true_hints_seen:(t_Array u8 v_SIGNATURE_SIZE & usize) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_ROWS_IN_A + (fun temp_0_ temp_1_ -> + let signature, true_hints_seen:(t_Array u8 v_SIGNATURE_SIZE & usize) = temp_0_ in + let _:usize = temp_1_ in + true) + (signature, true_hints_seen <: (t_Array u8 v_SIGNATURE_SIZE & usize)) + (fun temp_0_ i -> + let signature, true_hints_seen:(t_Array u8 v_SIGNATURE_SIZE & usize) = temp_0_ in + let i:usize = i in + let signature, true_hints_seen:(t_Array u8 v_SIGNATURE_SIZE & usize) = + Rust_primitives.Hax.Folds.fold_enumerated_slice (self.Libcrux_ml_dsa.Types.f_hint.[ i ] + <: + t_Array i32 (sz 256)) + (fun temp_0_ temp_1_ -> + let signature, true_hints_seen:(t_Array u8 v_SIGNATURE_SIZE & usize) = temp_0_ in + let _:usize = temp_1_ in + true) + (signature, true_hints_seen <: (t_Array u8 v_SIGNATURE_SIZE & usize)) + (fun temp_0_ temp_1_ -> + let signature, true_hints_seen:(t_Array u8 v_SIGNATURE_SIZE & usize) = temp_0_ in + let j, hint:(usize & i32) = temp_1_ in + if hint =. 1l <: bool + then + let signature:t_Array u8 v_SIGNATURE_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize signature + (offset +! true_hints_seen <: usize) + (cast (j <: usize) <: u8) + in + let true_hints_seen:usize = true_hints_seen +! sz 1 in + signature, true_hints_seen <: (t_Array u8 v_SIGNATURE_SIZE & usize) + else signature, true_hints_seen <: (t_Array u8 v_SIGNATURE_SIZE & usize)) + in + let signature:t_Array u8 v_SIGNATURE_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize signature + ((offset +! v_MAX_ONES_IN_HINT <: usize) +! i <: usize) + (cast (true_hints_seen <: usize) <: u8) + in + signature, true_hints_seen <: (t_Array u8 v_SIGNATURE_SIZE & usize)) + in + signature diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signature.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signature.fsti new file mode 100644 index 000000000..946d0fb21 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signature.fsti @@ -0,0 +1,37 @@ +module Libcrux_ml_dsa.Encoding.Signature +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +val impl__deserialize + (#v_SIMDUnit: Type0) + (v_COMMITMENT_HASH_SIZE v_COLUMNS_IN_A v_ROWS_IN_A v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_MAX_ONES_IN_HINT v_SIGNATURE_SIZE: + usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure + (Core.Result.t_Result + (Libcrux_ml_dsa.Types.t_Signature v_SIMDUnit + v_COMMITMENT_HASH_SIZE + v_COLUMNS_IN_A + v_ROWS_IN_A) Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +val impl__serialize + (#v_SIMDUnit: Type0) + (v_COMMITMENT_HASH_SIZE v_COLUMNS_IN_A v_ROWS_IN_A v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_MAX_ONES_IN_HINT v_SIGNATURE_SIZE: + usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (self: + Libcrux_ml_dsa.Types.t_Signature v_SIMDUnit + v_COMMITMENT_HASH_SIZE + v_COLUMNS_IN_A + v_ROWS_IN_A) + : Prims.Pure (t_Array u8 v_SIGNATURE_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signing_key.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signing_key.fst new file mode 100644 index 000000000..1394c5939 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signing_key.fst @@ -0,0 +1,328 @@ +module Libcrux_ml_dsa.Encoding.Signing_key +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Simd.Traits in + () + +let deserialize_then_ntt + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Array u8 v_SIGNING_KEY_SIZE) + = + let seed_for_A, remaining_serialized:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + (serialized <: t_Slice u8) + Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE + in + let seed_for_signing, remaining_serialized:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + remaining_serialized + Libcrux_ml_dsa.Constants.v_SEED_FOR_SIGNING_SIZE + in + let verification_key_hash, remaining_serialized:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + remaining_serialized + Libcrux_ml_dsa.Constants.v_BYTES_FOR_VERIFICATION_KEY_HASH + in + let s1_serialized, remaining_serialized:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + remaining_serialized + (v_ERROR_RING_ELEMENT_SIZE *! v_COLUMNS_IN_A <: usize) + in + let s2_serialized, t0_serialized:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + remaining_serialized + (v_ERROR_RING_ELEMENT_SIZE *! v_ROWS_IN_A <: usize) + in + let s1_as_ntt:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A = + Libcrux_ml_dsa.Encoding.Error.deserialize_to_vector_then_ntt #v_SIMDUnit + v_COLUMNS_IN_A + v_ETA + v_ERROR_RING_ELEMENT_SIZE + s1_serialized + in + let s2_as_ntt:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Libcrux_ml_dsa.Encoding.Error.deserialize_to_vector_then_ntt #v_SIMDUnit + v_ROWS_IN_A + v_ETA + v_ERROR_RING_ELEMENT_SIZE + s2_serialized + in + let t0_as_ntt:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Libcrux_ml_dsa.Encoding.T0.deserialize_to_vector_then_ntt #v_SIMDUnit v_ROWS_IN_A t0_serialized + in + Core.Result.impl__unwrap #(t_Array u8 (sz 32)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 (sz 32)) + #FStar.Tactics.Typeclasses.solve + seed_for_A + <: + Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError), + Core.Result.impl__unwrap #(t_Array u8 (sz 32)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 (sz 32)) + #FStar.Tactics.Typeclasses.solve + seed_for_signing + <: + Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError), + Core.Result.impl__unwrap #(t_Array u8 (sz 64)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 (sz 64)) + #FStar.Tactics.Typeclasses.solve + verification_key_hash + <: + Core.Result.t_Result (t_Array u8 (sz 64)) Core.Array.t_TryFromSliceError), + s1_as_ntt, + s2_as_ntt, + t0_as_ntt + <: + (t_Array u8 (sz 32) & t_Array u8 (sz 32) & t_Array u8 (sz 64) & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + +let generate_serialized + (#v_SIMDUnit #v_Shake256: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (seed_for_A seed_for_signing verification_key: t_Slice u8) + (s1: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + (s2 t0: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + = + let signing_key_serialized:t_Array u8 v_SIGNING_KEY_SIZE = + Rust_primitives.Hax.repeat 0uy v_SIGNING_KEY_SIZE + in + let offset:usize = sz 0 in + let signing_key_serialized:t_Array u8 v_SIGNING_KEY_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range signing_key_serialized + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (signing_key_serialized.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + seed_for_A + <: + t_Slice u8) + in + let offset:usize = offset +! Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE in + let signing_key_serialized:t_Array u8 v_SIGNING_KEY_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range signing_key_serialized + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! Libcrux_ml_dsa.Constants.v_SEED_FOR_SIGNING_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (signing_key_serialized.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end + = + offset +! Libcrux_ml_dsa.Constants.v_SEED_FOR_SIGNING_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + seed_for_signing + <: + t_Slice u8) + in + let offset:usize = offset +! Libcrux_ml_dsa.Constants.v_SEED_FOR_SIGNING_SIZE in + let verification_key_hash:t_Array u8 (sz 64) = Rust_primitives.Hax.repeat 0uy (sz 64) in + let verification_key_hash:t_Array u8 (sz 64) = + Libcrux_ml_dsa.Hash_functions.Shake256.f_shake256 #v_Shake256 + #FStar.Tactics.Typeclasses.solve + (sz 64) + verification_key + verification_key_hash + in + let signing_key_serialized:t_Array u8 v_SIGNING_KEY_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range signing_key_serialized + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end + = + offset +! Libcrux_ml_dsa.Constants.v_BYTES_FOR_VERIFICATION_KEY_HASH <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (signing_key_serialized.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end + = + offset +! Libcrux_ml_dsa.Constants.v_BYTES_FOR_VERIFICATION_KEY_HASH <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (verification_key_hash <: t_Slice u8) + <: + t_Slice u8) + in + let offset:usize = offset +! Libcrux_ml_dsa.Constants.v_BYTES_FOR_VERIFICATION_KEY_HASH in + let offset, signing_key_serialized:(usize & t_Array u8 v_SIGNING_KEY_SIZE) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Iter + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__iter #(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (s1 <: t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (offset, signing_key_serialized <: (usize & t_Array u8 v_SIGNING_KEY_SIZE)) + (fun temp_0_ ring_element -> + let offset, signing_key_serialized:(usize & t_Array u8 v_SIGNING_KEY_SIZE) = temp_0_ in + let ring_element:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + ring_element + in + let signing_key_serialized:t_Array u8 v_SIGNING_KEY_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range signing_key_serialized + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_ERROR_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (signing_key_serialized.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_ERROR_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Encoding.Error.serialize #v_SIMDUnit + v_ETA + v_ERROR_RING_ELEMENT_SIZE + ring_element + <: + t_Slice u8) + <: + t_Slice u8) + in + let offset:usize = offset +! v_ERROR_RING_ELEMENT_SIZE in + offset, signing_key_serialized <: (usize & t_Array u8 v_SIGNING_KEY_SIZE)) + in + let offset, signing_key_serialized:(usize & t_Array u8 v_SIGNING_KEY_SIZE) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Iter + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__iter #(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (s2 <: t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (offset, signing_key_serialized <: (usize & t_Array u8 v_SIGNING_KEY_SIZE)) + (fun temp_0_ ring_element -> + let offset, signing_key_serialized:(usize & t_Array u8 v_SIGNING_KEY_SIZE) = temp_0_ in + let ring_element:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + ring_element + in + let signing_key_serialized:t_Array u8 v_SIGNING_KEY_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range signing_key_serialized + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_ERROR_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (signing_key_serialized.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! v_ERROR_RING_ELEMENT_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Encoding.Error.serialize #v_SIMDUnit + v_ETA + v_ERROR_RING_ELEMENT_SIZE + ring_element + <: + t_Slice u8) + <: + t_Slice u8) + in + let offset:usize = offset +! v_ERROR_RING_ELEMENT_SIZE in + offset, signing_key_serialized <: (usize & t_Array u8 v_SIGNING_KEY_SIZE)) + in + let offset, signing_key_serialized:(usize & t_Array u8 v_SIGNING_KEY_SIZE) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Iter + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__iter #(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (t0 <: t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + <: + Core.Slice.Iter.t_Iter (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (offset, signing_key_serialized <: (usize & t_Array u8 v_SIGNING_KEY_SIZE)) + (fun temp_0_ ring_element -> + let offset, signing_key_serialized:(usize & t_Array u8 v_SIGNING_KEY_SIZE) = temp_0_ in + let ring_element:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + ring_element + in + let signing_key_serialized:t_Array u8 v_SIGNING_KEY_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range signing_key_serialized + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end + = + offset +! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T0S_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (signing_key_serialized.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end + = + offset +! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T0S_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Encoding.T0.serialize #v_SIMDUnit ring_element <: t_Slice u8) + <: + t_Slice u8) + in + let offset:usize = offset +! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T0S_SIZE in + offset, signing_key_serialized <: (usize & t_Array u8 v_SIGNING_KEY_SIZE)) + in + signing_key_serialized diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signing_key.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signing_key.fsti new file mode 100644 index 000000000..b8a8f2d90 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Signing_key.fsti @@ -0,0 +1,34 @@ +module Libcrux_ml_dsa.Encoding.Signing_key +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Simd.Traits in + () + +val deserialize_then_ntt + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Array u8 v_SIGNING_KEY_SIZE) + : Prims.Pure + (t_Array u8 (sz 32) & t_Array u8 (sz 32) & t_Array u8 (sz 64) & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + Prims.l_True + (fun _ -> Prims.l_True) + +val generate_serialized + (#v_SIMDUnit #v_Shake256: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + (seed_for_A seed_for_signing verification_key: t_Slice u8) + (s1: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + (s2 t0: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + : Prims.Pure (t_Array u8 v_SIGNING_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T0.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T0.fst new file mode 100644 index 000000000..b1193d6cd --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T0.fst @@ -0,0 +1,180 @@ +module Libcrux_ml_dsa.Encoding.T0 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let deserialize + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Slice u8) + = + let serialized_chunks:Core.Slice.Iter.t_Chunks u8 = + Core.Slice.impl__chunks #u8 serialized (sz 13) + in + let result:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + in + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit + (result.Libcrux_ml_dsa.Polynomial.f_simd_units <: t_Slice v_SIMDUnit) + <: + usize) + (fun temp_0_ temp_1_ -> + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (result, serialized_chunks + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & Core.Slice.Iter.t_Chunks u8) + ) + (fun temp_0_ i -> + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + temp_0_ + in + let i:usize = i in + let tmp0, out:(Core.Slice.Iter.t_Chunks u8 & Core.Option.t_Option (t_Slice u8)) = + Core.Iter.Traits.Iterator.f_next #(Core.Slice.Iter.t_Chunks u8) + #FStar.Tactics.Typeclasses.solve + serialized_chunks + in + let serialized_chunks:Core.Slice.Iter.t_Chunks u8 = tmp0 in + ({ + result with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_dsa.Polynomial.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_t0_deserialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Core.Option.impl__unwrap #(t_Slice u8) out <: t_Slice u8) + <: + v_SIMDUnit) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit), + serialized_chunks + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8)) + in + result + +let deserialize_to_vector_then_ntt + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Slice u8) + = + let ring_elements:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let ring_elements:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Iter.Adapters.Enumerate.t_Enumerate + (Core.Slice.Iter.t_Chunks u8)) + #FStar.Tactics.Typeclasses.solve + (Core.Iter.Traits.Iterator.f_enumerate #(Core.Slice.Iter.t_Chunks u8) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__chunks #u8 + serialized + Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T0S_SIZE + <: + Core.Slice.Iter.t_Chunks u8) + <: + Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Chunks u8)) + <: + Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Chunks u8)) + ring_elements + (fun ring_elements temp_1_ -> + let ring_elements:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + ring_elements + in + let i, bytes:(usize & t_Slice u8) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize ring_elements + i + (Libcrux_ml_dsa.Ntt.ntt #v_SIMDUnit + (deserialize #v_SIMDUnit bytes + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + in + ring_elements + +let serialize + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + let serialized:t_Array u8 (sz 416) = Rust_primitives.Hax.repeat 0uy (sz 416) in + let serialized:t_Array u8 (sz 416) = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun serialized temp_1_ -> + let serialized:t_Array u8 (sz 416) = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 (sz 416) = serialized in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Simd.Traits.f_t0_serialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + simd_unit + <: + t_Slice u8) + <: + t_Slice u8) + <: + t_Array u8 (sz 416)) + in + serialized diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T0.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T0.fsti new file mode 100644 index 000000000..3969d9d7c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T0.fsti @@ -0,0 +1,36 @@ +module Libcrux_ml_dsa.Encoding.T0 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let serialize__OUTPUT_BYTES_PER_SIMD_UNIT: usize = sz 13 + +val deserialize + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Slice u8) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_to_vector_then_ntt + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Slice u8) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val serialize + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (t_Array u8 (sz 416)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T1.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T1.fst new file mode 100644 index 000000000..6a59315c3 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T1.fst @@ -0,0 +1,129 @@ +module Libcrux_ml_dsa.Encoding.T1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let deserialize + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Slice u8) + = + let serialized_chunks:Core.Slice.Iter.t_Chunks u8 = + Core.Slice.impl__chunks #u8 serialized (sz 10) + in + let result:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + in + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit + (result.Libcrux_ml_dsa.Polynomial.f_simd_units <: t_Slice v_SIMDUnit) + <: + usize) + (fun temp_0_ temp_1_ -> + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (result, serialized_chunks + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & Core.Slice.Iter.t_Chunks u8) + ) + (fun temp_0_ i -> + let result, serialized_chunks:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8) = + temp_0_ + in + let i:usize = i in + let tmp0, out:(Core.Slice.Iter.t_Chunks u8 & Core.Option.t_Option (t_Slice u8)) = + Core.Iter.Traits.Iterator.f_next #(Core.Slice.Iter.t_Chunks u8) + #FStar.Tactics.Typeclasses.solve + serialized_chunks + in + let serialized_chunks:Core.Slice.Iter.t_Chunks u8 = tmp0 in + ({ + result with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_dsa.Polynomial.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_t1_deserialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Core.Option.impl__unwrap #(t_Slice u8) out <: t_Slice u8) + <: + v_SIMDUnit) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit), + serialized_chunks + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Core.Slice.Iter.t_Chunks u8)) + in + result + +let serialize + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + let serialized:t_Array u8 (sz 320) = Rust_primitives.Hax.repeat 0uy (sz 320) in + let serialized:t_Array u8 (sz 320) = + Rust_primitives.Hax.Folds.fold_enumerated_slice (re.Libcrux_ml_dsa.Polynomial.f_simd_units + <: + t_Slice v_SIMDUnit) + (fun serialized temp_1_ -> + let serialized:t_Array u8 (sz 320) = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 (sz 320) = serialized in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized.[ { + Core.Ops.Range.f_start = i *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! serialize__OUTPUT_BYTES_PER_SIMD_UNIT <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Simd.Traits.f_t1_serialize #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + simd_unit + <: + t_Slice u8) + <: + t_Slice u8) + <: + t_Array u8 (sz 320)) + in + serialized diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T1.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T1.fsti new file mode 100644 index 000000000..f05c66a13 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.T1.fsti @@ -0,0 +1,26 @@ +module Libcrux_ml_dsa.Encoding.T1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let serialize__OUTPUT_BYTES_PER_SIMD_UNIT: usize = sz 10 + +val deserialize + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Slice u8) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val serialize + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (t_Array u8 (sz 320)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Verification_key.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Verification_key.fst new file mode 100644 index 000000000..94a614a45 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Verification_key.fst @@ -0,0 +1,166 @@ +module Libcrux_ml_dsa.Encoding.Verification_key +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let deserialize + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_VERIFICATION_KEY_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + = + let t1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A + in + let seed_for_A, serialized_remaining:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + (serialized <: t_Slice u8) + Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE + in + let t1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_ROWS_IN_A + (fun t1 temp_1_ -> + let t1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A + = + t1 + in + let _:usize = temp_1_ in + true) + t1 + (fun t1 i -> + let t1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A + = + t1 + in + let i:usize = i in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize t1 + i + (Libcrux_ml_dsa.Encoding.T1.deserialize #v_SIMDUnit + (serialized_remaining.[ { + Core.Ops.Range.f_start + = + i *! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T1S_SIZE <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T1S_SIZE + <: + usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + in + Core.Result.impl__unwrap #(t_Array u8 (sz 32)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 (sz 32)) + #FStar.Tactics.Typeclasses.solve + seed_for_A + <: + Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError), + t1 + <: + (t_Array u8 (sz 32) & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + +let generate_serialized + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_VERIFICATION_KEY_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (seed_for_A: t_Slice u8) + (t1: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + = + let verification_key_serialized:t_Array u8 v_VERIFICATION_KEY_SIZE = + Rust_primitives.Hax.repeat 0uy v_VERIFICATION_KEY_SIZE + in + let verification_key_serialized:t_Array u8 v_VERIFICATION_KEY_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range verification_key_serialized + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (verification_key_serialized.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + seed_for_A + <: + t_Slice u8) + in + let verification_key_serialized:t_Array u8 v_VERIFICATION_KEY_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_slice (t1 + <: + t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (fun verification_key_serialized temp_1_ -> + let verification_key_serialized:t_Array u8 v_VERIFICATION_KEY_SIZE = + verification_key_serialized + in + let _:usize = temp_1_ in + true) + verification_key_serialized + (fun verification_key_serialized temp_1_ -> + let verification_key_serialized:t_Array u8 v_VERIFICATION_KEY_SIZE = + verification_key_serialized + in + let i, ring_element:(usize & Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + temp_1_ + in + let offset:usize = + Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE +! + (i *! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T1S_SIZE <: usize) + in + let verification_key_serialized:t_Array u8 v_VERIFICATION_KEY_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range verification_key_serialized + ({ + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end + = + offset +! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T1S_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (verification_key_serialized.[ { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end + = + offset +! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T1S_SIZE <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + (Libcrux_ml_dsa.Encoding.T1.serialize #v_SIMDUnit ring_element <: t_Slice u8) + <: + t_Slice u8) + in + verification_key_serialized) + in + verification_key_serialized diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Verification_key.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Verification_key.fsti new file mode 100644 index 000000000..59e60a0ee --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Encoding.Verification_key.fsti @@ -0,0 +1,29 @@ +module Libcrux_ml_dsa.Encoding.Verification_key +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +val deserialize + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_VERIFICATION_KEY_SIZE: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + : Prims.Pure + (t_Array u8 (sz 32) & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + Prims.l_True + (fun _ -> Prims.l_True) + +val generate_serialized + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_VERIFICATION_KEY_SIZE: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (seed_for_A: t_Slice u8) + (t1: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + : Prims.Pure (t_Array u8 v_VERIFICATION_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Neon.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Neon.fsti new file mode 100644 index 000000000..a7762dfe1 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Neon.fsti @@ -0,0 +1,57 @@ +module Libcrux_ml_dsa.Hash_functions.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +val t_Shake128x4:Type0 + +/// Neon SHAKE 256 x4 state +val t_Shake256x4:Type0 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl:Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 t_Shake128x4 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl_1:Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 t_Shake256x4 + +/// Init the state and absorb 4 blocks in parallel. +val init_absorb (input0 input1 input2 input3: t_Slice u8) + : Prims.Pure t_Shake128x4 Prims.l_True (fun _ -> Prims.l_True) + +val init_absorb_x4 (input0 input1 input2 input3: t_Slice u8) + : Prims.Pure t_Shake256x4 Prims.l_True (fun _ -> Prims.l_True) + +val shake256_x4 + (v_OUT_LEN: usize) + (input0 input1 input2 input3: t_Slice u8) + (out0 out1 out2 out3: t_Array u8 v_OUT_LEN) + : Prims.Pure + (t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN) + Prims.l_True + (fun _ -> Prims.l_True) + +val squeeze_first_block_x4 (state: t_Shake256x4) + : Prims.Pure + (t_Shake256x4 & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + Prims.l_True + (fun _ -> Prims.l_True) + +val squeeze_first_five_blocks (state: t_Shake128x4) (out0 out1 out2 out3: t_Array u8 (sz 840)) + : Prims.Pure + (t_Shake128x4 & t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840)) Prims.l_True (fun _ -> Prims.l_True) + +val squeeze_next_block (state: t_Shake128x4) + : Prims.Pure + (t_Shake128x4 & + (t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168))) + Prims.l_True + (fun _ -> Prims.l_True) + +val squeeze_next_block_x4 (state: t_Shake256x4) + : Prims.Pure + (t_Shake256x4 & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Portable.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Portable.fsti new file mode 100644 index 000000000..0a59a5cc8 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Portable.fsti @@ -0,0 +1,92 @@ +module Libcrux_ml_dsa.Hash_functions.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Portable SHAKE 128 state +val t_Shake128:Type0 + +/// Portable SHAKE 128 x4 state. +/// We\'re using a portable implementation so this is actually sequential. +val t_Shake128X4:Type0 + +/// Portable SHAKE 256 state +val t_Shake256:Type0 + +/// Portable SHAKE 256 x4 state. +/// We\'re using a portable implementation so this is actually sequential. +val t_Shake256X4:Type0 + +val t_Shake256Absorb:Type0 + +val t_Shake256Squeeze:Type0 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl:Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 t_Shake128X4 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl_1:Libcrux_ml_dsa.Hash_functions.Shake128.t_Xof t_Shake128 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl_2:Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof t_Shake256 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl_3:Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 t_Shake256X4 + +val init_absorb (input0 input1 input2 input3: t_Slice u8) + : Prims.Pure t_Shake128X4 Prims.l_True (fun _ -> Prims.l_True) + +val init_absorb_shake256 (input: t_Slice u8) + : Prims.Pure t_Shake256 Prims.l_True (fun _ -> Prims.l_True) + +val init_absorb_x4 (input0 input1 input2 input3: t_Slice u8) + : Prims.Pure t_Shake256X4 Prims.l_True (fun _ -> Prims.l_True) + +val shake128 (v_OUTPUT_LENGTH: usize) (input: t_Slice u8) (out: t_Array u8 v_OUTPUT_LENGTH) + : Prims.Pure (t_Array u8 v_OUTPUT_LENGTH) Prims.l_True (fun _ -> Prims.l_True) + +val shake256 (v_OUTPUT_LENGTH: usize) (input: t_Slice u8) (out: t_Array u8 v_OUTPUT_LENGTH) + : Prims.Pure (t_Array u8 v_OUTPUT_LENGTH) Prims.l_True (fun _ -> Prims.l_True) + +val shake256_absorb (st: t_Shake256Absorb) (input: t_Slice u8) + : Prims.Pure t_Shake256Absorb Prims.l_True (fun _ -> Prims.l_True) + +val shake256_absorb_final (st: t_Shake256Absorb) (input: t_Slice u8) + : Prims.Pure t_Shake256Squeeze Prims.l_True (fun _ -> Prims.l_True) + +val shake256_init: Prims.unit -> Prims.Pure t_Shake256Absorb Prims.l_True (fun _ -> Prims.l_True) + +val shake256_squeeze (st: t_Shake256Squeeze) (out: t_Slice u8) + : Prims.Pure (t_Shake256Squeeze & t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +val squeeze_first_block_shake256 (state: t_Shake256) + : Prims.Pure (t_Shake256 & t_Array u8 (sz 136)) Prims.l_True (fun _ -> Prims.l_True) + +val squeeze_first_block_x4 (state: t_Shake256X4) + : Prims.Pure + (t_Shake256X4 & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + Prims.l_True + (fun _ -> Prims.l_True) + +val squeeze_first_five_blocks (state: t_Shake128X4) (out0 out1 out2 out3: t_Array u8 (sz 840)) + : Prims.Pure + (t_Shake128X4 & t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840)) Prims.l_True (fun _ -> Prims.l_True) + +val squeeze_next_block (state: t_Shake128X4) + : Prims.Pure + (t_Shake128X4 & + (t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168))) + Prims.l_True + (fun _ -> Prims.l_True) + +val squeeze_next_block_shake256 (state: t_Shake256) + : Prims.Pure (t_Shake256 & t_Array u8 (sz 136)) Prims.l_True (fun _ -> Prims.l_True) + +val squeeze_next_block_x4 (state: t_Shake256X4) + : Prims.Pure + (t_Shake256X4 & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Shake128.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Shake128.fsti new file mode 100644 index 000000000..aa229c844 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Shake128.fsti @@ -0,0 +1,72 @@ +module Libcrux_ml_dsa.Hash_functions.Shake128 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +class t_Xof (v_Self: Type0) = { + f_shake128_pre:v_OUTPUT_LENGTH: usize -> t_Slice u8 -> t_Array u8 v_OUTPUT_LENGTH -> Type0; + f_shake128_post: + v_OUTPUT_LENGTH: usize -> + t_Slice u8 -> + t_Array u8 v_OUTPUT_LENGTH -> + t_Array u8 v_OUTPUT_LENGTH + -> Type0; + f_shake128:v_OUTPUT_LENGTH: usize -> x0: t_Slice u8 -> x1: t_Array u8 v_OUTPUT_LENGTH + -> Prims.Pure (t_Array u8 v_OUTPUT_LENGTH) + (f_shake128_pre v_OUTPUT_LENGTH x0 x1) + (fun result -> f_shake128_post v_OUTPUT_LENGTH x0 x1 result) +} + +/// When sampling matrix A we always want to do 4 absorb/squeeze calls in +/// parallel. +class t_XofX4 (v_Self: Type0) = { + f_init_absorb_pre:t_Slice u8 -> t_Slice u8 -> t_Slice u8 -> t_Slice u8 -> Type0; + f_init_absorb_post:t_Slice u8 -> t_Slice u8 -> t_Slice u8 -> t_Slice u8 -> v_Self -> Type0; + f_init_absorb:x0: t_Slice u8 -> x1: t_Slice u8 -> x2: t_Slice u8 -> x3: t_Slice u8 + -> Prims.Pure v_Self + (f_init_absorb_pre x0 x1 x2 x3) + (fun result -> f_init_absorb_post x0 x1 x2 x3 result); + f_squeeze_first_five_blocks_pre: + v_Self -> + t_Array u8 (sz 840) -> + t_Array u8 (sz 840) -> + t_Array u8 (sz 840) -> + t_Array u8 (sz 840) + -> Type0; + f_squeeze_first_five_blocks_post: + v_Self -> + t_Array u8 (sz 840) -> + t_Array u8 (sz 840) -> + t_Array u8 (sz 840) -> + t_Array u8 (sz 840) -> + (v_Self & t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840)) + -> Type0; + f_squeeze_first_five_blocks: + x0: v_Self -> + x1: t_Array u8 (sz 840) -> + x2: t_Array u8 (sz 840) -> + x3: t_Array u8 (sz 840) -> + x4: t_Array u8 (sz 840) + -> Prims.Pure + (v_Self & t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840)) + (f_squeeze_first_five_blocks_pre x0 x1 x2 x3 x4) + (fun result -> f_squeeze_first_five_blocks_post x0 x1 x2 x3 x4 result); + f_squeeze_next_block_pre:v_Self -> Type0; + f_squeeze_next_block_post: + v_Self -> + (v_Self & + (t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168))) + -> Type0; + f_squeeze_next_block:x0: v_Self + -> Prims.Pure + (v_Self & + (t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168))) + (f_squeeze_next_block_pre x0) + (fun result -> f_squeeze_next_block_post x0 result) +} + +let v_BLOCK_SIZE: usize = sz 168 + +let v_FIVE_BLOCKS_SIZE: usize = v_BLOCK_SIZE *! sz 5 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Shake256.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Shake256.fsti new file mode 100644 index 000000000..bd150aa95 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Shake256.fsti @@ -0,0 +1,106 @@ +module Libcrux_ml_dsa.Hash_functions.Shake256 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +class t_Xof (v_Self: Type0) = { + f_shake256_pre:v_OUTPUT_LENGTH: usize -> t_Slice u8 -> t_Array u8 v_OUTPUT_LENGTH -> Type0; + f_shake256_post: + v_OUTPUT_LENGTH: usize -> + t_Slice u8 -> + t_Array u8 v_OUTPUT_LENGTH -> + t_Array u8 v_OUTPUT_LENGTH + -> Type0; + f_shake256:v_OUTPUT_LENGTH: usize -> x0: t_Slice u8 -> x1: t_Array u8 v_OUTPUT_LENGTH + -> Prims.Pure (t_Array u8 v_OUTPUT_LENGTH) + (f_shake256_pre v_OUTPUT_LENGTH x0 x1) + (fun result -> f_shake256_post v_OUTPUT_LENGTH x0 x1 result); + f_init_absorb_pre:t_Slice u8 -> Type0; + f_init_absorb_post:t_Slice u8 -> v_Self -> Type0; + f_init_absorb:x0: t_Slice u8 + -> Prims.Pure v_Self (f_init_absorb_pre x0) (fun result -> f_init_absorb_post x0 result); + f_squeeze_first_block_pre:v_Self -> Type0; + f_squeeze_first_block_post:v_Self -> (v_Self & t_Array u8 (sz 136)) -> Type0; + f_squeeze_first_block:x0: v_Self + -> Prims.Pure (v_Self & t_Array u8 (sz 136)) + (f_squeeze_first_block_pre x0) + (fun result -> f_squeeze_first_block_post x0 result); + f_squeeze_next_block_pre:v_Self -> Type0; + f_squeeze_next_block_post:v_Self -> (v_Self & t_Array u8 (sz 136)) -> Type0; + f_squeeze_next_block:x0: v_Self + -> Prims.Pure (v_Self & t_Array u8 (sz 136)) + (f_squeeze_next_block_pre x0) + (fun result -> f_squeeze_next_block_post x0 result) +} + +class t_XofX4 (v_Self: Type0) = { + f_init_absorb_x4_pre:t_Slice u8 -> t_Slice u8 -> t_Slice u8 -> t_Slice u8 -> Type0; + f_init_absorb_x4_post:t_Slice u8 -> t_Slice u8 -> t_Slice u8 -> t_Slice u8 -> v_Self -> Type0; + f_init_absorb_x4:x0: t_Slice u8 -> x1: t_Slice u8 -> x2: t_Slice u8 -> x3: t_Slice u8 + -> Prims.Pure v_Self + (f_init_absorb_x4_pre x0 x1 x2 x3) + (fun result -> f_init_absorb_x4_post x0 x1 x2 x3 result); + f_squeeze_first_block_x4_pre:v_Self -> Type0; + f_squeeze_first_block_x4_post: + v_Self -> + (v_Self & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + -> Type0; + f_squeeze_first_block_x4:x0: v_Self + -> Prims.Pure + (v_Self & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + (f_squeeze_first_block_x4_pre x0) + (fun result -> f_squeeze_first_block_x4_post x0 result); + f_squeeze_next_block_x4_pre:v_Self -> Type0; + f_squeeze_next_block_x4_post: + v_Self -> + (v_Self & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + -> Type0; + f_squeeze_next_block_x4:x0: v_Self + -> Prims.Pure + (v_Self & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + (f_squeeze_next_block_x4_pre x0) + (fun result -> f_squeeze_next_block_x4_post x0 result); + f_shake256_x4_pre: + v_OUT_LEN: usize -> + t_Slice u8 -> + t_Slice u8 -> + t_Slice u8 -> + t_Slice u8 -> + t_Array u8 v_OUT_LEN -> + t_Array u8 v_OUT_LEN -> + t_Array u8 v_OUT_LEN -> + t_Array u8 v_OUT_LEN + -> Type0; + f_shake256_x4_post: + v_OUT_LEN: usize -> + t_Slice u8 -> + t_Slice u8 -> + t_Slice u8 -> + t_Slice u8 -> + t_Array u8 v_OUT_LEN -> + t_Array u8 v_OUT_LEN -> + t_Array u8 v_OUT_LEN -> + t_Array u8 v_OUT_LEN -> + (t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN) + -> Type0; + f_shake256_x4: + v_OUT_LEN: usize -> + x0: t_Slice u8 -> + x1: t_Slice u8 -> + x2: t_Slice u8 -> + x3: t_Slice u8 -> + x4: t_Array u8 v_OUT_LEN -> + x5: t_Array u8 v_OUT_LEN -> + x6: t_Array u8 v_OUT_LEN -> + x7: t_Array u8 v_OUT_LEN + -> Prims.Pure + (t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN) + (f_shake256_x4_pre v_OUT_LEN x0 x1 x2 x3 x4 x5 x6 x7) + (fun result -> f_shake256_x4_post v_OUT_LEN x0 x1 x2 x3 x4 x5 x6 x7 result) +} + +let v_BLOCK_SIZE: usize = sz 136 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Simd256.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Simd256.fsti new file mode 100644 index 000000000..32174758b --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Hash_functions.Simd256.fsti @@ -0,0 +1,78 @@ +module Libcrux_ml_dsa.Hash_functions.Simd256 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// AVX2 SHAKE 128 state +/// This only implements the XofX4 API. For the single Xof, the portable +/// version is used. +val t_Shake128x4:Type0 + +/// AVX2 SHAKE 256 x4 state. +val t_Shake256x4:Type0 + +/// AVX2 SHAKE 256 state +val t_Shake256:Type0 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl:Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 t_Shake128x4 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl_1:Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof t_Shake256 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl_2:Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 t_Shake256x4 + +/// Init the state and absorb 4 blocks in parallel. +val init_absorb (input0 input1 input2 input3: t_Slice u8) + : Prims.Pure t_Shake128x4 Prims.l_True (fun _ -> Prims.l_True) + +val init_absorb_shake256 (input: t_Slice u8) + : Prims.Pure t_Shake256 Prims.l_True (fun _ -> Prims.l_True) + +val init_absorb_x4 (input0 input1 input2 input3: t_Slice u8) + : Prims.Pure t_Shake256x4 Prims.l_True (fun _ -> Prims.l_True) + +val shake256 (v_OUTPUT_LENGTH: usize) (input: t_Slice u8) (out: t_Array u8 v_OUTPUT_LENGTH) + : Prims.Pure (t_Array u8 v_OUTPUT_LENGTH) Prims.l_True (fun _ -> Prims.l_True) + +val shake256_x4 + (v_OUT_LEN: usize) + (input0 input1 input2 input3: t_Slice u8) + (out0 out1 out2 out3: t_Array u8 v_OUT_LEN) + : Prims.Pure + (t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN & t_Array u8 v_OUT_LEN) + Prims.l_True + (fun _ -> Prims.l_True) + +val squeeze_first_block_shake256 (state: t_Shake256) + : Prims.Pure (t_Shake256 & t_Array u8 (sz 136)) Prims.l_True (fun _ -> Prims.l_True) + +val squeeze_first_block_x4 (state: t_Shake256x4) + : Prims.Pure + (t_Shake256x4 & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + Prims.l_True + (fun _ -> Prims.l_True) + +val squeeze_first_five_blocks (state: t_Shake128x4) (out0 out1 out2 out3: t_Array u8 (sz 840)) + : Prims.Pure + (t_Shake128x4 & t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840)) Prims.l_True (fun _ -> Prims.l_True) + +val squeeze_next_block (state: t_Shake128x4) + : Prims.Pure + (t_Shake128x4 & + (t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168))) + Prims.l_True + (fun _ -> Prims.l_True) + +val squeeze_next_block_shake256 (state: t_Shake256) + : Prims.Pure (t_Shake256 & t_Array u8 (sz 136)) Prims.l_True (fun _ -> Prims.l_True) + +val squeeze_next_block_x4 (state: t_Shake256x4) + : Prims.Pure + (t_Shake256x4 & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Matrix.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Matrix.fst new file mode 100644 index 000000000..0f4339ffb --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Matrix.fst @@ -0,0 +1,473 @@ +module Libcrux_ml_dsa.Matrix +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let vector_times_ring_element + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (vector: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + (ring_element: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Folds.fold_enumerated_slice (vector + <: + t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let _:usize = temp_1_ in + true) + result + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let i, vector_ring_element:(usize & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + temp_1_ + in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Ntt.invert_ntt_montgomery #v_SIMDUnit + (Libcrux_ml_dsa.Ntt.ntt_multiply_montgomery #v_SIMDUnit + vector_ring_element + ring_element + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + in + result + +let add_vectors + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (lhs rhs: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + = + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_DIMENSION + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let _:usize = temp_1_ in + true) + result + (fun result i -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let i:usize = i in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Polynomial.impl__add #v_SIMDUnit + (lhs.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (rhs.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + in + result + +let compute_A_times_mask + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (v_A_as_ntt: + t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) + (mask: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + = + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Rust_primitives.Hax.Folds.fold_enumerated_slice (v_A_as_ntt + <: + t_Slice + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A)) + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let _:usize = temp_1_ in + true) + result + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let i, row:(usize & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) = + temp_1_ + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Folds.fold_enumerated_slice (row + <: + t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let _:usize = temp_1_ in + true) + result + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let j, ring_element:(usize & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + temp_1_ + in + let product:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Ntt.ntt_multiply_montgomery #v_SIMDUnit + ring_element + (Libcrux_ml_dsa.Ntt.ntt #v_SIMDUnit + (mask.[ j ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Polynomial.impl__add #v_SIMDUnit + (result.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + product + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + result) + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Ntt.invert_ntt_montgomery #v_SIMDUnit + (result.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + result) + in + result + +let compute_As1_plus_s2 + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (v_A_as_ntt: + t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) + (s1: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + (s2: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + = + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Rust_primitives.Hax.Folds.fold_enumerated_slice (v_A_as_ntt + <: + t_Slice + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A)) + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let _:usize = temp_1_ in + true) + result + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let i, row:(usize & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) = + temp_1_ + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Folds.fold_enumerated_slice (row + <: + t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let _:usize = temp_1_ in + true) + result + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let j, ring_element:(usize & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + temp_1_ + in + let product:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Ntt.ntt_multiply_montgomery #v_SIMDUnit + ring_element + (Libcrux_ml_dsa.Ntt.ntt #v_SIMDUnit + (s1.[ j ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Polynomial.impl__add #v_SIMDUnit + (result.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + product + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + result) + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Ntt.invert_ntt_montgomery #v_SIMDUnit + (result.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Polynomial.impl__add #v_SIMDUnit + (result.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (s2.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + result) + in + result + +let compute_w_approx + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (v_A_as_ntt: + t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) + (signer_response: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + (verifier_challenge_as_ntt: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (t1: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + = + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Rust_primitives.Hax.Folds.fold_enumerated_slice (v_A_as_ntt + <: + t_Slice + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A)) + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let _:usize = temp_1_ in + true) + result + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let i, row:(usize & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) = + temp_1_ + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Folds.fold_enumerated_slice (row + <: + t_Slice (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit)) + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let _:usize = temp_1_ in + true) + result + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + result + in + let j, ring_element:(usize & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + temp_1_ + in + let product:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Ntt.ntt_multiply_montgomery #v_SIMDUnit + ring_element + (Libcrux_ml_dsa.Ntt.ntt #v_SIMDUnit + (signer_response.[ j ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Polynomial.impl__add #v_SIMDUnit + (result.[ i ] + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + product + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + result) + in + let t1_shifted:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Arithmetic.shift_left_then_reduce #v_SIMDUnit + 13l + (t1.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let challenge_times_t1_shifted:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement + v_SIMDUnit = + Libcrux_ml_dsa.Ntt.ntt_multiply_montgomery #v_SIMDUnit + verifier_challenge_as_ntt + (Libcrux_ml_dsa.Ntt.ntt #v_SIMDUnit t1_shifted + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Ntt.invert_ntt_montgomery #v_SIMDUnit + (Libcrux_ml_dsa.Polynomial.impl__subtract #v_SIMDUnit + (result.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + challenge_times_t1_shifted + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + result) + in + result + +let subtract_vectors + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (lhs rhs: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + = + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_DIMENSION + (fun result temp_1_ -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let _:usize = temp_1_ in + true) + result + (fun result i -> + let result:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + result + in + let i:usize = i in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + (Libcrux_ml_dsa.Polynomial.impl__subtract #v_SIMDUnit + (lhs.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (rhs.[ i ] <: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + <: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + in + result diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Matrix.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Matrix.fsti new file mode 100644 index 000000000..7db4128e6 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Matrix.fsti @@ -0,0 +1,90 @@ +module Libcrux_ml_dsa.Matrix +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +val vector_times_ring_element + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (vector: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + (ring_element: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val add_vectors + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (lhs rhs: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Compute InvertNTT(Â ◦ ŷ) +val compute_A_times_mask + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (v_A_as_ntt: + t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) + (mask: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Compute InvertNTT(Â ◦ ŝ₁) + s₂ +val compute_As1_plus_s2 + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (v_A_as_ntt: + t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) + (s1: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + (s2: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Compute InvertNTT(Â ◦ ẑ - ĉ ◦ NTT(t₁2ᵈ)) +val compute_w_approx + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (v_A_as_ntt: + t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) + (signer_response: + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + (verifier_challenge_as_ntt: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + (t1: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) + Prims.l_True + (fun _ -> Prims.l_True) + +val subtract_vectors + (#v_SIMDUnit: Type0) + (v_DIMENSION: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (lhs rhs: t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Avx2.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Avx2.fst new file mode 100644 index 000000000..e68b8fe9b --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Avx2.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_44_.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 2560) & t_Array u8 (sz 1312)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.generate_key_pair (sz 4) + (sz 4) + (sz 2) + (sz 96) + (sz 2560) + (sz 1312) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1312) (sz 2560) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.sign (sz 4) (sz 4) (sz 2) (sz 96) (sz 17) 95232l + (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) (sz 576) (sz 2560) (sz 2420) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.sign_pre_hashed_shake128 (sz 4) (sz 4) (sz 2) + (sz 96) (sz 17) 95232l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) (sz 576) (sz 2560) (sz 2420) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.verify (sz 4) (sz 4) (sz 2420) (sz 1312) (sz 17) + (sz 576) 95232l 78l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.verify_pre_hashed_shake128 (sz 4) (sz 4) + (sz 2420) (sz 1312) (sz 17) (sz 576) 95232l 78l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Avx2.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Avx2.fsti new file mode 100644 index 000000000..2cc5f13c7 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Avx2.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_44_.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-44 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1312) (sz 2560)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-44 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-44 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-44 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-44 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Neon.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Neon.fst new file mode 100644 index 000000000..f27fbeff4 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Neon.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_44_.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 2560) & t_Array u8 (sz 1312)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.generate_key_pair (sz 4) + (sz 4) + (sz 2) + (sz 96) + (sz 2560) + (sz 1312) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1312) (sz 2560) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.sign (sz 4) (sz 4) (sz 2) (sz 96) (sz 17) 95232l + (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) (sz 576) (sz 2560) (sz 2420) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.sign_pre_hashed_shake128 (sz 4) (sz 4) (sz 2) + (sz 96) (sz 17) 95232l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) (sz 576) (sz 2560) (sz 2420) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.verify (sz 4) (sz 4) (sz 2420) (sz 1312) (sz 17) + (sz 576) 95232l 78l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.verify_pre_hashed_shake128 (sz 4) (sz 4) + (sz 2420) (sz 1312) (sz 17) (sz 576) 95232l 78l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Neon.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Neon.fsti new file mode 100644 index 000000000..58227663f --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Neon.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_44_.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-44 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1312) (sz 2560)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-44 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-44 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-44 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-44 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Portable.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Portable.fst new file mode 100644 index 000000000..b28affb1d --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Portable.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_44_.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 2560) & t_Array u8 (sz 1312)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.generate_key_pair (sz 4) + (sz 4) + (sz 2) + (sz 96) + (sz 2560) + (sz 1312) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1312) (sz 2560) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.sign (sz 4) (sz 4) (sz 2) (sz 96) (sz 17) + 95232l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) (sz 576) (sz 2560) (sz 2420) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.sign_pre_hashed_shake128 (sz 4) (sz 4) + (sz 2) (sz 96) (sz 17) 95232l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) (sz 576) (sz 2560) + (sz 2420) signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.verify (sz 4) (sz 4) (sz 2420) (sz 1312) + (sz 17) (sz 576) 95232l 78l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.verify_pre_hashed_shake128 (sz 4) (sz 4) + (sz 2420) (sz 1312) (sz 17) (sz 576) 95232l 78l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Portable.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Portable.fsti new file mode 100644 index 000000000..1e6653b8a --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.Portable.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_44_.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-44 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1312) (sz 2560)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-44 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-44 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-44 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-44 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.fst new file mode 100644 index 000000000..4eff956f5 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_44_ +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 2560) & t_Array u8 (sz 1312)) = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.generate_key_pair (sz 4) + (sz 4) + (sz 2) + (sz 96) + (sz 2560) + (sz 1312) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1312) (sz 2560) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.sign (sz 4) (sz 4) (sz 2) (sz 96) (sz 17) 95232l + (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) (sz 576) (sz 2560) (sz 2420) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.sign_pre_hashed_shake128 (sz 4) (sz 4) (sz 2) (sz 96) + (sz 17) 95232l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) (sz 576) (sz 2560) (sz 2420) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.verify (sz 4) (sz 4) (sz 2420) (sz 1312) (sz 17) + (sz 576) 95232l 78l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.verify_pre_hashed_shake128 (sz 4) (sz 4) (sz 2420) + (sz 1312) (sz 17) (sz 576) 95232l 78l (sz 192) (sz 768) (sz 32) (sz 39) (sz 80) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.fsti new file mode 100644 index 000000000..a677e8e9a --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_44_.fsti @@ -0,0 +1,143 @@ +module Libcrux_ml_dsa.Ml_dsa_44_ +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let v_BITS_PER_COMMITMENT_COEFFICIENT: usize = sz 6 + +let v_BITS_PER_ERROR_COEFFICIENT: usize = sz 3 + +let v_BITS_PER_GAMMA1_COEFFICIENT: usize = sz 18 + +let v_COLUMNS_IN_A: usize = sz 4 + +let v_COMMITMENT_HASH_SIZE: usize = sz 32 + +let v_COMMITMENT_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_COMMITMENT_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + <: + usize) /! + sz 8 + +let v_ERROR_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_ERROR_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) /! + sz 8 + +let v_ETA: usize = sz 2 + +let v_GAMMA1_EXPONENT: usize = sz 17 + +let v_GAMMA1_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_GAMMA1_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize + ) /! + sz 8 + +let v_GAMMA2: i32 = (Libcrux_ml_dsa.Constants.v_FIELD_MODULUS -! 1l <: i32) /! 88l + +let v_MAX_ONES_IN_HINT: usize = sz 80 + +let v_ONES_IN_VERIFIER_CHALLENGE: usize = sz 39 + +let v_BETA: i32 = cast (v_ONES_IN_VERIFIER_CHALLENGE *! v_ETA <: usize) <: i32 + +let v_ROWS_IN_A: usize = sz 4 + +let v_COMMITMENT_VECTOR_SIZE: usize = v_COMMITMENT_RING_ELEMENT_SIZE *! v_ROWS_IN_A + +let v_SIGNATURE_SIZE: usize = + ((v_COMMITMENT_HASH_SIZE +! (v_COLUMNS_IN_A *! v_GAMMA1_RING_ELEMENT_SIZE <: usize) <: usize) +! + v_MAX_ONES_IN_HINT + <: + usize) +! + v_ROWS_IN_A + +let v_SIGNING_KEY_SIZE: usize = + (((Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE +! Libcrux_ml_dsa.Constants.v_SEED_FOR_SIGNING_SIZE + <: + usize) +! + Libcrux_ml_dsa.Constants.v_BYTES_FOR_VERIFICATION_KEY_HASH + <: + usize) +! + ((v_ROWS_IN_A +! v_COLUMNS_IN_A <: usize) *! v_ERROR_RING_ELEMENT_SIZE <: usize) + <: + usize) +! + (v_ROWS_IN_A *! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T0S_SIZE <: usize) + +let v_VERIFICATION_KEY_SIZE: usize = + Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE +! + (((Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_ROWS_IN_A <: usize) *! + (Libcrux_ml_dsa.Constants.v_FIELD_MODULUS_MINUS_ONE_BIT_LENGTH -! + Libcrux_ml_dsa.Constants.v_BITS_IN_LOWER_PART_OF_T + <: + usize) + <: + usize) /! + sz 8 + <: + usize) + +/// Generate an ML-DSA 44 Key Pair +/// Generate an ML-DSA key pair. The input is a byte array of size +/// [`KEY_GENERATION_RANDOMNESS_SIZE`]. +/// This function returns an [`MLDSA44KeyPair`]. +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1312) (sz 2560)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sign with ML-DSA 44 +/// Sign a `message` with the ML-DSA `signing_key`. +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// This function returns an [`MLDSA44Signature`]. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Sign with HashML-DSA 44, with a SHAKE128 pre-hashing +/// Sign a digest of `message` derived using `pre_hash` with the +/// ML-DSA `signing_key`. +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// This function returns an [`MLDSA44Signature`]. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 2560)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-44 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// Returns `Ok` when the `signature` is valid for the `message` and +/// `verification_key`, and a [`VerificationError`] otherwise. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-44 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// Returns `Ok` when the `signature` is valid for the `message` and +/// `verification_key`, and a [`VerificationError`] otherwise. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1312)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 2420)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Avx2.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Avx2.fst new file mode 100644 index 000000000..4dcf80489 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Avx2.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_65_.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 4032) & t_Array u8 (sz 1952)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.generate_key_pair (sz 6) + (sz 5) + (sz 4) + (sz 128) + (sz 4032) + (sz 1952) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1952) (sz 4032) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.sign (sz 6) (sz 5) (sz 4) (sz 128) (sz 19) + 261888l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) (sz 640) (sz 4032) (sz 3309) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.sign_pre_hashed_shake128 (sz 6) (sz 5) (sz 4) + (sz 128) (sz 19) 261888l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) (sz 640) (sz 4032) (sz 3309) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.verify (sz 6) (sz 5) (sz 3309) (sz 1952) (sz 19) + (sz 640) 261888l 196l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.verify_pre_hashed_shake128 (sz 6) (sz 5) + (sz 3309) (sz 1952) (sz 19) (sz 640) 261888l 196l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Avx2.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Avx2.fsti new file mode 100644 index 000000000..bfcb87df8 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Avx2.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_65_.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-65 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1952) (sz 4032)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-65 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-65 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-65 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-65 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Neon.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Neon.fst new file mode 100644 index 000000000..b54a04df2 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Neon.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_65_.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 4032) & t_Array u8 (sz 1952)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.generate_key_pair (sz 6) + (sz 5) + (sz 4) + (sz 128) + (sz 4032) + (sz 1952) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1952) (sz 4032) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.sign (sz 6) (sz 5) (sz 4) (sz 128) (sz 19) + 261888l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) (sz 640) (sz 4032) (sz 3309) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.sign_pre_hashed_shake128 (sz 6) (sz 5) (sz 4) + (sz 128) (sz 19) 261888l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) (sz 640) (sz 4032) (sz 3309) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.verify (sz 6) (sz 5) (sz 3309) (sz 1952) (sz 19) + (sz 640) 261888l 196l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.verify_pre_hashed_shake128 (sz 6) (sz 5) + (sz 3309) (sz 1952) (sz 19) (sz 640) 261888l 196l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Neon.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Neon.fsti new file mode 100644 index 000000000..ff39c5e48 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Neon.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_65_.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-65 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1952) (sz 4032)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-65 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-65 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-65 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-65 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Portable.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Portable.fst new file mode 100644 index 000000000..eaf1e627f --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Portable.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_65_.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 4032) & t_Array u8 (sz 1952)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.generate_key_pair (sz 6) + (sz 5) + (sz 4) + (sz 128) + (sz 4032) + (sz 1952) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1952) (sz 4032) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.sign (sz 6) (sz 5) (sz 4) (sz 128) (sz 19) + 261888l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) (sz 640) (sz 4032) (sz 3309) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.sign_pre_hashed_shake128 (sz 6) (sz 5) + (sz 4) (sz 128) (sz 19) 261888l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) (sz 640) (sz 4032) + (sz 3309) signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.verify (sz 6) (sz 5) (sz 3309) (sz 1952) + (sz 19) (sz 640) 261888l 196l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.verify_pre_hashed_shake128 (sz 6) (sz 5) + (sz 3309) (sz 1952) (sz 19) (sz 640) 261888l 196l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Portable.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Portable.fsti new file mode 100644 index 000000000..7568a9a1c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.Portable.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_65_.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-65 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1952) (sz 4032)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-65 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-65 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-65 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-65 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.fst new file mode 100644 index 000000000..d75500055 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_65_ +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 4032) & t_Array u8 (sz 1952)) = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.generate_key_pair (sz 6) + (sz 5) + (sz 4) + (sz 128) + (sz 4032) + (sz 1952) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1952) (sz 4032) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.sign (sz 6) (sz 5) (sz 4) (sz 128) (sz 19) 261888l + (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) (sz 640) (sz 4032) (sz 3309) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.sign_pre_hashed_shake128 (sz 6) (sz 5) (sz 4) (sz 128) + (sz 19) 261888l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) (sz 640) (sz 4032) (sz 3309) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.verify (sz 6) (sz 5) (sz 3309) (sz 1952) (sz 19) + (sz 640) 261888l 196l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.verify_pre_hashed_shake128 (sz 6) (sz 5) (sz 3309) + (sz 1952) (sz 19) (sz 640) 261888l 196l (sz 128) (sz 768) (sz 48) (sz 49) (sz 55) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.fsti new file mode 100644 index 000000000..47735a500 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_65_.fsti @@ -0,0 +1,143 @@ +module Libcrux_ml_dsa.Ml_dsa_65_ +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let v_BITS_PER_COMMITMENT_COEFFICIENT: usize = sz 4 + +let v_BITS_PER_ERROR_COEFFICIENT: usize = sz 4 + +let v_BITS_PER_GAMMA1_COEFFICIENT: usize = sz 20 + +let v_COLUMNS_IN_A: usize = sz 5 + +let v_COMMITMENT_HASH_SIZE: usize = sz 48 + +let v_COMMITMENT_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_COMMITMENT_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + <: + usize) /! + sz 8 + +let v_ERROR_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_ERROR_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) /! + sz 8 + +let v_ETA: usize = sz 4 + +let v_GAMMA1_EXPONENT: usize = sz 19 + +let v_GAMMA1_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_GAMMA1_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize + ) /! + sz 8 + +let v_GAMMA2: i32 = (Libcrux_ml_dsa.Constants.v_FIELD_MODULUS -! 1l <: i32) /! 32l + +let v_MAX_ONES_IN_HINT: usize = sz 55 + +let v_ONES_IN_VERIFIER_CHALLENGE: usize = sz 49 + +let v_BETA: i32 = cast (v_ONES_IN_VERIFIER_CHALLENGE *! v_ETA <: usize) <: i32 + +let v_ROWS_IN_A: usize = sz 6 + +let v_COMMITMENT_VECTOR_SIZE: usize = v_COMMITMENT_RING_ELEMENT_SIZE *! v_ROWS_IN_A + +let v_SIGNATURE_SIZE: usize = + ((v_COMMITMENT_HASH_SIZE +! (v_COLUMNS_IN_A *! v_GAMMA1_RING_ELEMENT_SIZE <: usize) <: usize) +! + v_MAX_ONES_IN_HINT + <: + usize) +! + v_ROWS_IN_A + +let v_SIGNING_KEY_SIZE: usize = + (((Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE +! Libcrux_ml_dsa.Constants.v_SEED_FOR_SIGNING_SIZE + <: + usize) +! + Libcrux_ml_dsa.Constants.v_BYTES_FOR_VERIFICATION_KEY_HASH + <: + usize) +! + ((v_ROWS_IN_A +! v_COLUMNS_IN_A <: usize) *! v_ERROR_RING_ELEMENT_SIZE <: usize) + <: + usize) +! + (v_ROWS_IN_A *! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T0S_SIZE <: usize) + +let v_VERIFICATION_KEY_SIZE: usize = + Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE +! + (((Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_ROWS_IN_A <: usize) *! + (Libcrux_ml_dsa.Constants.v_FIELD_MODULUS_MINUS_ONE_BIT_LENGTH -! + Libcrux_ml_dsa.Constants.v_BITS_IN_LOWER_PART_OF_T + <: + usize) + <: + usize) /! + sz 8 + <: + usize) + +/// Generate an ML-DSA 65 Key Pair +/// Generate an ML-DSA key pair. The input is a byte array of size +/// [`KEY_GENERATION_RANDOMNESS_SIZE`]. +/// This function returns an [`MLDSA65KeyPair`]. +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 1952) (sz 4032)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sign with ML-DSA 65 +/// Sign a `message` with the ML-DSA `signing_key`. +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// This function returns an [`MLDSA65Signature`]. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Sign with HashML-DSA 65, with a SHAKE128 pre-hashing +/// Sign a digest of `message` derived using `pre_hash` with the +/// ML-DSA `signing_key`. +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// This function returns an [`MLDSA65Signature`]. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4032)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-65 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// Returns `Ok` when the `signature` is valid for the `message` and +/// `verification_key`, and a [`VerificationError`] otherwise. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-65 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// Returns `Ok` when the `signature` is valid for the `message` and +/// `verification_key`, and a [`VerificationError`] otherwise. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 1952)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 3309)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Avx2.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Avx2.fst new file mode 100644 index 000000000..27eb5b514 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Avx2.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_87_.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 4896) & t_Array u8 (sz 2592)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.generate_key_pair (sz 8) + (sz 7) + (sz 2) + (sz 96) + (sz 4896) + (sz 2592) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 2592) (sz 4896) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.sign (sz 8) (sz 7) (sz 2) (sz 96) (sz 19) + 261888l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) (sz 640) (sz 4896) (sz 4627) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.sign_pre_hashed_shake128 (sz 8) (sz 7) (sz 2) + (sz 96) (sz 19) 261888l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) (sz 640) (sz 4896) (sz 4627) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.verify (sz 8) (sz 7) (sz 4627) (sz 2592) (sz 19) + (sz 640) 261888l 120l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.verify_pre_hashed_shake128 (sz 8) (sz 7) + (sz 4627) (sz 2592) (sz 19) (sz 640) 261888l 120l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Avx2.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Avx2.fsti new file mode 100644 index 000000000..2b2ba04ee --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Avx2.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_87_.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-87 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 2592) (sz 4896)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-87 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-87 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-87 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-87 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Neon.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Neon.fst new file mode 100644 index 000000000..e89d61679 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Neon.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_87_.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 4896) & t_Array u8 (sz 2592)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.generate_key_pair (sz 8) + (sz 7) + (sz 2) + (sz 96) + (sz 4896) + (sz 2592) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 2592) (sz 4896) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.sign (sz 8) (sz 7) (sz 2) (sz 96) (sz 19) + 261888l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) (sz 640) (sz 4896) (sz 4627) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.sign_pre_hashed_shake128 (sz 8) (sz 7) (sz 2) + (sz 96) (sz 19) 261888l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) (sz 640) (sz 4896) (sz 4627) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.verify (sz 8) (sz 7) (sz 4627) (sz 2592) (sz 19) + (sz 640) 261888l 120l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.verify_pre_hashed_shake128 (sz 8) (sz 7) + (sz 4627) (sz 2592) (sz 19) (sz 640) 261888l 120l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Neon.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Neon.fsti new file mode 100644 index 000000000..499342491 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Neon.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_87_.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-87 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 2592) (sz 4896)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-87 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-87 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-87 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-87 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Portable.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Portable.fst new file mode 100644 index 000000000..8ff301da4 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Portable.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_87_.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 4896) & t_Array u8 (sz 2592)) = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.generate_key_pair (sz 8) + (sz 7) + (sz 2) + (sz 96) + (sz 4896) + (sz 2592) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 2592) (sz 4896) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.sign (sz 8) (sz 7) (sz 2) (sz 96) (sz 19) + 261888l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) (sz 640) (sz 4896) (sz 4627) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.sign_pre_hashed_shake128 (sz 8) (sz 7) + (sz 2) (sz 96) (sz 19) 261888l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) (sz 640) (sz 4896) + (sz 4627) signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.verify (sz 8) (sz 7) (sz 4627) (sz 2592) + (sz 19) (sz 640) 261888l 120l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.verify_pre_hashed_shake128 (sz 8) (sz 7) + (sz 4627) (sz 2592) (sz 19) (sz 640) 261888l 120l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Portable.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Portable.fsti new file mode 100644 index 000000000..5825b758b --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.Portable.fsti @@ -0,0 +1,58 @@ +module Libcrux_ml_dsa.Ml_dsa_87_.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate an ML-DSA-87 Key Pair +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 2592) (sz 4896)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate an ML-DSA-87 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate a HashML-DSA-87 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-87 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-87 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.fst new file mode 100644 index 000000000..7628dbe10 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.fst @@ -0,0 +1,65 @@ +module Libcrux_ml_dsa.Ml_dsa_87_ +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair (randomness: t_Array u8 (sz 32)) = + let signing_key, verification_key:(t_Array u8 (sz 4896) & t_Array u8 (sz 2592)) = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.generate_key_pair (sz 8) + (sz 7) + (sz 2) + (sz 96) + (sz 4896) + (sz 2592) + randomness + in + { + Libcrux_ml_dsa.Types.f_signing_key + = + Libcrux_ml_dsa.Types.MLDSASigningKey signing_key + <: + Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896); + Libcrux_ml_dsa.Types.f_verification_key + = + Libcrux_ml_dsa.Types.MLDSAVerificationKey verification_key + <: + Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592) + } + <: + Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 2592) (sz 4896) + +let sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.sign (sz 8) (sz 7) (sz 2) (sz 96) (sz 19) 261888l + (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) (sz 640) (sz 4896) (sz 4627) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.sign_pre_hashed_shake128 (sz 8) (sz 7) (sz 2) (sz 96) + (sz 19) 261888l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) (sz 640) (sz 4896) (sz 4627) + signing_key.Libcrux_ml_dsa.Types._0 message context randomness + +let verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.verify (sz 8) (sz 7) (sz 4627) (sz 2592) (sz 19) + (sz 640) 261888l 120l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 + +let verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.verify_pre_hashed_shake128 (sz 8) (sz 7) (sz 4627) + (sz 2592) (sz 19) (sz 640) 261888l 120l (sz 128) (sz 1024) (sz 64) (sz 60) (sz 75) + verification_key.Libcrux_ml_dsa.Types._0 message context signature.Libcrux_ml_dsa.Types._0 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.fsti new file mode 100644 index 000000000..f5eb82a25 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_87_.fsti @@ -0,0 +1,143 @@ +module Libcrux_ml_dsa.Ml_dsa_87_ +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let v_BITS_PER_COMMITMENT_COEFFICIENT: usize = sz 4 + +let v_BITS_PER_ERROR_COEFFICIENT: usize = sz 3 + +let v_BITS_PER_GAMMA1_COEFFICIENT: usize = sz 20 + +let v_COLUMNS_IN_A: usize = sz 7 + +let v_COMMITMENT_HASH_SIZE: usize = sz 64 + +let v_COMMITMENT_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_COMMITMENT_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + <: + usize) /! + sz 8 + +let v_ERROR_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_ERROR_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize) /! + sz 8 + +let v_ETA: usize = sz 2 + +let v_GAMMA1_EXPONENT: usize = sz 19 + +let v_GAMMA1_RING_ELEMENT_SIZE: usize = + (v_BITS_PER_GAMMA1_COEFFICIENT *! Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT <: usize + ) /! + sz 8 + +let v_GAMMA2: i32 = (Libcrux_ml_dsa.Constants.v_FIELD_MODULUS -! 1l <: i32) /! 32l + +let v_MAX_ONES_IN_HINT: usize = sz 75 + +let v_ONES_IN_VERIFIER_CHALLENGE: usize = sz 60 + +let v_BETA: i32 = cast (v_ONES_IN_VERIFIER_CHALLENGE *! v_ETA <: usize) <: i32 + +let v_ROWS_IN_A: usize = sz 8 + +let v_COMMITMENT_VECTOR_SIZE: usize = v_COMMITMENT_RING_ELEMENT_SIZE *! v_ROWS_IN_A + +let v_SIGNATURE_SIZE: usize = + ((v_COMMITMENT_HASH_SIZE +! (v_COLUMNS_IN_A *! v_GAMMA1_RING_ELEMENT_SIZE <: usize) <: usize) +! + v_MAX_ONES_IN_HINT + <: + usize) +! + v_ROWS_IN_A + +let v_SIGNING_KEY_SIZE: usize = + (((Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE +! Libcrux_ml_dsa.Constants.v_SEED_FOR_SIGNING_SIZE + <: + usize) +! + Libcrux_ml_dsa.Constants.v_BYTES_FOR_VERIFICATION_KEY_HASH + <: + usize) +! + ((v_ROWS_IN_A +! v_COLUMNS_IN_A <: usize) *! v_ERROR_RING_ELEMENT_SIZE <: usize) + <: + usize) +! + (v_ROWS_IN_A *! Libcrux_ml_dsa.Constants.v_RING_ELEMENT_OF_T0S_SIZE <: usize) + +let v_VERIFICATION_KEY_SIZE: usize = + Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE +! + (((Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_ROWS_IN_A <: usize) *! + (Libcrux_ml_dsa.Constants.v_FIELD_MODULUS_MINUS_ONE_BIT_LENGTH -! + Libcrux_ml_dsa.Constants.v_BITS_IN_LOWER_PART_OF_T + <: + usize) + <: + usize) /! + sz 8 + <: + usize) + +/// Generate an ML-DSA 87 Key Pair +/// Generate an ML-DSA key pair. The input is a byte array of size +/// [`KEY_GENERATION_RANDOMNESS_SIZE`]. +/// This function returns an [`MLDSA87KeyPair`]. +val generate_key_pair (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_dsa.Types.t_MLDSAKeyPair (sz 2592) (sz 4896)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sign with ML-DSA 87 +/// Sign a `message` with the ML-DSA `signing_key`. +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// This function returns an [`MLDSA87Signature`]. +val sign + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Sign with HashML-DSA 87, with a SHAKE128 pre-hashing +/// Sign a digest of `message` derived using `pre_hash` with the +/// ML-DSA `signing_key`. +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// This function returns an [`MLDSA87Signature`]. +val sign_pre_hashed_shake128 + (signing_key: Libcrux_ml_dsa.Types.t_MLDSASigningKey (sz 4896)) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify an ML-DSA-87 Signature +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// Returns `Ok` when the `signature` is valid for the `message` and +/// `verification_key`, and a [`VerificationError`] otherwise. +val verify + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify a HashML-DSA-87 Signature, with a SHAKE128 pre-hashing +/// The parameter `context` is used for domain separation +/// and is a byte string of length at most 255 bytes. It +/// may also be empty. +/// Returns `Ok` when the `signature` is valid for the `message` and +/// `verification_key`, and a [`VerificationError`] otherwise. +val verify_pre_hashed_shake128 + (verification_key: Libcrux_ml_dsa.Types.t_MLDSAVerificationKey (sz 2592)) + (message context: t_Slice u8) + (signature: Libcrux_ml_dsa.Types.t_MLDSASignature (sz 4627)) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.fst new file mode 100644 index 000000000..db410963c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.fst @@ -0,0 +1,97 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Hash_functions.Simd256 in + let open Libcrux_ml_dsa.Pre_hash in + let open Libcrux_ml_dsa.Simd.Avx2 in + let open Libcrux_ml_dsa.Simd.Traits in + () + +let generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.generate_key_pair #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake256x4 v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE randomness + +let sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.sign #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake256x4 v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE signing_key message context + randomness + +let sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.sign_pre_hashed #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake256x4 #Libcrux_ml_dsa.Pre_hash.t_SHAKE128_PH + (sz 256) v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE + v_SIGNATURE_SIZE signing_key message context randomness + +let verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + = + Libcrux_ml_dsa.Ml_dsa_generic.verify #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake256 v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE + v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT verification_key message context signature + +let verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + = + Libcrux_ml_dsa.Ml_dsa_generic.verify_pre_hashed #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Simd256.t_Shake256 #Libcrux_ml_dsa.Pre_hash.t_SHAKE128_PH + (sz 256) v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + verification_key message context signature diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.fsti new file mode 100644 index 000000000..f5492bbb9 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.fsti @@ -0,0 +1,78 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Hash_functions.Simd256 in + let open Libcrux_ml_dsa.Pre_hash in + let open Libcrux_ml_dsa.Simd.Avx2 in + let open Libcrux_ml_dsa.Simd.Traits in + () + +/// Generate key pair. +val generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (t_Array u8 v_SIGNING_KEY_SIZE & t_Array u8 v_VERIFICATION_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sign. +val sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Sign (pre-hashed). +val sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify. +val verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify (pre-hashed with SHAKE-128). +val verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.fst new file mode 100644 index 000000000..42e4c6671 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.fst @@ -0,0 +1,78 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.generate_key_pair v_ROWS_IN_A + v_COLUMNS_IN_A + v_ETA + v_ERROR_RING_ELEMENT_SIZE + v_SIGNING_KEY_SIZE + v_VERIFICATION_KEY_SIZE + randomness + +let sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.sign v_ROWS_IN_A v_COLUMNS_IN_A + v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE signing_key message context + randomness + +let sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.sign_pre_hashed_shake128 v_ROWS_IN_A + v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE + v_SIGNATURE_SIZE signing_key message context randomness + +let verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.verify v_ROWS_IN_A v_COLUMNS_IN_A + v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 + v_BETA v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT verification_key message context signature + +let verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + = + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.Avx2_feature.verify_pre_hashed_shake128 v_ROWS_IN_A + v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + verification_key message context signature diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.fsti new file mode 100644 index 000000000..3763fcb0a --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.fsti @@ -0,0 +1,67 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Generate key pair. +val generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (t_Array u8 v_SIGNING_KEY_SIZE & t_Array u8 v_VERIFICATION_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sign. +val sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Sign (pre-hashed). +val sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify. +val verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify (pre-hashed with SHAKE-128). +val verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.fst new file mode 100644 index 000000000..9e12c192d --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.fst @@ -0,0 +1,98 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Neon in + let open Libcrux_ml_dsa.Hash_functions.Portable in + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Pre_hash in + let open Libcrux_ml_dsa.Simd.Portable in + let open Libcrux_ml_dsa.Simd.Traits in + () + +let generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.generate_key_pair #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Neon.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Neon.t_Shake256x4 v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE randomness + +let sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.sign #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Neon.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Neon.t_Shake256x4 v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE signing_key message context + randomness + +let sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.sign_pre_hashed #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Neon.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Neon.t_Shake256x4 #Libcrux_ml_dsa.Pre_hash.t_SHAKE128_PH (sz 256) + v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE + v_SIGNATURE_SIZE signing_key message context randomness + +let verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + = + Libcrux_ml_dsa.Ml_dsa_generic.verify #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Neon.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE + v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT verification_key message context signature + +let verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + = + Libcrux_ml_dsa.Ml_dsa_generic.verify_pre_hashed #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Neon.t_Shake128x4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 #Libcrux_ml_dsa.Pre_hash.t_SHAKE128_PH + (sz 256) v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + verification_key message context signature diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.fsti new file mode 100644 index 000000000..93c40dc34 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.fsti @@ -0,0 +1,79 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Neon in + let open Libcrux_ml_dsa.Hash_functions.Portable in + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Pre_hash in + let open Libcrux_ml_dsa.Simd.Portable in + let open Libcrux_ml_dsa.Simd.Traits in + () + +/// Generate key pair. +val generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (t_Array u8 v_SIGNING_KEY_SIZE & t_Array u8 v_VERIFICATION_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sign. +val sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Sign (pre-hashed). +val sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify. +val verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify (pre-hashed with SHAKE-128). +val verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.fst new file mode 100644 index 000000000..3ed0bdc8f --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.fst @@ -0,0 +1,97 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Portable in + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Pre_hash in + let open Libcrux_ml_dsa.Simd.Portable in + let open Libcrux_ml_dsa.Simd.Traits in + () + +let generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.generate_key_pair #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake128X4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256X4 v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE randomness + +let sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.sign #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake128X4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256X4 v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE signing_key message context + randomness + +let sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_dsa.Ml_dsa_generic.sign_pre_hashed #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake128X4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256X4 #Libcrux_ml_dsa.Pre_hash.t_SHAKE128_PH + (sz 256) v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE + v_SIGNATURE_SIZE signing_key message context randomness + +let verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + = + Libcrux_ml_dsa.Ml_dsa_generic.verify #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake128X4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE + v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT verification_key message context signature + +let verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + = + Libcrux_ml_dsa.Ml_dsa_generic.verify_pre_hashed #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake128X4 + #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256 #Libcrux_ml_dsa.Pre_hash.t_SHAKE128_PH + (sz 256) v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + verification_key message context signature diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.fsti new file mode 100644 index 000000000..1e4399d64 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.fsti @@ -0,0 +1,78 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Portable in + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Pre_hash in + let open Libcrux_ml_dsa.Simd.Portable in + let open Libcrux_ml_dsa.Simd.Traits in + () + +/// Generate key pair. +val generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (t_Array u8 v_SIGNING_KEY_SIZE & t_Array u8 v_VERIFICATION_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Sign. +val sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Sign (pre-hashed). +val sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// Verify. +val verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Verify (pre-hashed with SHAKE-128). +val verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.fst new file mode 100644 index 000000000..69d507f61 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.fst @@ -0,0 +1,163 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.generate_key_pair v_ROWS_IN_A + v_COLUMNS_IN_A + v_ETA + v_ERROR_RING_ELEMENT_SIZE + v_SIGNING_KEY_SIZE + v_VERIFICATION_KEY_SIZE + randomness + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.generate_key_pair v_ROWS_IN_A + v_COLUMNS_IN_A + v_ETA + v_ERROR_RING_ELEMENT_SIZE + v_SIGNING_KEY_SIZE + v_VERIFICATION_KEY_SIZE + randomness + else + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.generate_key_pair v_ROWS_IN_A + v_COLUMNS_IN_A + v_ETA + v_ERROR_RING_ELEMENT_SIZE + v_SIGNING_KEY_SIZE + v_VERIFICATION_KEY_SIZE + randomness + +let sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.sign v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE + v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE signing_key + message context randomness + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.sign v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE + v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE + signing_key message context randomness + else + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.sign v_ROWS_IN_A v_COLUMNS_IN_A v_ETA + v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE + v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE + signing_key message context randomness + +let sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.sign_pre_hashed_shake128 v_ROWS_IN_A + v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE + v_SIGNATURE_SIZE signing_key message context randomness + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.sign_pre_hashed_shake128 v_ROWS_IN_A + v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE + v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE signing_key message context randomness + else + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.sign_pre_hashed_shake128 v_ROWS_IN_A + v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 + v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE + v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE signing_key message context randomness + +let verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.verify v_ROWS_IN_A v_COLUMNS_IN_A + v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 + v_BETA v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT verification_key_serialized message context + signature_serialized + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.verify v_ROWS_IN_A v_COLUMNS_IN_A + v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE + v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE + v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + verification_key_serialized message context signature_serialized + else + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.verify v_ROWS_IN_A v_COLUMNS_IN_A + v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE + v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE + v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT + verification_key_serialized message context signature_serialized + +let verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + = + if Libcrux_platform.Platform.simd256_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Avx2.verify_pre_hashed_shake128 v_ROWS_IN_A + v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE + v_MAX_ONES_IN_HINT verification_key_serialized message context signature_serialized + else + if Libcrux_platform.Platform.simd128_support () + then + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Neon.verify_pre_hashed_shake128 v_ROWS_IN_A + v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE + v_MAX_ONES_IN_HINT verification_key_serialized message context signature_serialized + else + Libcrux_ml_dsa.Ml_dsa_generic.Instantiations.Portable.verify_pre_hashed_shake128 v_ROWS_IN_A + v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 v_BETA v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE + v_MAX_ONES_IN_HINT verification_key_serialized message context signature_serialized diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.fsti new file mode 100644 index 000000000..c617ed3c3 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing.fsti @@ -0,0 +1,62 @@ +module Libcrux_ml_dsa.Ml_dsa_generic.Multiplexing +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +val generate_key_pair + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (t_Array u8 v_SIGNING_KEY_SIZE & t_Array u8 v_VERIFICATION_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) + +val sign + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +val sign_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +val verify + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +val verify_pre_hashed_shake128 + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.fst new file mode 100644 index 000000000..878dd2cb5 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.fst @@ -0,0 +1,958 @@ +module Libcrux_ml_dsa.Ml_dsa_generic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Pre_hash in + let open Libcrux_ml_dsa.Simd.Traits in + () + +let derive_message_representative + (verification_key_hash: t_Array u8 (sz 64)) + (domain_separation_context: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) + (message: t_Slice u8) + (message_representative: t_Array u8 (sz 64)) + = + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_init () + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake + (verification_key_hash <: t_Slice u8) + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + match domain_separation_context with + | Core.Option.Option_Some domain_separation_context -> + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake + ((let list = + [ + cast (Core.Option.impl__is_some #(t_Array u8 (sz 11)) + (Libcrux_ml_dsa.Pre_hash.impl_1__pre_hash_oid domain_separation_context + <: + Core.Option.t_Option (t_Array u8 (sz 11))) + <: + bool) + <: + u8 + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); + Rust_primitives.Hax.array_of_list 1 list) + <: + t_Slice u8) + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake + ((let list = + [ + cast (Core.Slice.impl__len #u8 + (Libcrux_ml_dsa.Pre_hash.impl_1__context domain_separation_context + <: + t_Slice u8) + <: + usize) + <: + u8 + ] + in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); + Rust_primitives.Hax.array_of_list 1 list) + <: + t_Slice u8) + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake + (Libcrux_ml_dsa.Pre_hash.impl_1__context domain_separation_context <: t_Slice u8) + in + (match Libcrux_ml_dsa.Pre_hash.impl_1__pre_hash_oid domain_separation_context with + | Core.Option.Option_Some pre_hash_oid -> + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake (pre_hash_oid <: t_Slice u8) + | _ -> shake) + | _ -> shake + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb_final shake message + in + let tmp0, tmp1:(Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze & t_Array u8 (sz 64)) = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_squeeze shake message_representative + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze = tmp0 in + let message_representative:t_Array u8 (sz 64) = tmp1 in + let _:Prims.unit = () in + message_representative + +let sign_internal + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i5: + Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i6: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i7: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message: t_Slice u8) + (domain_separation_context: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) + (randomness: t_Array u8 (sz 32)) + = + let seed_for_A, seed_for_signing, verification_key_hash, s1_as_ntt, s2_as_ntt, t0_as_ntt:(t_Array + u8 (sz 32) & + t_Array u8 (sz 32) & + t_Array u8 (sz 64) & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) = + Libcrux_ml_dsa.Encoding.Signing_key.deserialize_then_ntt #v_SIMDUnit + v_ROWS_IN_A + v_COLUMNS_IN_A + v_ETA + v_ERROR_RING_ELEMENT_SIZE + v_SIGNING_KEY_SIZE + signing_key + in + let v_A_as_ntt:t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A = + Libcrux_ml_dsa.Samplex4.matrix_A #v_SIMDUnit + #v_Shake128X4 + v_ROWS_IN_A + v_COLUMNS_IN_A + (Libcrux_ml_dsa.Utils.into_padded_array (sz 34) (seed_for_A <: t_Slice u8) + <: + t_Array u8 (sz 34)) + in + let message_representative:t_Array u8 (sz 64) = Rust_primitives.Hax.repeat 0uy (sz 64) in + let message_representative:t_Array u8 (sz 64) = + derive_message_representative verification_key_hash + domain_separation_context + message + message_representative + in + let mask_seed:t_Array u8 (sz 64) = Rust_primitives.Hax.repeat 0uy (sz 64) in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_init () + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake (seed_for_signing <: t_Slice u8) + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake (randomness <: t_Slice u8) + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb_final shake + (message_representative <: t_Slice u8) + in + let tmp0, tmp1:(Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze & t_Array u8 (sz 64)) = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_squeeze shake mask_seed + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze = tmp0 in + let mask_seed:t_Array u8 (sz 64) = tmp1 in + let _:Prims.unit = () in + let _:Prims.unit = () in + let (domain_separator_for_mask: u16):u16 = 0us in + let v_BETA:i32 = cast (v_ONES_IN_VERIFIER_CHALLENGE *! v_ETA <: usize) <: i32 in + let attempt:usize = sz 0 in + let commitment_hash:Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) = + Core.Option.Option_None <: Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) + in + let signer_response:Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) = + Core.Option.Option_None + <: + Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + in + let hint:Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) = + Core.Option.Option_None <: Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) + in + let attempt, commitment_hash, domain_separator_for_mask, hint, signer_response:(usize & + Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) & + u16 & + Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) & + Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A)) = + Rust_primitives.f_while_loop (fun temp_0_ -> + let attempt, commitment_hash, domain_separator_for_mask, hint, signer_response:(usize & + Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) & + u16 & + Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) & + Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A)) + = + temp_0_ + in + attempt <. Libcrux_ml_dsa.Constants.v_REJECTION_SAMPLE_BOUND_SIGN <: bool) + (attempt, commitment_hash, domain_separator_for_mask, hint, signer_response + <: + (usize & Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) & u16 & + Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) & + Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A))) + (fun temp_0_ -> + let attempt, commitment_hash, domain_separator_for_mask, hint, signer_response:(usize & + Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) & + u16 & + Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) & + Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A)) + = + temp_0_ + in + let attempt:usize = attempt +! sz 1 in + let tmp0, out:(u16 & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) = + Libcrux_ml_dsa.Sample.sample_mask_vector #v_SIMDUnit + #v_Shake256 + #v_Shake256X4 + v_COLUMNS_IN_A + v_GAMMA1_EXPONENT + (Libcrux_ml_dsa.Utils.into_padded_array (sz 66) (mask_seed <: t_Slice u8) + <: + t_Array u8 (sz 66)) + domain_separator_for_mask + in + let domain_separator_for_mask:u16 = tmp0 in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A = + out + in + let v_A_times_mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A = + Libcrux_ml_dsa.Matrix.compute_A_times_mask #v_SIMDUnit + v_ROWS_IN_A + v_COLUMNS_IN_A + v_A_as_ntt + mask + in + let w0, commitment:(t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_ROWS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) = + Libcrux_ml_dsa.Arithmetic.decompose_vector #v_SIMDUnit + v_ROWS_IN_A + v_GAMMA2 + v_A_times_mask + in + let commitment_hash_candidate:t_Array u8 v_COMMITMENT_HASH_SIZE = + Rust_primitives.Hax.repeat 0uy v_COMMITMENT_HASH_SIZE + in + let commitment_serialized:t_Array u8 v_COMMITMENT_VECTOR_SIZE = + Libcrux_ml_dsa.Encoding.Commitment.serialize_vector #v_SIMDUnit + v_ROWS_IN_A + v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE + commitment + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_init () + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake + (message_representative <: t_Slice u8) + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb_final shake + (commitment_serialized <: t_Slice u8) + in + let tmp0, tmp1:(Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze & + t_Array u8 v_COMMITMENT_HASH_SIZE) = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_squeeze shake commitment_hash_candidate + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze = tmp0 in + let commitment_hash_candidate:t_Array u8 v_COMMITMENT_HASH_SIZE = tmp1 in + let _:Prims.unit = () in + let _:Prims.unit = () in + let verifier_challenge_as_ntt:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit + = + Libcrux_ml_dsa.Ntt.ntt #v_SIMDUnit + (Libcrux_ml_dsa.Sample.sample_challenge_ring_element #v_SIMDUnit + #v_Shake256 + v_ONES_IN_VERIFIER_CHALLENGE + v_COMMITMENT_HASH_SIZE + commitment_hash_candidate + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let challenge_times_s1:t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A = + Libcrux_ml_dsa.Matrix.vector_times_ring_element #v_SIMDUnit + v_COLUMNS_IN_A + s1_as_ntt + verifier_challenge_as_ntt + in + let challenge_times_s2:t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Libcrux_ml_dsa.Matrix.vector_times_ring_element #v_SIMDUnit + v_ROWS_IN_A + s2_as_ntt + verifier_challenge_as_ntt + in + let signer_response_candidate:t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A = + Libcrux_ml_dsa.Matrix.add_vectors #v_SIMDUnit v_COLUMNS_IN_A mask challenge_times_s1 + in + let w0_minus_challenge_times_s2:t_Array + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Libcrux_ml_dsa.Matrix.subtract_vectors #v_SIMDUnit v_ROWS_IN_A w0 challenge_times_s2 + in + if + Libcrux_ml_dsa.Arithmetic.vector_infinity_norm_exceeds #v_SIMDUnit + v_COLUMNS_IN_A + signer_response_candidate + ((1l <. v_MAX_ONES_IN_HINT + then + attempt, commitment_hash, domain_separator_for_mask, hint, signer_response + <: + (usize & Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) & u16 & + Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) & + Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A)) + else + let attempt:usize = Libcrux_ml_dsa.Constants.v_REJECTION_SAMPLE_BOUND_SIGN in + let commitment_hash:Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) = + Core.Option.Option_Some commitment_hash_candidate + <: + Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) + in + let signer_response:Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A) = + Core.Option.Option_Some signer_response_candidate + <: + Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A) + in + let hint:Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) = + Core.Option.Option_Some hint_candidate + <: + Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) + in + attempt, commitment_hash, domain_separator_for_mask, hint, signer_response + <: + (usize & Core.Option.t_Option (t_Array u8 v_COMMITMENT_HASH_SIZE) & u16 & + Core.Option.t_Option (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) & + Core.Option.t_Option + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A))) + in + match + match commitment_hash with + | Core.Option.Option_Some commitment_hash -> + Core.Result.Result_Ok commitment_hash + <: + Core.Result.t_Result (t_Array u8 v_COMMITMENT_HASH_SIZE) Libcrux_ml_dsa.Types.t_SigningError + | Core.Option.Option_None -> + Core.Result.Result_Err + (Libcrux_ml_dsa.Types.SigningError_RejectionSamplingError + <: + Libcrux_ml_dsa.Types.t_SigningError) + <: + Core.Result.t_Result (t_Array u8 v_COMMITMENT_HASH_SIZE) Libcrux_ml_dsa.Types.t_SigningError + with + | Core.Result.Result_Ok commitment_hash -> + (match + match signer_response with + | Core.Option.Option_Some signer_response -> + Core.Result.Result_Ok signer_response + <: + Core.Result.t_Result + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + Libcrux_ml_dsa.Types.t_SigningError + | Core.Option.Option_None -> + Core.Result.Result_Err + (Libcrux_ml_dsa.Types.SigningError_RejectionSamplingError + <: + Libcrux_ml_dsa.Types.t_SigningError) + <: + Core.Result.t_Result + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + Libcrux_ml_dsa.Types.t_SigningError + with + | Core.Result.Result_Ok signer_response -> + (match + match hint with + | Core.Option.Option_Some hint -> + Core.Result.Result_Ok hint + <: + Core.Result.t_Result (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) + Libcrux_ml_dsa.Types.t_SigningError + | Core.Option.Option_None -> + Core.Result.Result_Err + (Libcrux_ml_dsa.Types.SigningError_RejectionSamplingError + <: + Libcrux_ml_dsa.Types.t_SigningError) + <: + Core.Result.t_Result (t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A) + Libcrux_ml_dsa.Types.t_SigningError + with + | Core.Result.Result_Ok hint -> + let signature:t_Array u8 v_SIGNATURE_SIZE = + Libcrux_ml_dsa.Encoding.Signature.impl__serialize #v_SIMDUnit + v_COMMITMENT_HASH_SIZE + v_COLUMNS_IN_A + v_ROWS_IN_A + v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE + v_MAX_ONES_IN_HINT + v_SIGNATURE_SIZE + ({ + Libcrux_ml_dsa.Types.f_commitment_hash = commitment_hash; + Libcrux_ml_dsa.Types.f_signer_response = signer_response; + Libcrux_ml_dsa.Types.f_hint = hint + } + <: + Libcrux_ml_dsa.Types.t_Signature v_SIMDUnit + v_COMMITMENT_HASH_SIZE + v_COLUMNS_IN_A + v_ROWS_IN_A) + in + Core.Result.Result_Ok + (Libcrux_ml_dsa.Types.MLDSASignature signature + <: + Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + <: + Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError + | Core.Result.Result_Err err -> + Core.Result.Result_Err err + <: + Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) + | Core.Result.Result_Err err -> + Core.Result.Result_Err err + <: + Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) + | Core.Result.Result_Err err -> + Core.Result.Result_Err err + <: + Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError + +let sign + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i5: + Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i6: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i7: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + match + Libcrux_ml_dsa.Pre_hash.impl_1__new context + (Core.Option.Option_None <: Core.Option.t_Option (t_Array u8 (sz 11))) + with + | Core.Result.Result_Ok hoist36 -> + sign_internal #v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4 v_ROWS_IN_A v_COLUMNS_IN_A + v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE + v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE signing_key + message + (Core.Option.Option_Some hoist36 + <: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) randomness + | Core.Result.Result_Err err -> + Core.Result.Result_Err + (Core.Convert.f_from #Libcrux_ml_dsa.Types.t_SigningError + #Libcrux_ml_dsa.Pre_hash.t_DomainSeparationError + #FStar.Tactics.Typeclasses.solve + err) + <: + Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError + +let sign_pre_hashed + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4 #v_PH: Type0) + (v_PH_DIGEST_LEN v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: + usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i5: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i6: + Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i7: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i8: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i9: + Libcrux_ml_dsa.Pre_hash.t_PreHash v_PH v_PH_DIGEST_LEN) + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + = + if (Core.Slice.impl__len #u8 context <: usize) >. Libcrux_ml_dsa.Constants.v_CONTEXT_MAX_LEN + then + Core.Result.Result_Err + (Libcrux_ml_dsa.Types.SigningError_ContextTooLongError <: Libcrux_ml_dsa.Types.t_SigningError) + <: + Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError + else + let pre_hashed_message:t_Array u8 v_PH_DIGEST_LEN = + Libcrux_ml_dsa.Pre_hash.f_hash #v_PH #v_PH_DIGEST_LEN #FStar.Tactics.Typeclasses.solve message + in + match + Libcrux_ml_dsa.Pre_hash.impl_1__new context + (Core.Option.Option_Some + (Libcrux_ml_dsa.Pre_hash.f_oid #v_PH #v_PH_DIGEST_LEN #FStar.Tactics.Typeclasses.solve () + <: + t_Array u8 (sz 11)) + <: + Core.Option.t_Option (t_Array u8 (sz 11))) + with + | Core.Result.Result_Ok hoist39 -> + sign_internal #v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4 v_ROWS_IN_A v_COLUMNS_IN_A + v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT v_GAMMA2 v_COMMITMENT_RING_ELEMENT_SIZE + v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE + v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE + signing_key (pre_hashed_message <: t_Slice u8) + (Core.Option.Option_Some hoist39 + <: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) randomness + | Core.Result.Result_Err err -> + Core.Result.Result_Err + (Core.Convert.f_from #Libcrux_ml_dsa.Types.t_SigningError + #Libcrux_ml_dsa.Pre_hash.t_DomainSeparationError + #FStar.Tactics.Typeclasses.solve + err) + <: + Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError + +let verify_internal + (#v_SIMDUnit #v_Shake128X4 #v_Shake256: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i5: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message: t_Slice u8) + (domain_separation_context: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + = + let seed_for_A, t1:(t_Array u8 (sz 32) & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) = + Libcrux_ml_dsa.Encoding.Verification_key.deserialize #v_SIMDUnit + v_ROWS_IN_A + v_VERIFICATION_KEY_SIZE + verification_key_serialized + in + match + Libcrux_ml_dsa.Encoding.Signature.impl__deserialize #v_SIMDUnit + v_COMMITMENT_HASH_SIZE + v_COLUMNS_IN_A + v_ROWS_IN_A + v_GAMMA1_EXPONENT + v_GAMMA1_RING_ELEMENT_SIZE + v_MAX_ONES_IN_HINT + v_SIGNATURE_SIZE + signature_serialized + with + | Core.Result.Result_Ok signature -> + if + ~.(Libcrux_ml_dsa.Arithmetic.vector_infinity_norm_exceeds #v_SIMDUnit + v_COLUMNS_IN_A + signature.Libcrux_ml_dsa.Types.f_signer_response + ((2l <. commitment_hash + then + Core.Result.Result_Err + (Libcrux_ml_dsa.Types.VerificationError_CommitmentHashesDontMatchError + <: + Libcrux_ml_dsa.Types.t_VerificationError) + <: + Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError + else + Core.Result.Result_Ok (() <: Prims.unit) + <: + Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError + else + Core.Result.Result_Err + (Libcrux_ml_dsa.Types.VerificationError_SignerResponseExceedsBoundError + <: + Libcrux_ml_dsa.Types.t_VerificationError) + <: + Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError + | Core.Result.Result_Err err -> + Core.Result.Result_Err err + <: + Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError + +let verify + (#v_SIMDUnit #v_Shake128X4 #v_Shake256: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i5: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + = + match + Libcrux_ml_dsa.Pre_hash.impl_1__new context + (Core.Option.Option_None <: Core.Option.t_Option (t_Array u8 (sz 11))) + with + | Core.Result.Result_Ok hoist41 -> + verify_internal #v_SIMDUnit #v_Shake128X4 #v_Shake256 v_ROWS_IN_A v_COLUMNS_IN_A + v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 + v_BETA v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT verification_key_serialized message + (Core.Option.Option_Some hoist41 + <: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) signature_serialized + | Core.Result.Result_Err err -> + Core.Result.Result_Err + (Core.Convert.f_from #Libcrux_ml_dsa.Types.t_VerificationError + #Libcrux_ml_dsa.Pre_hash.t_DomainSeparationError + #FStar.Tactics.Typeclasses.solve + err) + <: + Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError + +let verify_pre_hashed + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_PH: Type0) + (v_PH_DIGEST_LEN v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i5: + Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i6: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i7: + Libcrux_ml_dsa.Pre_hash.t_PreHash v_PH v_PH_DIGEST_LEN) + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + = + let pre_hashed_message:t_Array u8 v_PH_DIGEST_LEN = + Libcrux_ml_dsa.Pre_hash.f_hash #v_PH #v_PH_DIGEST_LEN #FStar.Tactics.Typeclasses.solve message + in + match + Libcrux_ml_dsa.Pre_hash.impl_1__new context + (Core.Option.Option_Some + (Libcrux_ml_dsa.Pre_hash.f_oid #v_PH #v_PH_DIGEST_LEN #FStar.Tactics.Typeclasses.solve () + <: + t_Array u8 (sz 11)) + <: + Core.Option.t_Option (t_Array u8 (sz 11))) + with + | Core.Result.Result_Ok hoist43 -> + verify_internal #v_SIMDUnit #v_Shake128X4 #v_Shake256 v_ROWS_IN_A v_COLUMNS_IN_A + v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE v_GAMMA2 + v_BETA v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE + v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT verification_key_serialized + (pre_hashed_message <: t_Slice u8) + (Core.Option.Option_Some hoist43 + <: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) signature_serialized + | Core.Result.Result_Err err -> + Core.Result.Result_Err + (Core.Convert.f_from #Libcrux_ml_dsa.Types.t_VerificationError + #Libcrux_ml_dsa.Pre_hash.t_DomainSeparationError + #FStar.Tactics.Typeclasses.solve + err) + <: + Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError + +let generate_key_pair + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i5: + Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i6: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i7: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (randomness: t_Array u8 (sz 32)) + = + let seed_expanded:t_Array u8 (sz 128) = Rust_primitives.Hax.repeat 0uy (sz 128) in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_init () + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Absorb = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb shake (randomness <: t_Slice u8) + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_absorb_final shake + ((let list = [cast (v_ROWS_IN_A <: usize) <: u8; cast (v_COLUMNS_IN_A <: usize) <: u8] in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 2); + Rust_primitives.Hax.array_of_list 2 list) + <: + t_Slice u8) + in + let tmp0, tmp1:(Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze & t_Array u8 (sz 128)) = + Libcrux_ml_dsa.Hash_functions.Portable.shake256_squeeze shake seed_expanded + in + let shake:Libcrux_ml_dsa.Hash_functions.Portable.t_Shake256Squeeze = tmp0 in + let seed_expanded:t_Array u8 (sz 128) = tmp1 in + let _:Prims.unit = () in + let seed_for_a, seed_expanded:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + (seed_expanded <: t_Slice u8) + Libcrux_ml_dsa.Constants.v_SEED_FOR_A_SIZE + in + let seed_for_error_vectors, seed_for_signing:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 + seed_expanded + Libcrux_ml_dsa.Constants.v_SEED_FOR_ERROR_VECTORS_SIZE + in + let a_as_ntt:t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A = + Libcrux_ml_dsa.Samplex4.matrix_A #v_SIMDUnit + #v_Shake128X4 + v_ROWS_IN_A + v_COLUMNS_IN_A + (Libcrux_ml_dsa.Utils.into_padded_array (sz 34) seed_for_a <: t_Array u8 (sz 34)) + in + let s1, s2:(t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) = + Libcrux_ml_dsa.Samplex4.sample_s1_and_s2 #v_SIMDUnit + #v_Shake256X4 + v_ETA + v_COLUMNS_IN_A + v_ROWS_IN_A + (Libcrux_ml_dsa.Utils.into_padded_array (sz 66) seed_for_error_vectors <: t_Array u8 (sz 66)) + in + let t:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A = + Libcrux_ml_dsa.Matrix.compute_As1_plus_s2 #v_SIMDUnit v_ROWS_IN_A v_COLUMNS_IN_A a_as_ntt s1 s2 + in + let t0, t1:(t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_ROWS_IN_A) = + Libcrux_ml_dsa.Arithmetic.power2round_vector #v_SIMDUnit v_ROWS_IN_A t + in + let verification_key_serialized:t_Array u8 v_VERIFICATION_KEY_SIZE = + Libcrux_ml_dsa.Encoding.Verification_key.generate_serialized #v_SIMDUnit + v_ROWS_IN_A + v_VERIFICATION_KEY_SIZE + seed_for_a + t1 + in + let signing_key_serialized:t_Array u8 v_SIGNING_KEY_SIZE = + Libcrux_ml_dsa.Encoding.Signing_key.generate_serialized #v_SIMDUnit #v_Shake256 v_ROWS_IN_A + v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE seed_for_a seed_for_signing + (verification_key_serialized <: t_Slice u8) s1 s2 t0 + in + signing_key_serialized, verification_key_serialized + <: + (t_Array u8 v_SIGNING_KEY_SIZE & t_Array u8 v_VERIFICATION_KEY_SIZE) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.fsti new file mode 100644 index 000000000..abf9c8d7c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ml_dsa_generic.fsti @@ -0,0 +1,167 @@ +module Libcrux_ml_dsa.Ml_dsa_generic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Pre_hash in + let open Libcrux_ml_dsa.Simd.Traits in + () + +/// This corresponds to line 6 in algorithm 7 in FIPS 204 (line 7 in algorithm +/// 8, resp.). +/// If `domain_separation_context` is supplied, applies domain +/// separation and length encoding to the context string, +/// before appending the message (in the regular variant) or the +/// pre-hash OID as well as the pre-hashed message digest. Otherwise, +/// it is assumed that `message` already contains domain separation +/// information. +/// In FIPS 204 M' is the concatenation of the domain separated context, any +/// potential pre-hash OID and the message (or the message pre-hash). We do not +/// explicitely construct the concatenation in memory since it is of statically unknown +/// length, but feed its components directly into the incremental XOF. +/// Refer to line 10 of Algorithm 2 (and line 5 of Algorithm 3, resp.) in [FIPS +/// 204](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf#section.5) +/// for details on the domain separation for regular ML-DSA. Line +/// 23 of Algorithm 4 (and line 18 of Algorithm 5,resp.) describe domain separation for the HashMl-DSA +/// variant. +val derive_message_representative + (verification_key_hash: t_Array u8 (sz 64)) + (domain_separation_context: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) + (message: t_Slice u8) + (message_representative: t_Array u8 (sz 64)) + : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) + +/// The internal signing API. +/// If no `domain_separation_context` is supplied, it is assumed that +/// `message` already contains the domain separation. +val sign_internal + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + {| i4: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i5: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + {| i6: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + {| i7: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message: t_Slice u8) + (domain_separation_context: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +val sign + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + {| i4: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i5: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + {| i6: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + {| i7: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +val sign_pre_hashed + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4 #v_PH: Type0) + (v_PH_DIGEST_LEN v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_GAMMA1_EXPONENT: + usize) + (v_GAMMA2: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT v_GAMMA1_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_SIGNATURE_SIZE: + usize) + {| i5: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i6: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + {| i7: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + {| i8: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + {| i9: Libcrux_ml_dsa.Pre_hash.t_PreHash v_PH v_PH_DIGEST_LEN |} + (signing_key: t_Array u8 v_SIGNING_KEY_SIZE) + (message context: t_Slice u8) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure + (Core.Result.t_Result (Libcrux_ml_dsa.Types.t_MLDSASignature v_SIGNATURE_SIZE) + Libcrux_ml_dsa.Types.t_SigningError) Prims.l_True (fun _ -> Prims.l_True) + +/// The internal verification API. +/// If no `domain_separation_context` is supplied, it is assumed that +/// `message` already contains the domain separation. +val verify_internal + (#v_SIMDUnit #v_Shake128X4 #v_Shake256: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + {| i3: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i4: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + {| i5: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message: t_Slice u8) + (domain_separation_context: + Core.Option.t_Option Libcrux_ml_dsa.Pre_hash.t_DomainSeparationContext) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +val verify + (#v_SIMDUnit #v_Shake128X4 #v_Shake256: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + {| i3: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i4: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + {| i5: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +val verify_pre_hashed + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_PH: Type0) + (v_PH_DIGEST_LEN v_ROWS_IN_A v_COLUMNS_IN_A v_SIGNATURE_SIZE v_VERIFICATION_KEY_SIZE v_GAMMA1_EXPONENT v_GAMMA1_RING_ELEMENT_SIZE: + usize) + (v_GAMMA2 v_BETA: i32) + (v_COMMITMENT_RING_ELEMENT_SIZE v_COMMITMENT_VECTOR_SIZE v_COMMITMENT_HASH_SIZE v_ONES_IN_VERIFIER_CHALLENGE v_MAX_ONES_IN_HINT: + usize) + {| i4: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i5: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + {| i6: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + {| i7: Libcrux_ml_dsa.Pre_hash.t_PreHash v_PH v_PH_DIGEST_LEN |} + (verification_key_serialized: t_Array u8 v_VERIFICATION_KEY_SIZE) + (message context: t_Slice u8) + (signature_serialized: t_Array u8 v_SIGNATURE_SIZE) + : Prims.Pure (Core.Result.t_Result Prims.unit Libcrux_ml_dsa.Types.t_VerificationError) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate a key pair. +val generate_key_pair + (#v_SIMDUnit #v_Shake128X4 #v_Shake256 #v_Shake256X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A v_ETA v_ERROR_RING_ELEMENT_SIZE v_SIGNING_KEY_SIZE v_VERIFICATION_KEY_SIZE: + usize) + {| i4: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i5: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + {| i6: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + {| i7: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (t_Array u8 v_SIGNING_KEY_SIZE & t_Array u8 v_VERIFICATION_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ntt.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ntt.fst new file mode 100644 index 000000000..05275542e --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ntt.fst @@ -0,0 +1,89 @@ +module Libcrux_ml_dsa.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let invert_ntt_montgomery + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + { + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Libcrux_ml_dsa.Simd.Traits.f_invert_ntt_montgomery #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + re.Libcrux_ml_dsa.Polynomial.f_simd_units + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit + +let ntt + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + { + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Libcrux_ml_dsa.Simd.Traits.f_ntt #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + re.Libcrux_ml_dsa.Polynomial.f_simd_units + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit + +let ntt_multiply_montgomery + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (lhs rhs: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + = + let out:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + in + let out:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit + (out.Libcrux_ml_dsa.Polynomial.f_simd_units <: t_Slice v_SIMDUnit) + <: + usize) + (fun out temp_1_ -> + let out:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = out in + let _:usize = temp_1_ in + true) + out + (fun out i -> + let out:Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit = out in + let i:usize = i in + { + out with + Libcrux_ml_dsa.Polynomial.f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_dsa.Polynomial.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_montgomery_multiply #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (lhs.Libcrux_ml_dsa.Polynomial.f_simd_units.[ i ] <: v_SIMDUnit) + (rhs.Libcrux_ml_dsa.Polynomial.f_simd_units.[ i ] <: v_SIMDUnit) + <: + v_SIMDUnit) + <: + t_Array v_SIMDUnit (sz 32) + } + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + out diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ntt.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ntt.fsti new file mode 100644 index 000000000..1c6b919dc --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Ntt.fsti @@ -0,0 +1,34 @@ +module Libcrux_ml_dsa.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +val invert_ntt_montgomery + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (re: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_multiply_montgomery + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (lhs rhs: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Polynomial.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Polynomial.fst new file mode 100644 index 000000000..d92cb4d77 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Polynomial.fst @@ -0,0 +1,258 @@ +module Libcrux_ml_dsa.Polynomial +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let impl__infinity_norm_exceeds + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (self: t_PolynomialRingElement v_SIMDUnit) + (bound: i32) + = + let exceeds:bool = false in + let exceeds:bool = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(t_Array v_SIMDUnit + (sz 32)) + #FStar.Tactics.Typeclasses.solve + self.f_simd_units + <: + Core.Array.Iter.t_IntoIter v_SIMDUnit (sz 32)) + exceeds + (fun exceeds simd_unit -> + let exceeds:bool = exceeds in + let simd_unit:v_SIMDUnit = simd_unit in + exceeds || + (Libcrux_ml_dsa.Simd.Traits.f_infinity_norm_exceeds #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + simd_unit + bound + <: + bool)) + in + exceeds + +let impl__ZERO + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (_: Prims.unit) + = + { + f_simd_units + = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Simd.Traits.f_ZERO #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + () + <: + v_SIMDUnit) + (sz 32) + } + <: + t_PolynomialRingElement v_SIMDUnit + +let impl__from_i32_array + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (array: t_Slice i32) + = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #i32 array <: usize) >=. sz 256 <: bool) + in + () + in + let array_chunks:Core.Slice.Iter.t_Chunks i32 = + Core.Slice.impl__chunks #i32 array Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT + in + let result:t_PolynomialRingElement v_SIMDUnit = impl__ZERO #v_SIMDUnit () in + let array_chunks, result:(Core.Slice.Iter.t_Chunks i32 & t_PolynomialRingElement v_SIMDUnit) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + Libcrux_ml_dsa.Simd.Traits.v_SIMD_UNITS_IN_RING_ELEMENT + (fun temp_0_ temp_1_ -> + let array_chunks, result:(Core.Slice.Iter.t_Chunks i32 & + t_PolynomialRingElement v_SIMDUnit) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (array_chunks, result <: (Core.Slice.Iter.t_Chunks i32 & t_PolynomialRingElement v_SIMDUnit)) + (fun temp_0_ i -> + let array_chunks, result:(Core.Slice.Iter.t_Chunks i32 & + t_PolynomialRingElement v_SIMDUnit) = + temp_0_ + in + let i:usize = i in + let tmp0, out:(Core.Slice.Iter.t_Chunks i32 & Core.Option.t_Option (t_Slice i32)) = + Core.Iter.Traits.Iterator.f_next #(Core.Slice.Iter.t_Chunks i32) + #FStar.Tactics.Typeclasses.solve + array_chunks + in + let array_chunks:Core.Slice.Iter.t_Chunks i32 = tmp0 in + array_chunks, + ({ + result with + f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_from_coefficient_array #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Core.Option.impl__unwrap #(t_Slice i32) out <: t_Slice i32) + <: + v_SIMDUnit) + } + <: + t_PolynomialRingElement v_SIMDUnit) + <: + (Core.Slice.Iter.t_Chunks i32 & t_PolynomialRingElement v_SIMDUnit)) + in + result + +let impl__add + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (self rhs: t_PolynomialRingElement v_SIMDUnit) + = + let sum:t_PolynomialRingElement v_SIMDUnit = impl__ZERO #v_SIMDUnit () in + let sum:t_PolynomialRingElement v_SIMDUnit = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit (sum.f_simd_units <: t_Slice v_SIMDUnit) <: usize) + (fun sum temp_1_ -> + let sum:t_PolynomialRingElement v_SIMDUnit = sum in + let _:usize = temp_1_ in + true) + sum + (fun sum i -> + let sum:t_PolynomialRingElement v_SIMDUnit = sum in + let i:usize = i in + { + sum with + f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize sum.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_add #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (self.f_simd_units.[ i ] <: v_SIMDUnit) + (rhs.f_simd_units.[ i ] <: v_SIMDUnit) + <: + v_SIMDUnit) + <: + t_Array v_SIMDUnit (sz 32) + } + <: + t_PolynomialRingElement v_SIMDUnit) + in + sum + +let impl__subtract + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (self rhs: t_PolynomialRingElement v_SIMDUnit) + = + let difference:t_PolynomialRingElement v_SIMDUnit = impl__ZERO #v_SIMDUnit () in + let difference:t_PolynomialRingElement v_SIMDUnit = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #v_SIMDUnit (difference.f_simd_units <: t_Slice v_SIMDUnit) <: usize) + (fun difference temp_1_ -> + let difference:t_PolynomialRingElement v_SIMDUnit = difference in + let _:usize = temp_1_ in + true) + difference + (fun difference i -> + let difference:t_PolynomialRingElement v_SIMDUnit = difference in + let i:usize = i in + { + difference with + f_simd_units + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize difference.f_simd_units + i + (Libcrux_ml_dsa.Simd.Traits.f_subtract #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + (self.f_simd_units.[ i ] <: v_SIMDUnit) + (rhs.f_simd_units.[ i ] <: v_SIMDUnit) + <: + v_SIMDUnit) + <: + t_Array v_SIMDUnit (sz 32) + } + <: + t_PolynomialRingElement v_SIMDUnit) + in + difference + +let impl__to_i32_array + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (self: t_PolynomialRingElement v_SIMDUnit) + = + let result:t_Array i32 (sz 256) = Rust_primitives.Hax.repeat 0l (sz 256) in + let result:t_Array i32 (sz 256) = + Rust_primitives.Hax.Folds.fold_enumerated_slice (self.f_simd_units <: t_Slice v_SIMDUnit) + (fun result temp_1_ -> + let result:t_Array i32 (sz 256) = result in + let _:usize = temp_1_ in + true) + result + (fun result temp_1_ -> + let result:t_Array i32 (sz 256) = result in + let i, simd_unit:(usize & v_SIMDUnit) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range result + ({ + Core.Ops.Range.f_start + = + i *! Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT + <: + usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #i32 + (result.[ { + Core.Ops.Range.f_start + = + i *! Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT <: usize; + Core.Ops.Range.f_end + = + (i +! sz 1 <: usize) *! Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT + <: + usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i32) + (Libcrux_ml_dsa.Simd.Traits.f_to_coefficient_array #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + simd_unit + <: + t_Slice i32) + <: + t_Slice i32) + <: + t_Array i32 (sz 256)) + in + result diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Polynomial.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Polynomial.fsti new file mode 100644 index 000000000..918eb2620 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Polynomial.fsti @@ -0,0 +1,51 @@ +module Libcrux_ml_dsa.Polynomial +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +type t_PolynomialRingElement + (v_SIMDUnit: Type0) {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + = { f_simd_units:t_Array v_SIMDUnit (sz 32) } + +val impl__infinity_norm_exceeds + (#v_SIMDUnit: Type0) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (self: t_PolynomialRingElement v_SIMDUnit) + (bound: i32) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + +val impl__ZERO: + #v_SIMDUnit: Type0 -> + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} -> + Prims.unit + -> Prims.Pure (t_PolynomialRingElement v_SIMDUnit) Prims.l_True (fun _ -> Prims.l_True) + +val impl__from_i32_array + (#v_SIMDUnit: Type0) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (array: t_Slice i32) + : Prims.Pure (t_PolynomialRingElement v_SIMDUnit) Prims.l_True (fun _ -> Prims.l_True) + +val impl__add + (#v_SIMDUnit: Type0) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (self rhs: t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (t_PolynomialRingElement v_SIMDUnit) Prims.l_True (fun _ -> Prims.l_True) + +val impl__subtract + (#v_SIMDUnit: Type0) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (self rhs: t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (t_PolynomialRingElement v_SIMDUnit) Prims.l_True (fun _ -> Prims.l_True) + +val impl__to_i32_array + (#v_SIMDUnit: Type0) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (self: t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure (t_Array i32 (sz 256)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Pre_hash.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Pre_hash.fst new file mode 100644 index 000000000..839ac9c79 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Pre_hash.fst @@ -0,0 +1,89 @@ +module Libcrux_ml_dsa.Pre_hash +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Portable in + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + () + +let impl_1__context (self: t_DomainSeparationContext) = self.f_context + +let impl_1__pre_hash_oid (self: t_DomainSeparationContext) = self.f_pre_hash_oid + +let impl_1__new (context: t_Slice u8) (pre_hash_oid: Core.Option.t_Option (t_Array u8 (sz 11))) = + if (Core.Slice.impl__len #u8 context <: usize) >. Libcrux_ml_dsa.Constants.v_CONTEXT_MAX_LEN + then + Core.Result.Result_Err (DomainSeparationError_ContextTooLongError <: t_DomainSeparationError) + <: + Core.Result.t_Result t_DomainSeparationContext t_DomainSeparationError + else + Core.Result.Result_Ok + ({ f_context = context; f_pre_hash_oid = pre_hash_oid } <: t_DomainSeparationContext) + <: + Core.Result.t_Result t_DomainSeparationContext t_DomainSeparationError + +let t_DomainSeparationError_cast_to_repr (x: t_DomainSeparationError) = + match x with | DomainSeparationError_ContextTooLongError -> isz 0 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_2: Core.Convert.t_From Libcrux_ml_dsa.Types.t_SigningError t_DomainSeparationError = + { + f_from_pre = (fun (e: t_DomainSeparationError) -> true); + f_from_post + = + (fun (e: t_DomainSeparationError) (out: Libcrux_ml_dsa.Types.t_SigningError) -> true); + f_from + = + fun (e: t_DomainSeparationError) -> + match e with + | DomainSeparationError_ContextTooLongError -> + Libcrux_ml_dsa.Types.SigningError_ContextTooLongError <: Libcrux_ml_dsa.Types.t_SigningError + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_3: Core.Convert.t_From Libcrux_ml_dsa.Types.t_VerificationError t_DomainSeparationError = + { + f_from_pre = (fun (e: t_DomainSeparationError) -> true); + f_from_post + = + (fun (e: t_DomainSeparationError) (out: Libcrux_ml_dsa.Types.t_VerificationError) -> true); + f_from + = + fun (e: t_DomainSeparationError) -> + match e with + | DomainSeparationError_ContextTooLongError -> + Libcrux_ml_dsa.Types.VerificationError_ContextTooLongError + <: + Libcrux_ml_dsa.Types.t_VerificationError + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: t_PreHash t_SHAKE128_PH (sz 256) = + { + f_oid_pre = (fun (_: Prims.unit) -> true); + f_oid_post = (fun (_: Prims.unit) (out: t_Array u8 (sz 11)) -> true); + f_oid + = + (fun (_: Prims.unit) -> + let list = [6uy; 9uy; 96uy; 134uy; 72uy; 1uy; 101uy; 3uy; 4uy; 2uy; 11uy] in + FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 11); + Rust_primitives.Hax.array_of_list 11 list); + f_hash_pre = (fun (message: t_Slice u8) -> true); + f_hash_post = (fun (message: t_Slice u8) (out: t_Array u8 (sz 256)) -> true); + f_hash + = + fun (message: t_Slice u8) -> + let output:t_Array u8 (sz 256) = Rust_primitives.Hax.repeat 0uy (sz 256) in + let output:t_Array u8 (sz 256) = + Libcrux_ml_dsa.Hash_functions.Shake128.f_shake128 #Libcrux_ml_dsa.Hash_functions.Portable.t_Shake128 + #FStar.Tactics.Typeclasses.solve + (sz 256) + message + output + in + output + } diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Pre_hash.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Pre_hash.fsti new file mode 100644 index 000000000..2dc40559b --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Pre_hash.fsti @@ -0,0 +1,63 @@ +module Libcrux_ml_dsa.Pre_hash +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Portable in + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + () + +/// Binds the context string to an optional pre-hash OID identifying +/// the hash function or XOF used for pre-hashing. +type t_DomainSeparationContext = { + f_context:t_Slice u8; + f_pre_hash_oid:Core.Option.t_Option (t_Array u8 (sz 11)) +} + +/// Returns the context, guaranteed to be at most 255 bytes long. +val impl_1__context (self: t_DomainSeparationContext) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// Returns the pre-hash OID, if any. +val impl_1__pre_hash_oid (self: t_DomainSeparationContext) + : Prims.Pure (Core.Option.t_Option (t_Array u8 (sz 11))) Prims.l_True (fun _ -> Prims.l_True) + +type t_DomainSeparationError = | DomainSeparationError_ContextTooLongError : t_DomainSeparationError + +/// `context` must be at most 255 bytes long. +val impl_1__new (context: t_Slice u8) (pre_hash_oid: Core.Option.t_Option (t_Array u8 (sz 11))) + : Prims.Pure (Core.Result.t_Result t_DomainSeparationContext t_DomainSeparationError) + Prims.l_True + (fun _ -> Prims.l_True) + +val t_DomainSeparationError_cast_to_repr (x: t_DomainSeparationError) + : Prims.Pure isize Prims.l_True (fun _ -> Prims.l_True) + +class t_PreHash (v_Self: Type0) (v_DIGEST_LEN: usize) = { + f_oid_pre:Prims.unit -> Type0; + f_oid_post:Prims.unit -> t_Array u8 (sz 11) -> Type0; + f_oid:x0: Prims.unit + -> Prims.Pure (t_Array u8 (sz 11)) (f_oid_pre x0) (fun result -> f_oid_post x0 result); + f_hash_pre:t_Slice u8 -> Type0; + f_hash_post:t_Slice u8 -> t_Array u8 v_DIGEST_LEN -> Type0; + f_hash:x0: t_Slice u8 + -> Prims.Pure (t_Array u8 v_DIGEST_LEN) (f_hash_pre x0) (fun result -> f_hash_post x0 result) +} + +/// An implementation of the pre-hash trait for the SHAKE-128 XOF with +/// digest length 256 bytes. +type t_SHAKE128_PH = | SHAKE128_PH : t_SHAKE128_PH + +let v_PRE_HASH_OID_LEN: usize = sz 11 + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl_2:Core.Convert.t_From Libcrux_ml_dsa.Types.t_SigningError t_DomainSeparationError + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl_3:Core.Convert.t_From Libcrux_ml_dsa.Types.t_VerificationError t_DomainSeparationError + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl:t_PreHash t_SHAKE128_PH (sz 256) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Sample.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Sample.fst new file mode 100644 index 000000000..f2d7ff6c7 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Sample.fst @@ -0,0 +1,1286 @@ +module Libcrux_ml_dsa.Sample +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Simd.Traits in + () + +let update_seed (seed: t_Array u8 (sz 66)) (domain_separator: u16) = + let seed:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed + (sz 64) + (cast (domain_separator <: u16) <: u8) + in + let seed:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed + (sz 65) + (cast (domain_separator >>! 8l <: u16) <: u8) + in + let domain_separator:u16 = domain_separator +! 1us in + let hax_temp_output:t_Array u8 (sz 66) = seed in + domain_separator, hax_temp_output <: (u16 & t_Array u8 (sz 66)) + +let rejection_sample_less_than_eta_equals_2_ + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (randomness: t_Slice u8) + (sampled_coefficients: usize) + (out: t_Array i32 (sz 263)) + = + let done:bool = false in + let done, out, sampled_coefficients:(bool & t_Array i32 (sz 263) & usize) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Chunks + u8) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__chunks #u8 randomness (sz 4) <: Core.Slice.Iter.t_Chunks u8) + <: + Core.Slice.Iter.t_Chunks u8) + (done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize)) + (fun temp_0_ random_bytes -> + let done, out, sampled_coefficients:(bool & t_Array i32 (sz 263) & usize) = temp_0_ in + let random_bytes:t_Slice u8 = random_bytes in + if ~.done <: bool + then + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Traits.f_rejection_sample_less_than_eta_equals_2_ #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + random_bytes + (out.[ { Core.Ops.Range.f_start = sampled_coefficients } + <: + Core.Ops.Range.t_RangeFrom usize ] + <: + t_Slice i32) + in + let out:t_Array i32 (sz 263) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from out + ({ Core.Ops.Range.f_start = sampled_coefficients } + <: + Core.Ops.Range.t_RangeFrom usize) + tmp0 + in + let sampled:usize = out1 in + let sampled_coefficients:usize = sampled_coefficients +! sampled in + if sampled_coefficients >=. Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + then + let done:bool = true in + done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize) + else done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize) + else done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize)) + in + let hax_temp_output:bool = done in + sampled_coefficients, out, hax_temp_output <: (usize & t_Array i32 (sz 263) & bool) + +let rejection_sample_less_than_eta_equals_4_ + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (randomness: t_Slice u8) + (sampled_coefficients: usize) + (out: t_Array i32 (sz 263)) + = + let done:bool = false in + let done, out, sampled_coefficients:(bool & t_Array i32 (sz 263) & usize) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Chunks + u8) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__chunks #u8 randomness (sz 4) <: Core.Slice.Iter.t_Chunks u8) + <: + Core.Slice.Iter.t_Chunks u8) + (done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize)) + (fun temp_0_ random_bytes -> + let done, out, sampled_coefficients:(bool & t_Array i32 (sz 263) & usize) = temp_0_ in + let random_bytes:t_Slice u8 = random_bytes in + if ~.done <: bool + then + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Traits.f_rejection_sample_less_than_eta_equals_4_ #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + random_bytes + (out.[ { Core.Ops.Range.f_start = sampled_coefficients } + <: + Core.Ops.Range.t_RangeFrom usize ] + <: + t_Slice i32) + in + let out:t_Array i32 (sz 263) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from out + ({ Core.Ops.Range.f_start = sampled_coefficients } + <: + Core.Ops.Range.t_RangeFrom usize) + tmp0 + in + let sampled:usize = out1 in + let sampled_coefficients:usize = sampled_coefficients +! sampled in + if sampled_coefficients >=. Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + then + let done:bool = true in + done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize) + else done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize) + else done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize)) + in + let hax_temp_output:bool = done in + sampled_coefficients, out, hax_temp_output <: (usize & t_Array i32 (sz 263) & bool) + +let rejection_sample_less_than_eta + (#v_SIMDUnit: Type0) + (v_ETA: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (randomness: t_Slice u8) + (sampled: usize) + (out: t_Array i32 (sz 263)) + = + let (out, sampled), hax_temp_output:((t_Array i32 (sz 263) & usize) & bool) = + match cast (v_ETA <: usize) <: u8 with + | 2uy -> + let tmp0, tmp1, out1:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta_equals_2_ #v_SIMDUnit randomness sampled out + in + let sampled:usize = tmp0 in + let out:t_Array i32 (sz 263) = tmp1 in + (out, sampled <: (t_Array i32 (sz 263) & usize)), out1 + <: + ((t_Array i32 (sz 263) & usize) & bool) + | 4uy -> + let tmp0, tmp1, out1:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta_equals_4_ #v_SIMDUnit randomness sampled out + in + let sampled:usize = tmp0 in + let out:t_Array i32 (sz 263) = tmp1 in + (out, sampled <: (t_Array i32 (sz 263) & usize)), out1 + <: + ((t_Array i32 (sz 263) & usize) & bool) + | _ -> + (out, sampled <: (t_Array i32 (sz 263) & usize)), + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + <: + ((t_Array i32 (sz 263) & usize) & bool) + in + sampled, out, hax_temp_output <: (usize & t_Array i32 (sz 263) & bool) + +let rejection_sample_less_than_field_modulus + (#v_SIMDUnit: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (randomness: t_Slice u8) + (sampled_coefficients: usize) + (out: t_Array i32 (sz 263)) + = + let done:bool = false in + let done, out, sampled_coefficients:(bool & t_Array i32 (sz 263) & usize) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Chunks + u8) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__chunks #u8 randomness (sz 24) <: Core.Slice.Iter.t_Chunks u8) + <: + Core.Slice.Iter.t_Chunks u8) + (done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize)) + (fun temp_0_ random_bytes -> + let done, out, sampled_coefficients:(bool & t_Array i32 (sz 263) & usize) = temp_0_ in + let random_bytes:t_Slice u8 = random_bytes in + if ~.done <: bool + then + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Traits.f_rejection_sample_less_than_field_modulus #v_SIMDUnit + #FStar.Tactics.Typeclasses.solve + random_bytes + (out.[ { Core.Ops.Range.f_start = sampled_coefficients } + <: + Core.Ops.Range.t_RangeFrom usize ] + <: + t_Slice i32) + in + let out:t_Array i32 (sz 263) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from out + ({ Core.Ops.Range.f_start = sampled_coefficients } + <: + Core.Ops.Range.t_RangeFrom usize) + tmp0 + in + let sampled:usize = out1 in + let sampled_coefficients:usize = sampled_coefficients +! sampled in + if sampled_coefficients >=. Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + then + let done:bool = true in + done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize) + else done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize) + else done, out, sampled_coefficients <: (bool & t_Array i32 (sz 263) & usize)) + in + let hax_temp_output:bool = done in + sampled_coefficients, out, hax_temp_output <: (usize & t_Array i32 (sz 263) & bool) + +let inside_out_shuffle + (randomness: t_Slice u8) + (out_index: usize) + (signs: u64) + (result: t_Array i32 (sz 256)) + = + let done:bool = false in + let done, out_index, result, signs:(bool & usize & t_Array i32 (sz 256) & u64) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(t_Slice u8) + #FStar.Tactics.Typeclasses.solve + randomness + <: + Core.Slice.Iter.t_Iter u8) + (done, out_index, result, signs <: (bool & usize & t_Array i32 (sz 256) & u64)) + (fun temp_0_ byte -> + let done, out_index, result, signs:(bool & usize & t_Array i32 (sz 256) & u64) = + temp_0_ + in + let byte:u8 = byte in + if ~.done <: bool + then + let sample_at:usize = cast (byte <: u8) <: usize in + let out_index, result, signs:(usize & t_Array i32 (sz 256) & u64) = + if sample_at <=. out_index + then + let result:t_Array i32 (sz 256) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + out_index + (result.[ sample_at ] <: i32) + in + let out_index:usize = out_index +! sz 1 in + let result:t_Array i32 (sz 256) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + sample_at + (1l -! (2l *! (cast (signs &. 1uL <: u64) <: i32) <: i32) <: i32) + in + let signs:u64 = signs >>! 1l in + out_index, result, signs <: (usize & t_Array i32 (sz 256) & u64) + else out_index, result, signs <: (usize & t_Array i32 (sz 256) & u64) + in + let done:bool = + out_index =. (Core.Slice.impl__len #i32 (result <: t_Slice i32) <: usize) + in + done, out_index, result, signs <: (bool & usize & t_Array i32 (sz 256) & u64) + else done, out_index, result, signs <: (bool & usize & t_Array i32 (sz 256) & u64)) + in + let hax_temp_output:bool = done in + out_index, signs, result, hax_temp_output <: (usize & u64 & t_Array i32 (sz 256) & bool) + +let sample_challenge_ring_element + (#v_SIMDUnit #v_Shake256: Type0) + (v_NUMBER_OF_ONES v_SEED_SIZE: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (seed: t_Array u8 v_SEED_SIZE) + = + let state:v_Shake256 = + Libcrux_ml_dsa.Hash_functions.Shake256.f_init_absorb #v_Shake256 + #FStar.Tactics.Typeclasses.solve + (seed <: t_Slice u8) + in + let tmp0, out:(v_Shake256 & t_Array u8 (sz 136)) = + Libcrux_ml_dsa.Hash_functions.Shake256.f_squeeze_first_block #v_Shake256 + #FStar.Tactics.Typeclasses.solve + state + in + let state:v_Shake256 = tmp0 in + let randomness:t_Array u8 (sz 136) = out in + let signs:u64 = + Core.Num.impl__u64__from_le_bytes (Core.Result.impl__unwrap #(t_Array u8 (sz 8)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 (sz 8)) + #FStar.Tactics.Typeclasses.solve + (randomness.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 8 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + <: + Core.Result.t_Result (t_Array u8 (sz 8)) Core.Array.t_TryFromSliceError) + <: + t_Array u8 (sz 8)) + in + let result:t_Array i32 (sz 256) = Rust_primitives.Hax.repeat 0l (sz 256) in + let out_index:usize = + (Core.Slice.impl__len #i32 (result <: t_Slice i32) <: usize) -! v_NUMBER_OF_ONES + in + let tmp0, tmp1, tmp2, out:(usize & u64 & t_Array i32 (sz 256) & bool) = + inside_out_shuffle (randomness.[ { Core.Ops.Range.f_start = sz 8 } + <: + Core.Ops.Range.t_RangeFrom usize ] + <: + t_Slice u8) + out_index + signs + result + in + let out_index:usize = tmp0 in + let signs:u64 = tmp1 in + let result:t_Array i32 (sz 256) = tmp2 in + let done:bool = out in + let done, out_index, result, signs, state:(bool & usize & t_Array i32 (sz 256) & u64 & v_Shake256) + = + Rust_primitives.f_while_loop (fun temp_0_ -> + let done, out_index, result, signs, state:(bool & usize & t_Array i32 (sz 256) & u64 & + v_Shake256) = + temp_0_ + in + ~.done <: bool) + (done, out_index, result, signs, state + <: + (bool & usize & t_Array i32 (sz 256) & u64 & v_Shake256)) + (fun temp_0_ -> + let done, out_index, result, signs, state:(bool & usize & t_Array i32 (sz 256) & u64 & + v_Shake256) = + temp_0_ + in + let tmp0, out:(v_Shake256 & t_Array u8 (sz 136)) = + Libcrux_ml_dsa.Hash_functions.Shake256.f_squeeze_next_block #v_Shake256 + #FStar.Tactics.Typeclasses.solve + state + in + let state:v_Shake256 = tmp0 in + let randomness:t_Array u8 (sz 136) = out in + let tmp0, tmp1, tmp2, out:(usize & u64 & t_Array i32 (sz 256) & bool) = + inside_out_shuffle (randomness <: t_Slice u8) out_index signs result + in + let out_index:usize = tmp0 in + let signs:u64 = tmp1 in + let result:t_Array i32 (sz 256) = tmp2 in + let done:bool = out in + done, out_index, result, signs, state + <: + (bool & usize & t_Array i32 (sz 256) & u64 & v_Shake256)) + in + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (result <: t_Slice i32) + +let sample_four_error_ring_elements + (#v_SIMDUnit #v_Shake256: Type0) + (v_ETA: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256) + (seed_base: t_Array u8 (sz 66)) + (domain_separator0 domain_separator1 domain_seperator2 domain_separator3: u16) + = + let seed0:t_Array u8 (sz 66) = seed_base in + let seed0:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed0 + (sz 64) + (cast (domain_separator0 <: u16) <: u8) + in + let seed0:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed0 + (sz 65) + (cast (domain_separator0 >>! 8l <: u16) <: u8) + in + let seed1:t_Array u8 (sz 66) = seed0 in + let seed1:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed1 + (sz 64) + (cast (domain_separator1 <: u16) <: u8) + in + let seed1:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed1 + (sz 65) + (cast (domain_separator1 >>! 8l <: u16) <: u8) + in + let seed2:t_Array u8 (sz 66) = seed0 in + let seed2:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed2 + (sz 64) + (cast (domain_seperator2 <: u16) <: u8) + in + let seed2:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed2 + (sz 65) + (cast (domain_seperator2 >>! 8l <: u16) <: u8) + in + let seed3:t_Array u8 (sz 66) = seed0 in + let seed3:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed3 + (sz 64) + (cast (domain_separator3 <: u16) <: u8) + in + let seed3:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed3 + (sz 65) + (cast (domain_separator3 >>! 8l <: u16) <: u8) + in + let state:v_Shake256 = + Libcrux_ml_dsa.Hash_functions.Shake256.f_init_absorb_x4 #v_Shake256 + #FStar.Tactics.Typeclasses.solve + (seed0 <: t_Slice u8) + (seed1 <: t_Slice u8) + (seed2 <: t_Slice u8) + (seed3 <: t_Slice u8) + in + let tmp0, out4:(v_Shake256 & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) = + Libcrux_ml_dsa.Hash_functions.Shake256.f_squeeze_first_block_x4 #v_Shake256 + #FStar.Tactics.Typeclasses.solve + state + in + let state:v_Shake256 = tmp0 in + let randomnesses:(t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & + t_Array u8 (sz 136)) = + out4 + in + let out0:t_Array i32 (sz 263) = Rust_primitives.Hax.repeat 0l (sz 263) in + let out1:t_Array i32 (sz 263) = Rust_primitives.Hax.repeat 0l (sz 263) in + let out2:t_Array i32 (sz 263) = Rust_primitives.Hax.repeat 0l (sz 263) in + let out3:t_Array i32 (sz 263) = Rust_primitives.Hax.repeat 0l (sz 263) in + let sampled0:usize = sz 0 in + let sampled1:usize = sz 0 in + let sampled2:usize = sz 0 in + let sampled3:usize = sz 0 in + let tmp0, tmp1, out4:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta #v_SIMDUnit v_ETA (randomnesses._1 <: t_Slice u8) sampled0 out0 + in + let sampled0:usize = tmp0 in + let out0:t_Array i32 (sz 263) = tmp1 in + let done0:bool = out4 in + let tmp0, tmp1, out4:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta #v_SIMDUnit v_ETA (randomnesses._2 <: t_Slice u8) sampled1 out1 + in + let sampled1:usize = tmp0 in + let out1:t_Array i32 (sz 263) = tmp1 in + let done1:bool = out4 in + let tmp0, tmp1, out4:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta #v_SIMDUnit v_ETA (randomnesses._3 <: t_Slice u8) sampled2 out2 + in + let sampled2:usize = tmp0 in + let out2:t_Array i32 (sz 263) = tmp1 in + let done2:bool = out4 in + let tmp0, tmp1, out4:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta #v_SIMDUnit v_ETA (randomnesses._4 <: t_Slice u8) sampled3 out3 + in + let sampled3:usize = tmp0 in + let out3:t_Array i32 (sz 263) = tmp1 in + let done3:bool = out4 in + let + done0, done1, done2, done3, out0, out1, out2, out3, sampled0, sampled1, sampled2, sampled3, state:( + bool & bool & bool & bool & t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + usize & + usize & + usize & + usize & + v_Shake256) = + Rust_primitives.f_while_loop (fun temp_0_ -> + let + done0, + done1, + done2, + done3, + out0, + out1, + out2, + out3, + sampled0, + sampled1, + sampled2, + sampled3, + state:(bool & bool & bool & bool & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + usize & + usize & + usize & + usize & + v_Shake256) = + temp_0_ + in + (~.done0 <: bool) || (~.done1 <: bool) || (~.done2 <: bool) || (~.done3 <: bool)) + (done0, + done1, + done2, + done3, + out0, + out1, + out2, + out3, + sampled0, + sampled1, + sampled2, + sampled3, + state + <: + (bool & bool & bool & bool & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + usize & + usize & + usize & + usize & + v_Shake256)) + (fun temp_0_ -> + let + done0, + done1, + done2, + done3, + out0, + out1, + out2, + out3, + sampled0, + sampled1, + sampled2, + sampled3, + state:(bool & bool & bool & bool & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + usize & + usize & + usize & + usize & + v_Shake256) = + temp_0_ + in + let tmp0, out4:(v_Shake256 & + (t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136))) + = + Libcrux_ml_dsa.Hash_functions.Shake256.f_squeeze_next_block_x4 #v_Shake256 + #FStar.Tactics.Typeclasses.solve + state + in + let state:v_Shake256 = tmp0 in + let randomnesses:(t_Array u8 (sz 136) & t_Array u8 (sz 136) & t_Array u8 (sz 136) & + t_Array u8 (sz 136)) = + out4 + in + let done0, out0, sampled0:(bool & t_Array i32 (sz 263) & usize) = + if ~.done0 + then + let tmp0, tmp1, out4:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta #v_SIMDUnit + v_ETA + (randomnesses._1 <: t_Slice u8) + sampled0 + out0 + in + let sampled0:usize = tmp0 in + let out0:t_Array i32 (sz 263) = tmp1 in + let done0:bool = out4 in + done0, out0, sampled0 <: (bool & t_Array i32 (sz 263) & usize) + else done0, out0, sampled0 <: (bool & t_Array i32 (sz 263) & usize) + in + let done1, out1, sampled1:(bool & t_Array i32 (sz 263) & usize) = + if ~.done1 + then + let tmp0, tmp1, out4:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta #v_SIMDUnit + v_ETA + (randomnesses._2 <: t_Slice u8) + sampled1 + out1 + in + let sampled1:usize = tmp0 in + let out1:t_Array i32 (sz 263) = tmp1 in + let done1:bool = out4 in + done1, out1, sampled1 <: (bool & t_Array i32 (sz 263) & usize) + else done1, out1, sampled1 <: (bool & t_Array i32 (sz 263) & usize) + in + let done2, out2, sampled2:(bool & t_Array i32 (sz 263) & usize) = + if ~.done2 + then + let tmp0, tmp1, out4:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta #v_SIMDUnit + v_ETA + (randomnesses._3 <: t_Slice u8) + sampled2 + out2 + in + let sampled2:usize = tmp0 in + let out2:t_Array i32 (sz 263) = tmp1 in + let done2:bool = out4 in + done2, out2, sampled2 <: (bool & t_Array i32 (sz 263) & usize) + else done2, out2, sampled2 <: (bool & t_Array i32 (sz 263) & usize) + in + if ~.done3 + then + let tmp0, tmp1, out4:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_eta #v_SIMDUnit + v_ETA + (randomnesses._4 <: t_Slice u8) + sampled3 + out3 + in + let sampled3:usize = tmp0 in + let out3:t_Array i32 (sz 263) = tmp1 in + let done3:bool = out4 in + done0, + done1, + done2, + done3, + out0, + out1, + out2, + out3, + sampled0, + sampled1, + sampled2, + sampled3, + state + <: + (bool & bool & bool & bool & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + usize & + usize & + usize & + usize & + v_Shake256) + else + done0, + done1, + done2, + done3, + out0, + out1, + out2, + out3, + sampled0, + sampled1, + sampled2, + sampled3, + state + <: + (bool & bool & bool & bool & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + usize & + usize & + usize & + usize & + v_Shake256)) + in + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (out0 <: t_Slice i32), + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (out1 <: t_Slice i32), + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (out2 <: t_Slice i32), + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (out3 <: t_Slice i32) + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + +let sample_four_ring_elements + (#v_SIMDUnit #v_Shake128: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128) + (seed0: t_Array u8 (sz 34)) + (domain_separator0 domain_separator1 domain_seperator2 domain_separator3: u16) + = + let seed0:t_Array u8 (sz 34) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed0 + (sz 32) + (cast (domain_separator0 <: u16) <: u8) + in + let seed0:t_Array u8 (sz 34) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed0 + (sz 33) + (cast (domain_separator0 >>! 8l <: u16) <: u8) + in + let seed1:t_Array u8 (sz 34) = seed0 in + let seed1:t_Array u8 (sz 34) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed1 + (sz 32) + (cast (domain_separator1 <: u16) <: u8) + in + let seed1:t_Array u8 (sz 34) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed1 + (sz 33) + (cast (domain_separator1 >>! 8l <: u16) <: u8) + in + let seed2:t_Array u8 (sz 34) = seed0 in + let seed2:t_Array u8 (sz 34) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed2 + (sz 32) + (cast (domain_seperator2 <: u16) <: u8) + in + let seed2:t_Array u8 (sz 34) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed2 + (sz 33) + (cast (domain_seperator2 >>! 8l <: u16) <: u8) + in + let seed3:t_Array u8 (sz 34) = seed0 in + let seed3:t_Array u8 (sz 34) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed3 + (sz 32) + (cast (domain_separator3 <: u16) <: u8) + in + let seed3:t_Array u8 (sz 34) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed3 + (sz 33) + (cast (domain_separator3 >>! 8l <: u16) <: u8) + in + let state:v_Shake128 = + Libcrux_ml_dsa.Hash_functions.Shake128.f_init_absorb #v_Shake128 + #FStar.Tactics.Typeclasses.solve + (seed0 <: t_Slice u8) + (seed1 <: t_Slice u8) + (seed2 <: t_Slice u8) + (seed3 <: t_Slice u8) + in + let randomness0:t_Array u8 (sz 840) = Rust_primitives.Hax.repeat 0uy (sz 840) in + let randomness1:t_Array u8 (sz 840) = Rust_primitives.Hax.repeat 0uy (sz 840) in + let randomness2:t_Array u8 (sz 840) = Rust_primitives.Hax.repeat 0uy (sz 840) in + let randomness3:t_Array u8 (sz 840) = Rust_primitives.Hax.repeat 0uy (sz 840) in + let tmp0, tmp1, tmp2, tmp3, tmp4:(v_Shake128 & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840) & + t_Array u8 (sz 840)) = + Libcrux_ml_dsa.Hash_functions.Shake128.f_squeeze_first_five_blocks #v_Shake128 + #FStar.Tactics.Typeclasses.solve + state + randomness0 + randomness1 + randomness2 + randomness3 + in + let state:v_Shake128 = tmp0 in + let randomness0:t_Array u8 (sz 840) = tmp1 in + let randomness1:t_Array u8 (sz 840) = tmp2 in + let randomness2:t_Array u8 (sz 840) = tmp3 in + let randomness3:t_Array u8 (sz 840) = tmp4 in + let _:Prims.unit = () in + let coefficients0:t_Array i32 (sz 263) = Rust_primitives.Hax.repeat 0l (sz 263) in + let coefficients1:t_Array i32 (sz 263) = Rust_primitives.Hax.repeat 0l (sz 263) in + let coefficients2:t_Array i32 (sz 263) = Rust_primitives.Hax.repeat 0l (sz 263) in + let coefficients3:t_Array i32 (sz 263) = Rust_primitives.Hax.repeat 0l (sz 263) in + let sampled0:usize = sz 0 in + let sampled1:usize = sz 0 in + let sampled2:usize = sz 0 in + let sampled3:usize = sz 0 in + let tmp0, tmp1, out:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_field_modulus #v_SIMDUnit + (randomness0 <: t_Slice u8) + sampled0 + coefficients0 + in + let sampled0:usize = tmp0 in + let coefficients0:t_Array i32 (sz 263) = tmp1 in + let done0:bool = out in + let tmp0, tmp1, out:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_field_modulus #v_SIMDUnit + (randomness1 <: t_Slice u8) + sampled1 + coefficients1 + in + let sampled1:usize = tmp0 in + let coefficients1:t_Array i32 (sz 263) = tmp1 in + let done1:bool = out in + let tmp0, tmp1, out:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_field_modulus #v_SIMDUnit + (randomness2 <: t_Slice u8) + sampled2 + coefficients2 + in + let sampled2:usize = tmp0 in + let coefficients2:t_Array i32 (sz 263) = tmp1 in + let done2:bool = out in + let tmp0, tmp1, out:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_field_modulus #v_SIMDUnit + (randomness3 <: t_Slice u8) + sampled3 + coefficients3 + in + let sampled3:usize = tmp0 in + let coefficients3:t_Array i32 (sz 263) = tmp1 in + let done3:bool = out in + let + coefficients0, + coefficients1, + coefficients2, + coefficients3, + done0, + done1, + done2, + done3, + sampled0, + sampled1, + sampled2, + sampled3, + state:(t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + bool & + bool & + bool & + bool & + usize & + usize & + usize & + usize & + v_Shake128) = + Rust_primitives.f_while_loop (fun temp_0_ -> + let + coefficients0, + coefficients1, + coefficients2, + coefficients3, + done0, + done1, + done2, + done3, + sampled0, + sampled1, + sampled2, + sampled3, + state:(t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + bool & + bool & + bool & + bool & + usize & + usize & + usize & + usize & + v_Shake128) = + temp_0_ + in + (~.done0 <: bool) || (~.done1 <: bool) || (~.done2 <: bool) || (~.done3 <: bool)) + (coefficients0, + coefficients1, + coefficients2, + coefficients3, + done0, + done1, + done2, + done3, + sampled0, + sampled1, + sampled2, + sampled3, + state + <: + (t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + bool & + bool & + bool & + bool & + usize & + usize & + usize & + usize & + v_Shake128)) + (fun temp_0_ -> + let + coefficients0, + coefficients1, + coefficients2, + coefficients3, + done0, + done1, + done2, + done3, + sampled0, + sampled1, + sampled2, + sampled3, + state:(t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + bool & + bool & + bool & + bool & + usize & + usize & + usize & + usize & + v_Shake128) = + temp_0_ + in + let tmp0, out:(v_Shake128 & + (t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168))) + = + Libcrux_ml_dsa.Hash_functions.Shake128.f_squeeze_next_block #v_Shake128 + #FStar.Tactics.Typeclasses.solve + state + in + let state:v_Shake128 = tmp0 in + let randomnesses:(t_Array u8 (sz 168) & t_Array u8 (sz 168) & t_Array u8 (sz 168) & + t_Array u8 (sz 168)) = + out + in + let coefficients0, done0, sampled0:(t_Array i32 (sz 263) & bool & usize) = + if ~.done0 + then + let tmp0, tmp1, out:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_field_modulus #v_SIMDUnit + (randomnesses._1 <: t_Slice u8) + sampled0 + coefficients0 + in + let sampled0:usize = tmp0 in + let coefficients0:t_Array i32 (sz 263) = tmp1 in + let done0:bool = out in + coefficients0, done0, sampled0 <: (t_Array i32 (sz 263) & bool & usize) + else coefficients0, done0, sampled0 <: (t_Array i32 (sz 263) & bool & usize) + in + let coefficients1, done1, sampled1:(t_Array i32 (sz 263) & bool & usize) = + if ~.done1 + then + let tmp0, tmp1, out:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_field_modulus #v_SIMDUnit + (randomnesses._2 <: t_Slice u8) + sampled1 + coefficients1 + in + let sampled1:usize = tmp0 in + let coefficients1:t_Array i32 (sz 263) = tmp1 in + let done1:bool = out in + coefficients1, done1, sampled1 <: (t_Array i32 (sz 263) & bool & usize) + else coefficients1, done1, sampled1 <: (t_Array i32 (sz 263) & bool & usize) + in + let coefficients2, done2, sampled2:(t_Array i32 (sz 263) & bool & usize) = + if ~.done2 + then + let tmp0, tmp1, out:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_field_modulus #v_SIMDUnit + (randomnesses._3 <: t_Slice u8) + sampled2 + coefficients2 + in + let sampled2:usize = tmp0 in + let coefficients2:t_Array i32 (sz 263) = tmp1 in + let done2:bool = out in + coefficients2, done2, sampled2 <: (t_Array i32 (sz 263) & bool & usize) + else coefficients2, done2, sampled2 <: (t_Array i32 (sz 263) & bool & usize) + in + if ~.done3 + then + let tmp0, tmp1, out:(usize & t_Array i32 (sz 263) & bool) = + rejection_sample_less_than_field_modulus #v_SIMDUnit + (randomnesses._4 <: t_Slice u8) + sampled3 + coefficients3 + in + let sampled3:usize = tmp0 in + let coefficients3:t_Array i32 (sz 263) = tmp1 in + let done3:bool = out in + coefficients0, + coefficients1, + coefficients2, + coefficients3, + done0, + done1, + done2, + done3, + sampled0, + sampled1, + sampled2, + sampled3, + state + <: + (t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + bool & + bool & + bool & + bool & + usize & + usize & + usize & + usize & + v_Shake128) + else + coefficients0, + coefficients1, + coefficients2, + coefficients3, + done0, + done1, + done2, + done3, + sampled0, + sampled1, + sampled2, + sampled3, + state + <: + (t_Array i32 (sz 263) & t_Array i32 (sz 263) & t_Array i32 (sz 263) & + t_Array i32 (sz 263) & + bool & + bool & + bool & + bool & + usize & + usize & + usize & + usize & + v_Shake128)) + in + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (coefficients0 <: t_Slice i32), + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (coefficients1 <: t_Slice i32), + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (coefficients2 <: t_Slice i32), + Libcrux_ml_dsa.Polynomial.impl__from_i32_array #v_SIMDUnit (coefficients3 <: t_Slice i32) + <: + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + +let sample_mask_ring_element + (#v_SIMDUnit #v_Shake256: Type0) + (v_GAMMA1_EXPONENT: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (seed: t_Array u8 (sz 66)) + = + match cast (v_GAMMA1_EXPONENT <: usize) <: u8 with + | 17uy -> + let out:t_Array u8 (sz 576) = Rust_primitives.Hax.repeat 0uy (sz 576) in + let out:t_Array u8 (sz 576) = + Libcrux_ml_dsa.Hash_functions.Shake256.f_shake256 #v_Shake256 + #FStar.Tactics.Typeclasses.solve + (sz 576) + (seed <: t_Slice u8) + out + in + Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit v_GAMMA1_EXPONENT (out <: t_Slice u8) + | 19uy -> + let out:t_Array u8 (sz 640) = Rust_primitives.Hax.repeat 0uy (sz 640) in + let out:t_Array u8 (sz 640) = + Libcrux_ml_dsa.Hash_functions.Shake256.f_shake256 #v_Shake256 + #FStar.Tactics.Typeclasses.solve + (sz 640) + (seed <: t_Slice u8) + out + in + Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit v_GAMMA1_EXPONENT (out <: t_Slice u8) + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let sample_mask_vector + (#v_SIMDUnit #v_Shake256 #v_Shake256X4: Type0) + (v_DIMENSION v_GAMMA1_EXPONENT: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i5: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (seed: t_Array u8 (sz 66)) + (domain_separator: u16) + = + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION + in + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((v_DIMENSION =. sz 4 <: bool) || (v_DIMENSION =. sz 5 <: bool) || + (v_DIMENSION =. sz 7 <: bool)) + in + () + in + let tmp0, out4:(u16 & t_Array u8 (sz 66)) = update_seed seed domain_separator in + let domain_separator:u16 = tmp0 in + let seed0:t_Array u8 (sz 66) = out4 in + let tmp0, out4:(u16 & t_Array u8 (sz 66)) = update_seed seed domain_separator in + let domain_separator:u16 = tmp0 in + let seed1:t_Array u8 (sz 66) = out4 in + let tmp0, out4:(u16 & t_Array u8 (sz 66)) = update_seed seed domain_separator in + let domain_separator:u16 = tmp0 in + let seed2:t_Array u8 (sz 66) = out4 in + let tmp0, out4:(u16 & t_Array u8 (sz 66)) = update_seed seed domain_separator in + let domain_separator:u16 = tmp0 in + let seed3:t_Array u8 (sz 66) = out4 in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + match cast (v_GAMMA1_EXPONENT <: usize) <: u8 with + | 17uy -> + let out0:t_Array u8 (sz 576) = Rust_primitives.Hax.repeat 0uy (sz 576) in + let out1:t_Array u8 (sz 576) = Rust_primitives.Hax.repeat 0uy (sz 576) in + let out2:t_Array u8 (sz 576) = Rust_primitives.Hax.repeat 0uy (sz 576) in + let out3:t_Array u8 (sz 576) = Rust_primitives.Hax.repeat 0uy (sz 576) in + let tmp0, tmp1, tmp2, tmp3:(t_Array u8 (sz 576) & t_Array u8 (sz 576) & t_Array u8 (sz 576) & + t_Array u8 (sz 576)) = + Libcrux_ml_dsa.Hash_functions.Shake256.f_shake256_x4 #v_Shake256X4 + #FStar.Tactics.Typeclasses.solve (sz 576) (seed0 <: t_Slice u8) (seed1 <: t_Slice u8) + (seed2 <: t_Slice u8) (seed3 <: t_Slice u8) out0 out1 out2 out3 + in + let out0:t_Array u8 (sz 576) = tmp0 in + let out1:t_Array u8 (sz 576) = tmp1 in + let out2:t_Array u8 (sz 576) = tmp2 in + let out3:t_Array u8 (sz 576) = tmp3 in + let _:Prims.unit = () in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + (sz 0) + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (out0 <: t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + (sz 1) + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (out1 <: t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + (sz 2) + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (out2 <: t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + (sz 3) + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (out3 <: t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + mask + | 19uy -> + let out0:t_Array u8 (sz 640) = Rust_primitives.Hax.repeat 0uy (sz 640) in + let out1:t_Array u8 (sz 640) = Rust_primitives.Hax.repeat 0uy (sz 640) in + let out2:t_Array u8 (sz 640) = Rust_primitives.Hax.repeat 0uy (sz 640) in + let out3:t_Array u8 (sz 640) = Rust_primitives.Hax.repeat 0uy (sz 640) in + let tmp0, tmp1, tmp2, tmp3:(t_Array u8 (sz 640) & t_Array u8 (sz 640) & t_Array u8 (sz 640) & + t_Array u8 (sz 640)) = + Libcrux_ml_dsa.Hash_functions.Shake256.f_shake256_x4 #v_Shake256X4 + #FStar.Tactics.Typeclasses.solve (sz 640) (seed0 <: t_Slice u8) (seed1 <: t_Slice u8) + (seed2 <: t_Slice u8) (seed3 <: t_Slice u8) out0 out1 out2 out3 + in + let out0:t_Array u8 (sz 640) = tmp0 in + let out1:t_Array u8 (sz 640) = tmp1 in + let out2:t_Array u8 (sz 640) = tmp2 in + let out3:t_Array u8 (sz 640) = tmp3 in + let _:Prims.unit = () in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + (sz 0) + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (out0 <: t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + (sz 1) + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (out1 <: t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + (sz 2) + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (out2 <: t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + (sz 3) + (Libcrux_ml_dsa.Encoding.Gamma1.deserialize #v_SIMDUnit + v_GAMMA1_EXPONENT + (out3 <: t_Slice u8) + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + mask + | _ -> mask + in + let domain_separator, mask, seed:(u16 & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array u8 (sz 66)) = + Rust_primitives.Hax.Folds.fold_range (sz 4) + v_DIMENSION + (fun temp_0_ temp_1_ -> + let domain_separator, mask, seed:(u16 & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array u8 (sz 66)) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (domain_separator, mask, seed + <: + (u16 & t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array u8 (sz 66))) + (fun temp_0_ i -> + let domain_separator, mask, seed:(u16 & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array u8 (sz 66)) = + temp_0_ + in + let i:usize = i in + let seed:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed + (sz 64) + (cast (domain_separator <: u16) <: u8) + in + let seed:t_Array u8 (sz 66) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed + (sz 65) + (cast (domain_separator >>! 8l <: u16) <: u8) + in + let domain_separator:u16 = domain_separator +! 1us in + let mask:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize mask + i + (sample_mask_ring_element #v_SIMDUnit #v_Shake256 v_GAMMA1_EXPONENT seed + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + in + domain_separator, mask, seed + <: + (u16 & t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION & + t_Array u8 (sz 66))) + in + let hax_temp_output:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_DIMENSION = + mask + in + domain_separator, hax_temp_output + <: + (u16 & t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Sample.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Sample.fsti new file mode 100644 index 000000000..a742ab51f --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Sample.fsti @@ -0,0 +1,117 @@ +module Libcrux_ml_dsa.Sample +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Simd.Traits in + () + +val update_seed (seed: t_Array u8 (sz 66)) (domain_separator: u16) + : Prims.Pure (u16 & t_Array u8 (sz 66)) Prims.l_True (fun _ -> Prims.l_True) + +val rejection_sample_less_than_eta_equals_2_ + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (randomness: t_Slice u8) + (sampled_coefficients: usize) + (out: t_Array i32 (sz 263)) + : Prims.Pure (usize & t_Array i32 (sz 263) & bool) Prims.l_True (fun _ -> Prims.l_True) + +val rejection_sample_less_than_eta_equals_4_ + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (randomness: t_Slice u8) + (sampled_coefficients: usize) + (out: t_Array i32 (sz 263)) + : Prims.Pure (usize & t_Array i32 (sz 263) & bool) Prims.l_True (fun _ -> Prims.l_True) + +val rejection_sample_less_than_eta + (#v_SIMDUnit: Type0) + (v_ETA: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (randomness: t_Slice u8) + (sampled: usize) + (out: t_Array i32 (sz 263)) + : Prims.Pure (usize & t_Array i32 (sz 263) & bool) Prims.l_True (fun _ -> Prims.l_True) + +val rejection_sample_less_than_field_modulus + (#v_SIMDUnit: Type0) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (randomness: t_Slice u8) + (sampled_coefficients: usize) + (out: t_Array i32 (sz 263)) + : Prims.Pure (usize & t_Array i32 (sz 263) & bool) Prims.l_True (fun _ -> Prims.l_True) + +val inside_out_shuffle + (randomness: t_Slice u8) + (out_index: usize) + (signs: u64) + (result: t_Array i32 (sz 256)) + : Prims.Pure (usize & u64 & t_Array i32 (sz 256) & bool) Prims.l_True (fun _ -> Prims.l_True) + +val sample_challenge_ring_element + (#v_SIMDUnit #v_Shake256: Type0) + (v_NUMBER_OF_ONES v_SEED_SIZE: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + (seed: t_Array u8 v_SEED_SIZE) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val sample_four_error_ring_elements + (#v_SIMDUnit #v_Shake256: Type0) + (v_ETA: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256 |} + (seed_base: t_Array u8 (sz 66)) + (domain_separator0 domain_separator1 domain_seperator2 domain_separator3: u16) + : Prims.Pure + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val sample_four_ring_elements + (#v_SIMDUnit #v_Shake128: Type0) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128 |} + (seed0: t_Array u8 (sz 34)) + (domain_separator0 domain_separator1 domain_seperator2 domain_separator3: u16) + : Prims.Pure + (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val sample_mask_ring_element + (#v_SIMDUnit #v_Shake256: Type0) + (v_GAMMA1_EXPONENT: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + (seed: t_Array u8 (sz 66)) + : Prims.Pure (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val sample_mask_vector + (#v_SIMDUnit #v_Shake256 #v_Shake256X4: Type0) + (v_DIMENSION v_GAMMA1_EXPONENT: usize) + {| i3: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i4: Libcrux_ml_dsa.Hash_functions.Shake256.t_Xof v_Shake256 |} + {| i5: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + (seed: t_Array u8 (sz 66)) + (domain_separator: u16) + : Prims.Pure + (u16 & t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Samplex4.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Samplex4.fst new file mode 100644 index 000000000..ac648b477 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Samplex4.fst @@ -0,0 +1,1295 @@ +module Libcrux_ml_dsa.Samplex4 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Simd.Traits in + () + +let generate_domain_separator (row column: u8) = + (cast (column <: u8) <: u16) |. ((cast (row <: u8) <: u16) < matrix_A_4_by_4_ #v_SIMDUnit #v_Shake128X4 v_ROWS_IN_A v_COLUMNS_IN_A seed + | 6uy, 5uy -> matrix_A_6_by_5_ #v_SIMDUnit #v_Shake128X4 v_ROWS_IN_A v_COLUMNS_IN_A seed + | 8uy, 7uy -> matrix_A_8_by_7_ #v_SIMDUnit #v_Shake128X4 v_ROWS_IN_A v_COLUMNS_IN_A seed + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let sample_s1_and_s2_4_by_4_ + (#v_SIMDUnit #v_Shake256X4: Type0) + (v_ETA v_S1_DIMENSION v_S2_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (seed_base: t_Array u8 (sz 66)) + = + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_S1_DIMENSION + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_S2_DIMENSION + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 0us + 1us + 2us + 3us + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 0) four._1 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 1) four._2 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 2) four._3 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 3) four._4 + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 4us + 5us + 6us + 7us + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 0) four._1 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 1) four._2 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 2) four._3 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 3) four._4 + in + s1, s2 + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION) + +let sample_s1_and_s2_5_by_6_ + (#v_SIMDUnit #v_Shake256X4: Type0) + (v_ETA v_S1_DIMENSION v_S2_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (seed_base: t_Array u8 (sz 66)) + = + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_S1_DIMENSION + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_S2_DIMENSION + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 0us + 1us + 2us + 3us + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 0) four._1 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 1) four._2 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 2) four._3 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 3) four._4 + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 4us + 5us + 6us + 7us + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 4) four._1 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 0) four._2 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 1) four._3 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 2) four._4 + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 8us + 9us + 10us + 11us + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 3) four._1 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 4) four._2 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 5) four._3 + in + s1, s2 + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION) + +let sample_s1_and_s2_7_by_8_ + (#v_SIMDUnit #v_Shake256X4: Type0) + (v_ETA v_S1_DIMENSION v_S2_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (seed_base: t_Array u8 (sz 66)) + = + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_S1_DIMENSION + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.repeat (Libcrux_ml_dsa.Polynomial.impl__ZERO #v_SIMDUnit () + <: + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_S2_DIMENSION + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 0us + 1us + 2us + 3us + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 0) four._1 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 1) four._2 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 2) four._3 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 3) four._4 + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 4us + 5us + 6us + 7us + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 4) four._1 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 5) four._2 + in + let s1:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s1 (sz 6) four._3 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 0) four._4 + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 8us + 9us + 10us + 11us + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 1) four._1 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 2) four._2 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 3) four._3 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 4) four._4 + in + let four:(Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit & + Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) = + Libcrux_ml_dsa.Sample.sample_four_error_ring_elements #v_SIMDUnit + #v_Shake256X4 + v_ETA + seed_base + 12us + 13us + 14us + 15us + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 5) four._1 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 6) four._2 + in + let s2:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize s2 (sz 7) four._3 + in + s1, s2 + <: + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION) + +let sample_s1_and_s2 + (#v_SIMDUnit #v_Shake256X4: Type0) + (v_ETA v_S1_DIMENSION v_S2_DIMENSION: usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4) + (seed: t_Array u8 (sz 66)) + = + match + (cast (v_S1_DIMENSION <: usize) <: u8), (cast (v_S2_DIMENSION <: usize) <: u8) <: (u8 & u8) + with + | 4uy, 4uy -> + sample_s1_and_s2_4_by_4_ #v_SIMDUnit #v_Shake256X4 v_ETA v_S1_DIMENSION v_S2_DIMENSION seed + | 5uy, 6uy -> + sample_s1_and_s2_5_by_6_ #v_SIMDUnit #v_Shake256X4 v_ETA v_S1_DIMENSION v_S2_DIMENSION seed + | 7uy, 8uy -> + sample_s1_and_s2_7_by_8_ #v_SIMDUnit #v_Shake256X4 v_ETA v_S1_DIMENSION v_S2_DIMENSION seed + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Samplex4.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Samplex4.fsti new file mode 100644 index 000000000..a914aec27 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Samplex4.fsti @@ -0,0 +1,121 @@ +module Libcrux_ml_dsa.Samplex4 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Hash_functions.Shake128 in + let open Libcrux_ml_dsa.Hash_functions.Shake256 in + let open Libcrux_ml_dsa.Simd.Traits in + () + +val generate_domain_separator (row column: u8) : Prims.Pure u16 Prims.l_True (fun _ -> Prims.l_True) + +val update_matrix + (#v_SIMDUnit: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + (m: + t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) + (i j: usize) + (v: Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + : Prims.Pure + (t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) Prims.l_True (fun _ -> Prims.l_True) + +val matrix_A_4_by_4_ + (#v_SIMDUnit #v_Shake128X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + (seed: t_Array u8 (sz 34)) + : Prims.Pure + (t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) Prims.l_True (fun _ -> Prims.l_True) + +val matrix_A_6_by_5_ + (#v_SIMDUnit #v_Shake128X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + (seed: t_Array u8 (sz 34)) + : Prims.Pure + (t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) Prims.l_True (fun _ -> Prims.l_True) + +val matrix_A_8_by_7_ + (#v_SIMDUnit #v_Shake128X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + (seed: t_Array u8 (sz 34)) + : Prims.Pure + (t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) Prims.l_True (fun _ -> Prims.l_True) + +val matrix_A + (#v_SIMDUnit #v_Shake128X4: Type0) + (v_ROWS_IN_A v_COLUMNS_IN_A: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake128.t_XofX4 v_Shake128X4 |} + (seed: t_Array u8 (sz 34)) + : Prims.Pure + (t_Array + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_COLUMNS_IN_A) + v_ROWS_IN_A) Prims.l_True (fun _ -> Prims.l_True) + +val sample_s1_and_s2_4_by_4_ + (#v_SIMDUnit #v_Shake256X4: Type0) + (v_ETA v_S1_DIMENSION v_S2_DIMENSION: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + (seed_base: t_Array u8 (sz 66)) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val sample_s1_and_s2_5_by_6_ + (#v_SIMDUnit #v_Shake256X4: Type0) + (v_ETA v_S1_DIMENSION v_S2_DIMENSION: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + (seed_base: t_Array u8 (sz 66)) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val sample_s1_and_s2_7_by_8_ + (#v_SIMDUnit #v_Shake256X4: Type0) + (v_ETA v_S1_DIMENSION v_S2_DIMENSION: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + (seed_base: t_Array u8 (sz 66)) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) + +val sample_s1_and_s2 + (#v_SIMDUnit #v_Shake256X4: Type0) + (v_ETA v_S1_DIMENSION v_S2_DIMENSION: usize) + {| i2: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + {| i3: Libcrux_ml_dsa.Hash_functions.Shake256.t_XofX4 v_Shake256X4 |} + (seed: t_Array u8 (sz 66)) + : Prims.Pure + (t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S1_DIMENSION & + t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) v_S2_DIMENSION) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Arithmetic.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Arithmetic.fst new file mode 100644 index 000000000..3dd67c65e --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Arithmetic.fst @@ -0,0 +1,366 @@ +module Libcrux_ml_dsa.Simd.Avx2.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let add (lhs rhs: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + Libcrux_intrinsics.Avx2_extract.mm256_add_epi32 lhs rhs + +let compute_hint (v_GAMMA2: i32) (low high: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + let gamma2:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 v_GAMMA2 + in + let minus_gamma2:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (Core.Ops.Arith.Neg.neg v_GAMMA2 <: i32) + in + let low_within_bound:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_cmpgt_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_abs_epi32 + low + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + gamma2 + in + let low_equals_minus_gamma2:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_cmpeq_epi32 low minus_gamma2 + in + let low_equals_minus_gamma2_and_high_is_nonzero:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sign_epi32 low_equals_minus_gamma2 high + in + let hints:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_or_si256 low_within_bound + low_equals_minus_gamma2_and_high_is_nonzero + in + let hints_mask:i32 = + Libcrux_intrinsics.Avx2_extract.mm256_movemask_ps (Libcrux_intrinsics.Avx2_extract.mm256_castsi256_ps + hints + <: + u8) + in + (cast (Core.Num.impl__i32__count_ones hints_mask <: u32) <: usize), + Libcrux_intrinsics.Avx2_extract.mm256_and_si256 hints + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 1l <: Libcrux_intrinsics.Avx2_extract.t_Vec256 + ) + <: + (usize & Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let infinity_norm_exceeds (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) (bound: i32) = + let absolute_values:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_abs_epi32 simd_unit + in + let bound:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (bound -! 1l <: i32) + in + let compare_with_bound:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_cmpgt_epi32 absolute_values bound + in + let result:i32 = + Libcrux_intrinsics.Avx2_extract.mm256_testz_si256 compare_with_bound compare_with_bound + in + if result =. 1l then false else true + +let subtract (lhs rhs: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 lhs rhs + +let shift_left_then_reduce (v_SHIFT_BY: i32) (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + let shifted:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_slli_epi32 v_SHIFT_BY simd_unit + in + let quotient:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_add_epi32 shifted + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (1l < + let result:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mullo_epi32 ceil_of_r_by_128_ + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 11275l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let result:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_add_epi32 result + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (1l < + let result:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mullo_epi32 ceil_of_r_by_128_ + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 1025l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let result:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_add_epi32 result + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (1l < + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + in + let r0:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mullo_epi32 r1 + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 v_ALPHA + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let r0:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 r r0 + in + let mask:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 field_modulus_halved r0 + in + let mask:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srai_epi32 31l mask + in + let field_modulus_and_mask:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_and_si256 mask + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let r0:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 r0 field_modulus_and_mask + in + r0, r1 <: (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let use_hint (v_GAMMA2: i32) (r hint: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + let r0, r1:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) = + decompose v_GAMMA2 r + in + let all_zeros:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_setzero_si256 () + in + let negate_hints:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.vec256_blendv_epi32 all_zeros hint r0 + in + let negate_hints:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_slli_epi32 1l negate_hints + in + let hints:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 hint negate_hints + in + let r1_plus_hints:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_add_epi32 r1 hints + in + match v_GAMMA2 with + | 95232l -> + let max:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 43l + in + let r1_plus_hints:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.vec256_blendv_epi32 r1_plus_hints max r1_plus_hints + in + let greater_than_or_equal_to_max:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_cmpgt_epi32 r1_plus_hints max + in + Libcrux_intrinsics.Avx2_extract.vec256_blendv_epi32 r1_plus_hints + all_zeros + greater_than_or_equal_to_max + | 261888l -> + Libcrux_intrinsics.Avx2_extract.mm256_and_si256 r1_plus_hints + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 15l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Arithmetic.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Arithmetic.fsti new file mode 100644 index 000000000..a8ec4e3d7 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Arithmetic.fsti @@ -0,0 +1,45 @@ +module Libcrux_ml_dsa.Simd.Avx2.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +val add (lhs rhs: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val compute_hint (v_GAMMA2: i32) (low high: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (usize & Libcrux_intrinsics.Avx2_extract.t_Vec256) + Prims.l_True + (fun _ -> Prims.l_True) + +val infinity_norm_exceeds (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) (bound: i32) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + +val subtract (lhs rhs: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val shift_left_then_reduce (v_SHIFT_BY: i32) (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val to_unsigned_representatives (t: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val power2round (r: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + Prims.l_True + (fun _ -> Prims.l_True) + +val montgomery_multiply (lhs rhs: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val montgomery_multiply_by_constant (lhs: Libcrux_intrinsics.Avx2_extract.t_Vec256) (constant: i32) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val decompose (v_GAMMA2: i32) (r: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + Prims.l_True + (fun _ -> Prims.l_True) + +val use_hint (v_GAMMA2: i32) (r hint: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment.fst new file mode 100644 index 000000000..5f1406970 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment.fst @@ -0,0 +1,151 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let serialize (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + let serialized:t_Array u8 (sz 19) = Rust_primitives.Hax.repeat 0uy (sz 19) in + match cast (v_OUTPUT_SIZE <: usize) <: u8 with + | 4uy -> + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 simd_unit + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 28l 0l 28l 0l 28l 0l 28l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 28l adjacent_2_combined + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permutevar8x32_epi32 adjacent_2_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 0l 0l 0l 6l 2l 4l 0l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 adjacent_4_combined + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_shuffle_epi8 adjacent_4_combined + (Libcrux_intrinsics.Avx2_extract.mm_set_epi8 240uy 240uy 240uy 240uy 240uy 240uy 240uy 240uy + 240uy 240uy 240uy 240uy 12uy 4uy 8uy 0uy + <: + Libcrux_intrinsics.Avx2_extract.t_Vec128) + in + let serialized:t_Array u8 (sz 19) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_bytes_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 16 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + adjacent_4_combined + <: + t_Slice u8) + in + Core.Result.impl__unwrap #(t_Array u8 v_OUTPUT_SIZE) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 v_OUTPUT_SIZE) + #FStar.Tactics.Typeclasses.solve + (serialized.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 4 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + <: + Core.Result.t_Result (t_Array u8 v_OUTPUT_SIZE) Core.Array.t_TryFromSliceError) + | 6uy -> + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 simd_unit + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 26l 0l 26l 0l 26l 0l 26l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 26l adjacent_2_combined + in + let adjacent_3_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi8 adjacent_2_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi8 (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) + (-1y) (-1y) (-1y) (-1y) (-1y) 9y 8y 1y 0y (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) + (-1y) (-1y) (-1y) (-1y) (-1y) 9y 8y 1y 0y + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_3_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mullo_epi16 adjacent_3_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi16 1s 1s 1s 1s 1s 1s 1s (1s < + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment.fsti new file mode 100644 index 000000000..58e2355b6 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment.fsti @@ -0,0 +1,7 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +val serialize (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.fst new file mode 100644 index 000000000..a8ea63851 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.fst @@ -0,0 +1,251 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.Error +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize_to_unsigned_when_eta_is_2_ (bytes: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 bytes <: usize) =. sz 3 <: bool) + in + () + in + let bytes_in_simd_unit:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 (cast (bytes.[ sz 2 ] <: u8) <: i32) + (cast (bytes.[ sz 2 ] <: u8) <: i32) + (((cast (bytes.[ sz 2 ] <: u8) <: i32) < deserialize_to_unsigned_when_eta_is_2_ serialized + | 4uy -> deserialize_to_unsigned_when_eta_is_4_ serialized + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let deserialize (v_ETA: usize) (serialized: t_Slice u8) = + let unsigned:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + deserialize_to_unsigned v_ETA serialized + in + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 ( + cast (v_ETA <: usize) <: i32) + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + unsigned + +let serialize_when_eta_is_2_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + = + let serialized:t_Array u8 (sz 16) = Rust_primitives.Hax.repeat 0uy (sz 16) in + let simd_unit_shifted:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 + serialize_when_eta_is_2___ETA + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + simd_unit + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 simd_unit_shifted + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 29l 0l 29l 0l 29l 0l 29l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 29l adjacent_2_combined + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi8 adjacent_2_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi8 (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) + (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) 8y (-1y) 0y (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) + (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) 8y (-1y) 0y + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_madd_epi16 adjacent_4_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi16 0s 0s 0s 0s 0s 0s (1s < serialize_when_eta_is_2_ v_OUTPUT_SIZE simd_unit + | 4uy -> serialize_when_eta_is_4_ v_OUTPUT_SIZE simd_unit + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.fsti new file mode 100644 index 000000000..11a0e04cf --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.fsti @@ -0,0 +1,37 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.Error +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize_to_unsigned_when_eta_is_2___COEFFICIENT_MASK: i32 = (1l < Prims.l_True) + +val deserialize_to_unsigned_when_eta_is_4_ (bytes: t_Slice u8) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val deserialize_to_unsigned (v_ETA: usize) (serialized: t_Slice u8) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val deserialize (v_ETA: usize) (serialized: t_Slice u8) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val serialize_when_eta_is_2_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_when_eta_is_4_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val serialize (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1.fst new file mode 100644 index 000000000..c7012e6cb --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1.fst @@ -0,0 +1,311 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize_when_gamma1_is_2_pow_17_ (serialized: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 serialized <: usize) =. sz 18 <: bool) + in + () + in + let serialized_lower:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 16 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + in + let serialized_upper:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 2; + Core.Ops.Range.f_end = sz 18 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + in + let serialized:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_m128i serialized_upper serialized_lower + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi8 serialized + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi8 (-1y) 15y 14y 13y (-1y) 13y 12y 11y (-1y) 11y + 10y 9y (-1y) 9y 8y 7y (-1y) 8y 7y 6y (-1y) 6y 5y 4y (-1y) 4y 3y 2y (-1y) 2y 1y 0y + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srlv_epi32 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 6l 4l 2l 0l 6l 4l 2l 0l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_and_si256 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 deserialize_when_gamma1_is_2_pow_17___GAMMA1_TIMES_2_MASK + + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 deserialize_when_gamma1_is_2_pow_17___GAMMA1 + + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + coefficients + +let deserialize_when_gamma1_is_2_pow_19_ (serialized: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 serialized <: usize) =. sz 20 <: bool) + in + () + in + let serialized_lower:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 16 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + in + let serialized_upper:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 4; + Core.Ops.Range.f_end = sz 20 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + in + let serialized:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_m128i serialized_upper serialized_lower + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi8 serialized + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi8 (-1y) 15y 14y 13y (-1y) 13y 12y 11y (-1y) 10y + 9y 8y (-1y) 8y 7y 6y (-1y) 9y 8y 7y (-1y) 7y 6y 5y (-1y) 4y 3y 2y (-1y) 2y 1y 0y + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srlv_epi32 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 4l 0l 4l 0l 4l 0l 4l 0l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_and_si256 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 deserialize_when_gamma1_is_2_pow_19___GAMMA1_TIMES_2_MASK + + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 deserialize_when_gamma1_is_2_pow_19___GAMMA1 + + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + coefficients + +let deserialize (v_GAMMA1_EXPONENT: usize) (serialized: t_Slice u8) = + match cast (v_GAMMA1_EXPONENT <: usize) <: u8 with + | 17uy -> deserialize_when_gamma1_is_2_pow_17_ serialized + | 19uy -> deserialize_when_gamma1_is_2_pow_19_ serialized + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let serialize_when_gamma1_is_2_pow_17_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + = + let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let simd_unit_shifted:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 + serialize_when_gamma1_is_2_pow_17___GAMMA1 + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + simd_unit + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 simd_unit_shifted + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 14l 0l 14l 0l 14l 0l 14l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 14l adjacent_2_combined + in + let every_second_element:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_bsrli_epi128 8l adjacent_2_combined + in + let every_second_element_shifted:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_slli_epi64 36l every_second_element + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_add_epi64 adjacent_2_combined every_second_element_shifted + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srlv_epi64 adjacent_4_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi64x 28L 0L 28L 0L + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let lower_4_:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 adjacent_4_combined + in + let serialized:t_Array u8 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_bytes_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 16 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + lower_4_ + <: + t_Slice u8) + in + let upper_4_:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_extracti128_si256 1l adjacent_4_combined + in + let serialized:t_Array u8 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ Core.Ops.Range.f_start = sz 9; Core.Ops.Range.f_end = sz 25 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_bytes_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 9; + Core.Ops.Range.f_end = sz 25 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + upper_4_ + <: + t_Slice u8) + in + Core.Result.impl__unwrap #(t_Array u8 v_OUTPUT_SIZE) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 v_OUTPUT_SIZE) + #FStar.Tactics.Typeclasses.solve + (serialized.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 18 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + <: + Core.Result.t_Result (t_Array u8 v_OUTPUT_SIZE) Core.Array.t_TryFromSliceError) + +let serialize_when_gamma1_is_2_pow_19_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + = + let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let simd_unit_shifted:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 + serialize_when_gamma1_is_2_pow_19___GAMMA1 + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + simd_unit + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 simd_unit_shifted + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 12l 0l 12l 0l 12l 0l 12l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 12l adjacent_2_combined + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi8 adjacent_2_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi8 (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) 12y 11y + 10y 9y 8y 4y 3y 2y 1y 0y (-1y) (-1y) (-1y) (-1y) (-1y) (-1y) 12y 11y 10y 9y 8y 4y 3y 2y 1y + 0y + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let lower_4_:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 adjacent_4_combined + in + let serialized:t_Array u8 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_bytes_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 16 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + lower_4_ + <: + t_Slice u8) + in + let upper_4_:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_extracti128_si256 1l adjacent_4_combined + in + let serialized:t_Array u8 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ Core.Ops.Range.f_start = sz 10; Core.Ops.Range.f_end = sz 26 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_bytes_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 10; + Core.Ops.Range.f_end = sz 26 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + upper_4_ + <: + t_Slice u8) + in + Core.Result.impl__unwrap #(t_Array u8 v_OUTPUT_SIZE) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 v_OUTPUT_SIZE) + #FStar.Tactics.Typeclasses.solve + (serialized.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 20 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + <: + Core.Result.t_Result (t_Array u8 v_OUTPUT_SIZE) Core.Array.t_TryFromSliceError) + +let serialize (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + match cast (v_OUTPUT_SIZE <: usize) <: u8 with + | 18uy -> serialize_when_gamma1_is_2_pow_17_ v_OUTPUT_SIZE simd_unit + | 20uy -> serialize_when_gamma1_is_2_pow_19_ v_OUTPUT_SIZE simd_unit + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1.fsti new file mode 100644 index 000000000..09917efd7 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1.fsti @@ -0,0 +1,40 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize_when_gamma1_is_2_pow_17___GAMMA1: i32 = 1l < Prims.l_True) + +val deserialize_when_gamma1_is_2_pow_19_ (serialized: t_Slice u8) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val deserialize (v_GAMMA1_EXPONENT: usize) (serialized: t_Slice u8) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val serialize_when_gamma1_is_2_pow_17_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_when_gamma1_is_2_pow_19_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val serialize (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T0.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T0.fst new file mode 100644 index 000000000..cf9feff51 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T0.fst @@ -0,0 +1,128 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.T0 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let change_interval (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + let interval_end:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (1l < Hax_lib.v_assert (left_val =. right_val <: bool) + in + () + in + let serialized_extended:t_Array u8 (sz 16) = Rust_primitives.Hax.repeat 0uy (sz 16) in + let serialized_extended:t_Array u8 (sz 16) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized_extended + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 13 } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized_extended.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 13 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + serialized + <: + t_Slice u8) + in + let serialized:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (serialized_extended <: t_Slice u8) + in + let serialized:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_m128i serialized serialized + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi8 serialized + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi8 (-1y) (-1y) 12y 11y (-1y) 11y 10y 9y (-1y) + (-1y) 9y 8y (-1y) 8y 7y 6y (-1y) 6y 5y 4y (-1y) (-1y) 4y 3y (-1y) 3y 2y 1y (-1y) (-1y) 1y + 0y + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srlv_epi32 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 3l 6l 1l 4l 7l 2l 5l 0l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_and_si256 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 deserialize__COEFFICIENT_MASK + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + change_interval coefficients + +let serialize (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + let serialized:t_Array u8 (sz 16) = Rust_primitives.Hax.repeat 0uy (sz 16) in + let simd_unit:Libcrux_intrinsics.Avx2_extract.t_Vec256 = change_interval simd_unit in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 simd_unit + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 19l 0l 19l 0l 19l 0l 19l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 19l adjacent_2_combined + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permutevar8x32_epi32 adjacent_2_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 0l 0l 0l 6l 4l 2l 0l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 adjacent_4_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 6l 0l 6l 0l 6l 0l 6l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 6l adjacent_4_combined + in + let second_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_bsrli_epi128 8l adjacent_4_combined + in + let least_12_bits_shifted_up:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_slli_epi64 52l second_4_combined + in + let bits_sequential:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_add_epi64 adjacent_4_combined least_12_bits_shifted_up + in + let bits_sequential:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srlv_epi64 bits_sequential + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi64x 0L 0L 12L 0L + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let bits_sequential:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 bits_sequential + in + let serialized:t_Array u8 (sz 16) = + Libcrux_intrinsics.Avx2_extract.mm_storeu_bytes_si128 serialized bits_sequential + in + Core.Result.impl__unwrap #(t_Array u8 (sz 13)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 (sz 13)) + #FStar.Tactics.Typeclasses.solve + (serialized.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 13 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + <: + Core.Result.t_Result (t_Array u8 (sz 13)) Core.Array.t_TryFromSliceError) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T0.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T0.fsti new file mode 100644 index 000000000..6ecaf9832 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T0.fsti @@ -0,0 +1,15 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.T0 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +val change_interval (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +let deserialize__COEFFICIENT_MASK: i32 = (1l < Prims.l_True) + +val serialize (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure (t_Array u8 (sz 13)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T1.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T1.fst new file mode 100644 index 000000000..5c03793af --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T1.fst @@ -0,0 +1,134 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.T1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let serialize (simd_unit: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + let serialized:t_Array u8 (sz 24) = Rust_primitives.Hax.repeat 0uy (sz 24) in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 simd_unit + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 22l 0l 22l 0l 22l 0l 22l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_2_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 22l adjacent_2_combined + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permutevar8x32_epi32 adjacent_2_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 0l 6l 4l 0l 0l 2l 0l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sllv_epi32 adjacent_4_combined + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 12l 0l 12l 0l 12l 0l 12l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let adjacent_4_combined:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srli_epi64 12l adjacent_4_combined + in + let lower_4_:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 adjacent_4_combined + in + let serialized:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 16 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_bytes_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 16 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + lower_4_ + <: + t_Slice u8) + in + let upper_4_:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_extracti128_si256 1l adjacent_4_combined + in + let serialized:t_Array u8 (sz 24) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized + ({ Core.Ops.Range.f_start = sz 5; Core.Ops.Range.f_end = sz 21 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_bytes_si128 (serialized.[ { + Core.Ops.Range.f_start = sz 5; + Core.Ops.Range.f_end = sz 21 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + upper_4_ + <: + t_Slice u8) + in + Core.Result.impl__unwrap #(t_Array u8 (sz 10)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice u8) + #(t_Array u8 (sz 10)) + #FStar.Tactics.Typeclasses.solve + (serialized.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 10 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + <: + Core.Result.t_Result (t_Array u8 (sz 10)) Core.Array.t_TryFromSliceError) + +let deserialize (bytes: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + match Core.Slice.impl__len #u8 bytes, sz 10 <: (usize & usize) with + | left_val, right_val -> Hax_lib.v_assert (left_val =. right_val <: bool) + in + () + in + let bytes_extended:t_Array u8 (sz 16) = Rust_primitives.Hax.repeat 0uy (sz 16) in + let bytes_extended:t_Array u8 (sz 16) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range bytes_extended + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 10 } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (bytes_extended.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 10 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + bytes + <: + t_Slice u8) + in + let bytes_loaded:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (bytes_extended <: t_Slice u8) + in + let bytes_loaded:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_m128i bytes_loaded bytes_loaded + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi8 bytes_loaded + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi8 (-1y) (-1y) 9y 8y (-1y) (-1y) 8y 7y (-1y) + (-1y) 7y 6y (-1y) (-1y) 6y 5y (-1y) (-1y) 4y 3y (-1y) (-1y) 3y 2y (-1y) (-1y) 2y 1y (-1y) + (-1y) 1y 0y + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srlv_epi32 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 6l 4l 2l 0l 6l 4l 2l 0l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + Libcrux_intrinsics.Avx2_extract.mm256_and_si256 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 deserialize__COEFFICIENT_MASK + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T1.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T1.fsti new file mode 100644 index 000000000..53c46df38 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Encoding.T1.fsti @@ -0,0 +1,12 @@ +module Libcrux_ml_dsa.Simd.Avx2.Encoding.T1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize__COEFFICIENT_MASK: i32 = (1l < Prims.l_True) + +val deserialize (bytes: t_Slice u8) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Invntt.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Invntt.fst new file mode 100644 index 000000000..dc0b422fd --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Invntt.fst @@ -0,0 +1,542 @@ +module Libcrux_ml_dsa.Simd.Avx2.Invntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let simd_unit_invert_ntt_at_layer_0_ + (simd_unit0 simd_unit1: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta00 zeta01 zeta02 zeta03 zeta10 zeta11 zeta12 zeta13: i32) + = + let a_shuffled:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 216l simd_unit0 + in + let b_shuffled:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 216l simd_unit1 + in + let lo_values:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpacklo_epi64 a_shuffled b_shuffled + in + let hi_values:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpackhi_epi64 a_shuffled b_shuffled + in + let sums:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add lo_values hi_values + in + let differences:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract hi_values lo_values + in + let zetas:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 zeta13 + zeta12 + zeta03 + zeta02 + zeta11 + zeta10 + zeta01 + zeta00 + in + let products:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply differences zetas + in + let a_shuffled:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpacklo_epi64 sums products + in + let b_shuffled:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpackhi_epi64 sums products + in + let a:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 216l a_shuffled + in + let b:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 216l b_shuffled + in + a, b <: (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let invert_ntt_at_layer_0___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta00 zeta01 zeta02 zeta03 zeta10 zeta11 zeta12 zeta13: i32) + = + let lhs, lhs_1_:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & + Libcrux_intrinsics.Avx2_extract.t_Vec256) = + simd_unit_invert_ntt_at_layer_0_ (re.[ index ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (re.[ index +! sz 1 <: usize ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) zeta00 zeta01 + zeta02 zeta03 zeta10 zeta11 zeta12 zeta13 + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re index lhs + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re (index +! sz 1 <: usize) lhs_1_ + in + let _:Prims.unit = () in + re + +let invert_ntt_at_layer_0_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 0) 1976782l (-846154l) 1400424l 3937738l (-1362209l) + (-48306l) 3919660l (-554416l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 2) (-3545687l) 1612842l (-976891l) 183443l (-2286327l) + (-420899l) (-2235985l) (-2939036l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 4) (-3833893l) (-260646l) (-1104333l) (-1667432l) 1910376l + (-1803090l) 1723600l (-426683l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 6) 472078l 1717735l (-975884l) 2213111l 269760l 3866901l + 3523897l (-3038916l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 8) (-1799107l) (-3694233l) 1652634l 810149l 3014001l + 1616392l 162844l (-3183426l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 10) (-1207385l) 185531l 3369112l 1957272l (-164721l) + 2454455l 2432395l (-2013608l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 12) (-3776993l) 594136l (-3724270l) (-2584293l) (-1846953l) + (-1671176l) (-2831860l) (-542412l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 14) 3406031l 2235880l 777191l 1500165l (-1374803l) + (-2546312l) 1917081l (-1279661l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 16) (-1962642l) 3306115l 1312455l (-451100l) (-1430225l) + (-3318210l) 1237275l (-1333058l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 18) (-1050970l) 1903435l 1869119l (-2994039l) (-3548272l) + 2635921l 1250494l (-3767016l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 20) 1595974l 2486353l 1247620l 4055324l 1265009l + (-2590150l) 2691481l 2842341l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 22) 203044l 1735879l (-3342277l) 3437287l 4108315l + (-2437823l) 286988l 342297l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 24) (-3595838l) (-768622l) (-525098l) (-3556995l) 3207046l + 2031748l (-3122442l) (-655327l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 26) (-522500l) (-43260l) (-1613174l) 495491l 819034l + 909542l 1859098l 900702l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 28) (-3193378l) (-1197226l) (-3759364l) (-3520352l) + 3513181l (-1235728l) 2434439l 266997l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_0___round re (sz 30) (-3562462l) (-2446433l) 2244091l (-3342478l) 3817976l + 2316500l 3407706l 2091667l + in + re + +let simd_unit_invert_ntt_at_layer_1_ + (simd_unit0 simd_unit1: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta00 zeta01 zeta10 zeta11: i32) + = + let lo_values:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpacklo_epi64 simd_unit0 simd_unit1 + in + let hi_values:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpackhi_epi64 simd_unit0 simd_unit1 + in + let sums:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add lo_values hi_values + in + let differences:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract hi_values lo_values + in + let zetas:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 zeta11 + zeta11 + zeta01 + zeta01 + zeta10 + zeta10 + zeta00 + zeta00 + in + let products:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply differences zetas + in + let a:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpacklo_epi64 sums products + in + let b:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpackhi_epi64 sums products + in + a, b <: (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let invert_ntt_at_layer_1___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta_00_ zeta_01_ zeta_10_ zeta_11_: i32) + = + let lhs, lhs_1_:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & + Libcrux_intrinsics.Avx2_extract.t_Vec256) = + simd_unit_invert_ntt_at_layer_1_ (re.[ index ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (re.[ index +! sz 1 <: usize ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + zeta_00_ + zeta_01_ + zeta_10_ + zeta_11_ + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re index lhs + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re (index +! sz 1 <: usize) lhs_1_ + in + let _:Prims.unit = () in + re + +let invert_ntt_at_layer_1_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 0) 3839961l (-3628969l) (-3881060l) (-3019102l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 2) (-1439742l) (-812732l) (-1584928l) 1285669l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 4) 1341330l 1315589l (-177440l) (-2409325l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 6) (-1851402l) 3159746l (-3553272l) 189548l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 8) (-1316856l) 759969l (-210977l) 2389356l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 10) (-3249728l) 1653064l (-8578l) (-3724342l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 12) 3958618l 904516l (-1100098l) 44288l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 14) 3097992l 508951l 264944l (-3343383l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 16) (-1430430l) 1852771l 1349076l (-381987l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 18) (-1308169l) (-22981l) (-1228525l) (-671102l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 20) (-2477047l) (-411027l) (-3693493l) (-2967645l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 22) 2715295l 2147896l (-983419l) 3412210l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 24) 126922l (-3632928l) (-3157330l) (-3190144l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 26) (-1000202l) (-4083598l) 1939314l (-1257611l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 28) (-1585221l) 2176455l 3475950l (-1452451l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_1___round re (sz 30) (-3041255l) (-3677745l) (-1528703l) (-3930395l) + in + re + +let simd_unit_invert_ntt_at_layer_2_ + (simd_unit0 simd_unit1: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta0 zeta1: i32) + = + let lo_values:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permute2x128_si256 32l simd_unit0 simd_unit1 + in + let hi_values:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permute2x128_si256 49l simd_unit0 simd_unit1 + in + let sums:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add lo_values hi_values + in + let differences:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract hi_values lo_values + in + let zetas:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 zeta1 zeta1 zeta1 zeta1 zeta0 zeta0 zeta0 zeta0 + in + let products:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply differences zetas + in + let a:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permute2x128_si256 32l sums products + in + let b:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permute2x128_si256 49l sums products + in + a, b <: (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let invert_ntt_at_layer_2___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta1 zeta2: i32) + = + let lhs, lhs_1_:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & + Libcrux_intrinsics.Avx2_extract.t_Vec256) = + simd_unit_invert_ntt_at_layer_2_ (re.[ index ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (re.[ index +! sz 1 <: usize ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + zeta1 + zeta2 + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re index lhs + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re (index +! sz 1 <: usize) lhs_1_ + in + let _:Prims.unit = () in + re + +let invert_ntt_at_layer_2_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 0) (-2797779l) 2071892l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 2) (-2556880l) 3900724l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 4) 3881043l 954230l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 6) 531354l 811944l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 8) 3699596l (-1600420l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 10) (-2140649l) 3507263l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 12) (-3821735l) 3505694l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 14) (-1643818l) (-1699267l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 16) (-539299l) 2348700l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 18) (-300467l) 3539968l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 20) (-2867647l) 3574422l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 22) (-3043716l) (-3861115l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 24) 3915439l (-2537516l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 26) (-3592148l) (-1661693l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 28) 3530437l 3077325l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + invert_ntt_at_layer_2___round re (sz 30) 95776l 2706023l + in + re + +let outer_3_plus + (v_OFFSET v_STEP_BY: usize) + (v_ZETA: i32) + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Folds.fold_range v_OFFSET + (v_OFFSET +! v_STEP_BY <: usize) + (fun re temp_1_ -> + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = re in + let _:usize = temp_1_ in + true) + re + (fun re j -> + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = re in + let j:usize = j in + let a_minus_b:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract (re.[ j +! v_STEP_BY <: usize ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + (re.[ j ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + j + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add (re.[ j ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + (re.[ j +! v_STEP_BY <: usize ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + (j +! v_STEP_BY <: usize) + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply_by_constant a_minus_b v_ZETA + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + re) + in + let hax_temp_output:Prims.unit = () <: Prims.unit in + re + +let invert_ntt_at_layer_3_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 0) (sz 1) 280005l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 2) (sz 1) 4010497l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 4) (sz 1) (-19422l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 6) (sz 1) 1757237l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 8) (sz 1) (-3277672l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 10) (sz 1) (-1399561l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 12) (sz 1) (-3859737l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 14) (sz 1) (-2118186l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 16) (sz 1) (-2108549l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 18) (sz 1) 2619752l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 20) (sz 1) (-1119584l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 22) (sz 1) (-549488l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 24) (sz 1) 3585928l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 26) (sz 1) (-1079900l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 28) (sz 1) 1024112l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 30) (sz 1) 2725464l re + in + re + +let invert_ntt_at_layer_4_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 0) (sz 2) 2680103l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 4) (sz 2) 3111497l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 8) (sz 2) (-2884855l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 12) (sz 2) 3119733l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 16) (sz 2) (-2091905l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 20) (sz 2) (-359251l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 24) (sz 2) 2353451l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 28) (sz 2) 1826347l re + in + re + +let invert_ntt_at_layer_5_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 0) (sz 4) 466468l re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 8) (sz 4) (-876248l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 16) (sz 4) (-777960l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 24) (sz 4) 237124l re + in + re + +let invert_ntt_at_layer_6_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 0) (sz 8) (-518909l) re + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 16) (sz 8) (-2608894l) re + in + re + +let invert_ntt_at_layer_7_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + outer_3_plus (sz 0) (sz 16) 25847l re + in + re + +let invert_ntt_montgomery (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = invert_ntt_at_layer_0_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = invert_ntt_at_layer_1_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = invert_ntt_at_layer_2_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = invert_ntt_at_layer_3_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = invert_ntt_at_layer_4_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = invert_ntt_at_layer_5_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = invert_ntt_at_layer_6_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = invert_ntt_at_layer_7_ re in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #Libcrux_intrinsics.Avx2_extract.t_Vec256 + (re <: t_Slice Libcrux_intrinsics.Avx2_extract.t_Vec256) + <: + usize) + (fun re temp_1_ -> + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = re in + let _:usize = temp_1_ in + true) + re + (fun re i -> + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = re in + let i:usize = i in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + i + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply_by_constant (re.[ i ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + 41978l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + <: + t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + in + re diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Invntt.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Invntt.fsti new file mode 100644 index 000000000..23e4bca7c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Invntt.fsti @@ -0,0 +1,127 @@ +module Libcrux_ml_dsa.Simd.Avx2.Invntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let invert_ntt_at_layer_3___STEP: usize = sz 8 + +let invert_ntt_at_layer_3___STEP_BY: usize = sz 1 + +let invert_ntt_at_layer_4___STEP: usize = sz 16 + +let invert_ntt_at_layer_4___STEP_BY: usize = sz 2 + +let invert_ntt_at_layer_5___STEP: usize = sz 32 + +let invert_ntt_at_layer_5___STEP_BY: usize = sz 4 + +let invert_ntt_at_layer_6___STEP: usize = sz 64 + +let invert_ntt_at_layer_6___STEP_BY: usize = sz 8 + +let invert_ntt_at_layer_7___STEP: usize = sz 128 + +let invert_ntt_at_layer_7___STEP_BY: usize = sz 16 + +let simd_unit_invert_ntt_at_layer_0___SHUFFLE: i32 = 216l + +val simd_unit_invert_ntt_at_layer_0_ + (simd_unit0 simd_unit1: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta00 zeta01 zeta02 zeta03 zeta10 zeta11 zeta12 zeta13: i32) + : Prims.Pure + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_0___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta00 zeta01 zeta02 zeta03 zeta10 zeta11 zeta12 zeta13: i32) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_0_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val simd_unit_invert_ntt_at_layer_1_ + (simd_unit0 simd_unit1: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta00 zeta01 zeta10 zeta11: i32) + : Prims.Pure + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_1___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta_00_ zeta_01_ zeta_10_ zeta_11_: i32) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_1_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val simd_unit_invert_ntt_at_layer_2_ + (simd_unit0 simd_unit1: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta0 zeta1: i32) + : Prims.Pure + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_2___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta1 zeta2: i32) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_2_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val outer_3_plus + (v_OFFSET v_STEP_BY: usize) + (v_ZETA: i32) + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_3_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_4_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_5_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_6_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_7_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_montgomery (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Ntt.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Ntt.fst new file mode 100644 index 000000000..d8d17ec4c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Ntt.fst @@ -0,0 +1,872 @@ +module Libcrux_ml_dsa.Simd.Avx2.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let ntt_at_layer_7_and_6___mul + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (step_by: usize) + (field_modulus inverse_of_modulus_mod_montgomery_r: Libcrux_intrinsics.Avx2_extract.t_Vec256) + = + let prod02:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mul_epi32 (re.[ index +! step_by <: usize ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + zeta + in + let prod13:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mul_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 + 245l + (re.[ index +! step_by <: usize ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + (Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 245l zeta + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let k02:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mul_epi32 prod02 inverse_of_modulus_mod_montgomery_r + in + let k13:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mul_epi32 prod13 inverse_of_modulus_mod_montgomery_r + in + let c02:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mul_epi32 k02 field_modulus + in + let c13:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mul_epi32 k13 field_modulus + in + let res02:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 prod02 c02 + in + let res13:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 prod13 c13 + in + let res02_shifted:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 245l res02 + in + let t:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_blend_epi32 170l res02_shifted res13 + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + (index +! step_by <: usize) + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract (re.[ index ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + t + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + index + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add (re.[ index ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + t + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + re + +let butterfly_2_ + (a b: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta_a0 zeta_a1 zeta_a2 zeta_a3 zeta_b0 zeta_b1 zeta_b2 zeta_b3: i32) + = + let a_shuffled:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 216l a + in + let b_shuffled:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 216l b + in + let summands:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpacklo_epi64 a_shuffled b_shuffled + in + let zeta_multiplicands:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpackhi_epi64 a_shuffled b_shuffled + in + let zetas:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 zeta_b3 + zeta_b2 + zeta_a3 + zeta_a2 + zeta_b1 + zeta_b0 + zeta_a1 + zeta_a0 + in + let zeta_products:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply zeta_multiplicands zetas + in + let add_terms:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add summands zeta_products + in + let sub_terms:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract summands zeta_products + in + let a_terms_shuffled:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpacklo_epi64 add_terms sub_terms + in + let b_terms_shuffled:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpackhi_epi64 add_terms sub_terms + in + let a_out:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 216l a_terms_shuffled + in + let b_out:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi32 216l b_terms_shuffled + in + a_out, b_out + <: + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let butterfly_4_ + (a b: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta_a0 zeta_a1 zeta_b0 zeta_b1: i32) + = + let summands:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpacklo_epi64 a b + in + let zeta_multiplicands:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpackhi_epi64 a b + in + let zetas:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 zeta_b1 + zeta_b1 + zeta_a1 + zeta_a1 + zeta_b0 + zeta_b0 + zeta_a0 + zeta_a0 + in + let zeta_products:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply zeta_multiplicands zetas + in + let add_terms:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add summands zeta_products + in + let sub_terms:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract summands zeta_products + in + let a_out:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpacklo_epi64 add_terms sub_terms + in + let b_out:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_unpackhi_epi64 add_terms sub_terms + in + a_out, b_out + <: + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let butterfly_8_ (a b: Libcrux_intrinsics.Avx2_extract.t_Vec256) (zeta0 zeta1: i32) = + let summands:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_m128i (Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 + b + <: + Libcrux_intrinsics.Avx2_extract.t_Vec128) + (Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 a + <: + Libcrux_intrinsics.Avx2_extract.t_Vec128) + in + let zeta_multiplicands:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permute2x128_si256 19l b a + in + let zetas:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 zeta1 zeta1 zeta1 zeta1 zeta0 zeta0 zeta0 zeta0 + in + let zeta_products:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply zeta_multiplicands zetas + in + let add_terms:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add summands zeta_products + in + let sub_terms:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract summands zeta_products + in + let a_out:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set_m128i (Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 + sub_terms + <: + Libcrux_intrinsics.Avx2_extract.t_Vec128) + (Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 add_terms + <: + Libcrux_intrinsics.Avx2_extract.t_Vec128) + in + let b_out:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permute2x128_si256 19l sub_terms add_terms + in + a_out, b_out + <: + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let ntt_at_layer_0___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta_0_ zeta_1_ zeta_2_ zeta_3_ zeta_4_ zeta_5_ zeta_6_ zeta_7_: i32) + = + let a, b:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) = + butterfly_2_ (re.[ index ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (re.[ index +! sz 1 <: usize ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) zeta_0_ zeta_1_ + zeta_2_ zeta_3_ zeta_4_ zeta_5_ zeta_6_ zeta_7_ + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re index a + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re (index +! sz 1 <: usize) b + in + re + +let ntt_at_layer_0_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 0) 2091667l 3407706l 2316500l 3817976l (-3342478l) 2244091l + (-2446433l) (-3562462l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 2) 266997l 2434439l (-1235728l) 3513181l (-3520352l) (-3759364l) + (-1197226l) (-3193378l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 4) 900702l 1859098l 909542l 819034l 495491l (-1613174l) (-43260l) + (-522500l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 6) (-655327l) (-3122442l) 2031748l 3207046l (-3556995l) (-525098l) + (-768622l) (-3595838l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 8) 342297l 286988l (-2437823l) 4108315l 3437287l (-3342277l) + 1735879l 203044l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 10) 2842341l 2691481l (-2590150l) 1265009l 4055324l 1247620l + 2486353l 1595974l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 12) (-3767016l) 1250494l 2635921l (-3548272l) (-2994039l) 1869119l + 1903435l (-1050970l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 14) (-1333058l) 1237275l (-3318210l) (-1430225l) (-451100l) + 1312455l 3306115l (-1962642l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 16) (-1279661l) 1917081l (-2546312l) (-1374803l) 1500165l 777191l + 2235880l 3406031l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 18) (-542412l) (-2831860l) (-1671176l) (-1846953l) (-2584293l) + (-3724270l) 594136l (-3776993l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 20) (-2013608l) 2432395l 2454455l (-164721l) 1957272l 3369112l + 185531l (-1207385l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 22) (-3183426l) 162844l 1616392l 3014001l 810149l 1652634l + (-3694233l) (-1799107l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 24) (-3038916l) 3523897l 3866901l 269760l 2213111l (-975884l) + 1717735l 472078l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 26) (-426683l) 1723600l (-1803090l) 1910376l (-1667432l) + (-1104333l) (-260646l) (-3833893l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 28) (-2939036l) (-2235985l) (-420899l) (-2286327l) 183443l + (-976891l) 1612842l (-3545687l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_0___round re (sz 30) (-554416l) 3919660l (-48306l) (-1362209l) 3937738l 1400424l + (-846154l) 1976782l + in + re + +let ntt_at_layer_1___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta_0_ zeta_1_ zeta_2_ zeta_3_: i32) + = + let a, b:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) = + butterfly_4_ (re.[ index ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (re.[ index +! sz 1 <: usize ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + zeta_0_ + zeta_1_ + zeta_2_ + zeta_3_ + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re index a + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re (index +! sz 1 <: usize) b + in + re + +let ntt_at_layer_1_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 0) (-3930395l) (-1528703l) (-3677745l) (-3041255l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 2) (-1452451l) 3475950l 2176455l (-1585221l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 4) (-1257611l) 1939314l (-4083598l) (-1000202l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 6) (-3190144l) (-3157330l) (-3632928l) 126922l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 8) 3412210l (-983419l) 2147896l 2715295l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 10) (-2967645l) (-3693493l) (-411027l) (-2477047l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 12) (-671102l) (-1228525l) (-22981l) (-1308169l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 14) (-381987l) 1349076l 1852771l (-1430430l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 16) (-3343383l) 264944l 508951l 3097992l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 18) 44288l (-1100098l) 904516l 3958618l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 20) (-3724342l) (-8578l) 1653064l (-3249728l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 22) 2389356l (-210977l) 759969l (-1316856l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 24) 189548l (-3553272l) 3159746l (-1851402l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 26) (-2409325l) (-177440l) 1315589l 1341330l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 28) 1285669l (-1584928l) (-812732l) (-1439742l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_1___round re (sz 30) (-3019102l) (-3881060l) (-3628969l) 3839961l + in + re + +let ntt_at_layer_2___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta_0_ zeta_1_: i32) + = + let a, b:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) = + butterfly_8_ (re.[ index ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (re.[ index +! sz 1 <: usize ] <: Libcrux_intrinsics.Avx2_extract.t_Vec256) + zeta_0_ + zeta_1_ + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re index a + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re (index +! sz 1 <: usize) b + in + re + +let ntt_at_layer_2_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 0) 2706023l 95776l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 2) 3077325l 3530437l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 4) (-1661693l) (-3592148l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 6) (-2537516l) 3915439l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 8) (-3861115l) (-3043716l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 10) 3574422l (-2867647l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 12) 3539968l (-300467l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 14) 2348700l (-539299l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 16) (-1699267l) (-1643818l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 18) 3505694l (-3821735l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 20) 3507263l (-2140649l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 22) (-1600420l) 3699596l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 24) 811944l 531354l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 26) 954230l 3881043l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 28) 3900724l (-2556880l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_2___round re (sz 30) 2071892l (-2797779l) + in + re + +let ntt_at_layer_7_and_6_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let field_modulus:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS + in + let inverse_of_modulus_mod_montgomery_r:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (cast (Libcrux_ml_dsa.Simd.Traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + <: + u64) + <: + i32) + in + let zeta7:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 25847l + in + let zeta60:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (-2608894l) + in + let zeta61:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 (-518909l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 0) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 0 +! sz 1 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 0 +! sz 2 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 0 +! sz 3 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 8) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 8 +! sz 1 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 8 +! sz 2 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 8 +! sz 3 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 0) + zeta60 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 0 +! sz 1 <: usize) + zeta60 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 0 +! sz 2 <: usize) + zeta60 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 0 +! sz 3 <: usize) + zeta60 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 16) + zeta61 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 16 +! sz 1 <: usize) + zeta61 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 16 +! sz 2 <: usize) + zeta61 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 16 +! sz 3 <: usize) + zeta61 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 4) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 4 +! sz 1 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 4 +! sz 2 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 4 +! sz 3 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 12) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 12 +! sz 1 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 12 +! sz 2 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 12 +! sz 3 <: usize) + zeta7 + ntt_at_layer_7_and_6___STEP_BY_7_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 4) + zeta60 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 4 +! sz 1 <: usize) + zeta60 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 4 +! sz 2 <: usize) + zeta60 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 4 +! sz 3 <: usize) + zeta60 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 20) + zeta61 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 20 +! sz 1 <: usize) + zeta61 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 20 +! sz 2 <: usize) + zeta61 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_7_and_6___mul re + (sz 20 +! sz 3 <: usize) + zeta61 + ntt_at_layer_7_and_6___STEP_BY_6_ + field_modulus + inverse_of_modulus_mod_montgomery_r + in + let _:Prims.unit = () in + re + +let ntt_at_layer_5_to_3___round + (v_STEP v_STEP_BY: usize) + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta: i32) + = + let rhs:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 zeta + in + let offset:usize = + ((index *! v_STEP <: usize) *! sz 2 <: usize) /! + Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Folds.fold_range offset + (offset +! v_STEP_BY <: usize) + (fun re temp_1_ -> + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = re in + let _:usize = temp_1_ in + true) + re + (fun re j -> + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = re in + let j:usize = j in + let t:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply (re.[ j +! v_STEP_BY <: usize ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + rhs + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + (j +! v_STEP_BY <: usize) + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract (re.[ j ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + t + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + j + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add (re.[ j ] + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + t + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + re) + in + let hax_temp_output:Prims.unit = () <: Prims.unit in + re + +let ntt_at_layer_5_to_3_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 32) (sz 4) re (sz 0) 237124l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 32) (sz 4) re (sz 1) (-777960l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 32) (sz 4) re (sz 2) (-876248l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 32) (sz 4) re (sz 3) 466468l + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 16) (sz 2) re (sz 0) 1826347l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 16) (sz 2) re (sz 1) 2353451l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 16) (sz 2) re (sz 2) (-359251l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 16) (sz 2) re (sz 3) (-2091905l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 16) (sz 2) re (sz 4) 3119733l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 16) (sz 2) re (sz 5) (-2884855l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 16) (sz 2) re (sz 6) 3111497l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 16) (sz 2) re (sz 7) 2680103l + in + let _:Prims.unit = () in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 0) 2725464l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 1) 1024112l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 2) (-1079900l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 3) 3585928l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 4) (-549488l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 5) (-1119584l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 6) 2619752l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 7) (-2108549l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 8) (-2118186l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 9) (-3859737l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 10) (-1399561l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 11) (-3277672l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 12) 1757237l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 13) (-19422l) + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 14) 4010497l + in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + ntt_at_layer_5_to_3___round (sz 8) (sz 1) re (sz 15) 280005l + in + let _:Prims.unit = () in + let hax_temp_output:Prims.unit = () <: Prims.unit in + re + +let ntt (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) = + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = ntt_at_layer_7_and_6_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = ntt_at_layer_5_to_3_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = ntt_at_layer_2_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = ntt_at_layer_1_ re in + let re:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = ntt_at_layer_0_ re in + let _:Prims.unit = () in + re diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Ntt.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Ntt.fsti new file mode 100644 index 000000000..40c8f1b32 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Ntt.fsti @@ -0,0 +1,128 @@ +module Libcrux_ml_dsa.Simd.Avx2.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let butterfly_2___SHUFFLE: i32 = 216l + +let ntt_at_layer_5_to_3___STEP: usize = sz 1 < Prims.l_True) + +let ntt_at_layer_5_to_3___STEP_BY: usize = + ntt_at_layer_5_to_3___STEP /! Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT + +let ntt_at_layer_5_to_3___STEP_BY_1: usize = + ntt_at_layer_5_to_3___STEP_1 /! Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT + +let ntt_at_layer_5_to_3___STEP_BY_2: usize = + ntt_at_layer_5_to_3___STEP_2 /! Libcrux_ml_dsa.Simd.Traits.v_COEFFICIENTS_IN_SIMD_UNIT + +let ntt_at_layer_7_and_6___STEP_BY_6_: usize = + (sz 1 < Prims.l_True) + +val butterfly_4_ + (a b: Libcrux_intrinsics.Avx2_extract.t_Vec256) + (zeta_a0 zeta_a1 zeta_b0 zeta_b1: i32) + : Prims.Pure + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + Prims.l_True + (fun _ -> Prims.l_True) + +val butterfly_8_ (a b: Libcrux_intrinsics.Avx2_extract.t_Vec256) (zeta0 zeta1: i32) + : Prims.Pure + (Libcrux_intrinsics.Avx2_extract.t_Vec256 & Libcrux_intrinsics.Avx2_extract.t_Vec256) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_0___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta_0_ zeta_1_ zeta_2_ zeta_3_ zeta_4_ zeta_5_ zeta_6_ zeta_7_: i32) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_0_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_1___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta_0_ zeta_1_ zeta_2_ zeta_3_: i32) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_1_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_2___round + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta_0_ zeta_1_: i32) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_2_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// This is equivalent to the pqclean 0 and 1 +/// This does 32 Montgomery multiplications (192 multiplications). +/// This is the same as in pqclean. The only difference is locality of registers. +val ntt_at_layer_7_and_6_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_5_to_3___round + (v_STEP v_STEP_BY: usize) + (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + (index: usize) + (zeta: i32) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Layer 5, 4, 3 +/// Each layer does 16 Montgomery multiplications -> 3*16 = 48 total +/// pqclean does 4 * 4 on each layer -> 48 total | plus 4 * 4 shuffles every time (48) +val ntt_at_layer_5_to_3_ (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt (re: t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + : Prims.Pure (t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta.fst new file mode 100644 index 000000000..67e806244 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta.fst @@ -0,0 +1,149 @@ +module Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let shift_interval (v_ETA: usize) (coefficients: Libcrux_intrinsics.Avx2_extract.t_Vec256) = + match cast (v_ETA <: usize) <: u8 with + | 2uy -> + let quotient:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mullo_epi32 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 26l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let quotient:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_srai_epi32 7l quotient + in + let quotient:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_mullo_epi32 quotient + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 5l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients_mod_5_:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 coefficients quotient + in + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 + (cast (v_ETA <: usize) <: i32) + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + coefficients_mod_5_ + | 4uy -> + Libcrux_intrinsics.Avx2_extract.mm256_sub_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 + (cast (v_ETA <: usize) <: i32) + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + coefficients + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let sample (v_ETA: usize) (input: t_Slice u8) (output: t_Slice i32) = + let potential_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.deserialize_to_unsigned (sz 4) input + in + let (interval_boundary: i32):i32 = + match cast (v_ETA <: usize) <: u8 with + | 2uy -> 15l + | 4uy -> 9l + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + in + let compare_with_interval_boundary:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_cmpgt_epi32 (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 + interval_boundary + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + potential_coefficients + in + let good:i32 = + Libcrux_intrinsics.Avx2_extract.mm256_movemask_ps (Libcrux_intrinsics.Avx2_extract.mm256_castsi256_ps + compare_with_interval_boundary + <: + u8) + in + let good_lower_half:i32 = good &. 15l in + let good_upper_half:i32 = good >>! 4l in + let shifted:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + shift_interval v_ETA potential_coefficients + in + let lower_shuffles:t_Array u8 (sz 16) = + Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.v_SHUFFLE_TABLE.[ cast (good_lower_half + <: + i32) + <: + usize ] + in + let lower_shuffles:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (lower_shuffles <: t_Slice u8) + in + let lower_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 shifted + in + let lower_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_shuffle_epi8 lower_coefficients lower_shuffles + in + let output:t_Slice i32 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range output + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 4 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_si128_i32 (output.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 4 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i32) + lower_coefficients + <: + t_Slice i32) + in + let sampled_count:usize = cast (Core.Num.impl__i32__count_ones good_lower_half <: u32) <: usize in + let upper_shuffles:t_Array u8 (sz 16) = + Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.v_SHUFFLE_TABLE.[ cast (good_upper_half + <: + i32) + <: + usize ] + in + let upper_shuffles:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (upper_shuffles <: t_Slice u8) + in + let upper_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_extracti128_si256 1l shifted + in + let upper_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_shuffle_epi8 upper_coefficients upper_shuffles + in + let output:t_Slice i32 = + 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 4 <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_si128_i32 (output.[ { + Core.Ops.Range.f_start = sampled_count; + Core.Ops.Range.f_end = sampled_count +! sz 4 <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i32) + upper_coefficients + <: + t_Slice i32) + in + let hax_temp_output:usize = + sampled_count +! (cast (Core.Num.impl__i32__count_ones good_upper_half <: u32) <: usize) + in + output, hax_temp_output <: (t_Slice i32 & usize) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta.fsti new file mode 100644 index 000000000..b18b2e3aa --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta.fsti @@ -0,0 +1,10 @@ +module Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +val shift_interval (v_ETA: usize) (coefficients: Libcrux_intrinsics.Avx2_extract.t_Vec256) + : Prims.Pure Libcrux_intrinsics.Avx2_extract.t_Vec256 Prims.l_True (fun _ -> Prims.l_True) + +val sample (v_ETA: usize) (input: t_Slice u8) (output: t_Slice i32) + : Prims.Pure (t_Slice i32 & usize) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus.fst new file mode 100644 index 000000000..f3d66cf87 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus.fst @@ -0,0 +1,142 @@ +module Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let bytestream_to_potential_coefficients (serialized: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + match Core.Slice.impl__len #u8 serialized, sz 24 <: (usize & usize) with + | left_val, right_val -> Hax_lib.v_assert (left_val =. right_val <: bool) + in + () + in + let serialized_extended:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let serialized_extended:t_Array u8 (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range_to serialized_extended + ({ Core.Ops.Range.f_end = sz 24 } <: Core.Ops.Range.t_RangeTo usize) + (Core.Slice.impl__copy_from_slice #u8 + (serialized_extended.[ { Core.Ops.Range.f_end = sz 24 } <: Core.Ops.Range.t_RangeTo usize + ] + <: + t_Slice u8) + serialized + <: + t_Slice u8) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_loadu_si256_u8 (serialized_extended <: t_Slice u8) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_permutevar8x32_epi32 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi32 0l 5l 4l 3l 0l 2l 1l 0l + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + let coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_shuffle_epi8 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set_epi8 (-1y) 11y 10y 9y (-1y) 8y 7y 6y (-1y) 5y 4y 3y + (-1y) 2y 1y 0y (-1y) 11y 10y 9y (-1y) 8y 7y 6y (-1y) 5y 4y 3y (-1y) 2y 1y 0y + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + in + Libcrux_intrinsics.Avx2_extract.mm256_and_si256 coefficients + (Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 bytestream_to_potential_coefficients__COEFFICIENT_MASK + + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let sample (input: t_Slice u8) (output: t_Slice i32) = + let field_modulus:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_set1_epi32 Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS + in + let potential_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + bytestream_to_potential_coefficients input + in + let compare_with_field_modulus:Libcrux_intrinsics.Avx2_extract.t_Vec256 = + Libcrux_intrinsics.Avx2_extract.mm256_cmpgt_epi32 field_modulus potential_coefficients + in + let good:i32 = + Libcrux_intrinsics.Avx2_extract.mm256_movemask_ps (Libcrux_intrinsics.Avx2_extract.mm256_castsi256_ps + compare_with_field_modulus + <: + u8) + in + let good_lower_half:i32 = good &. 15l in + let good_upper_half:i32 = good >>! 4l in + let lower_shuffles:t_Array u8 (sz 16) = + Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.v_SHUFFLE_TABLE.[ cast (good_lower_half + <: + i32) + <: + usize ] + in + let lower_shuffles:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (lower_shuffles <: t_Slice u8) + in + let lower_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_castsi256_si128 potential_coefficients + in + let lower_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_shuffle_epi8 lower_coefficients lower_shuffles + in + let output:t_Slice i32 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range output + ({ Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 4 } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_si128_i32 (output.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 4 + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i32) + lower_coefficients + <: + t_Slice i32) + in + let sampled_count:usize = cast (Core.Num.impl__i32__count_ones good_lower_half <: u32) <: usize in + let upper_shuffles:t_Array u8 (sz 16) = + Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.v_SHUFFLE_TABLE.[ cast (good_upper_half + <: + i32) + <: + usize ] + in + let upper_shuffles:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_loadu_si128 (upper_shuffles <: t_Slice u8) + in + let upper_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm256_extracti128_si256 1l potential_coefficients + in + let upper_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec128 = + Libcrux_intrinsics.Avx2_extract.mm_shuffle_epi8 upper_coefficients upper_shuffles + in + let output:t_Slice i32 = + 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 4 <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Libcrux_intrinsics.Avx2_extract.mm_storeu_si128_i32 (output.[ { + Core.Ops.Range.f_start = sampled_count; + Core.Ops.Range.f_end = sampled_count +! sz 4 <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i32) + upper_coefficients + <: + t_Slice i32) + in + let hax_temp_output:usize = + sampled_count +! (cast (Core.Num.impl__i32__count_ones good_upper_half <: u32) <: usize) + in + output, hax_temp_output <: (t_Slice i32 & usize) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus.fsti new file mode 100644 index 000000000..8d297cab8 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus.fsti @@ -0,0 +1,12 @@ +module Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let bytestream_to_potential_coefficients__COEFFICIENT_MASK: i32 = (1l < Prims.l_True) + +val sample (input: t_Slice u8) (output: t_Slice i32) + : Prims.Pure (t_Slice i32 & usize) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.fst new file mode 100644 index 000000000..97a40a5a5 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.fst @@ -0,0 +1,107 @@ +module Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let is_bit_set (number: usize) (bit_position: u8) = + ((number &. (sz 1 <>! bit_position <: usize) =. sz 1 + +let generate_shuffle_table (_: Prims.unit) = + let byte_shuffles:t_Array (t_Array u8 (sz 16)) (sz 16) = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 255uy (sz 16) <: t_Array u8 (sz 16)) + (sz 16) + in + let byte_shuffles:t_Array (t_Array u8 (sz 16)) (sz 16) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (sz 1 < + let byte_shuffles:t_Array (t_Array u8 (sz 16)) (sz 16) = byte_shuffles in + let _:usize = temp_1_ in + true) + byte_shuffles + (fun byte_shuffles bit_pattern -> + let byte_shuffles:t_Array (t_Array u8 (sz 16)) (sz 16) = byte_shuffles in + let bit_pattern:usize = bit_pattern in + let byte_shuffles_index:usize = sz 0 in + let byte_shuffles, byte_shuffles_index:(t_Array (t_Array u8 (sz 16)) (sz 16) & usize) = + Rust_primitives.Hax.Folds.fold_range 0uy + 4uy + (fun temp_0_ temp_1_ -> + let byte_shuffles, byte_shuffles_index:(t_Array (t_Array u8 (sz 16)) (sz 16) & + usize) = + temp_0_ + in + let _:u8 = temp_1_ in + true) + (byte_shuffles, byte_shuffles_index <: (t_Array (t_Array u8 (sz 16)) (sz 16) & usize)) + (fun temp_0_ bit_position -> + let byte_shuffles, byte_shuffles_index:(t_Array (t_Array u8 (sz 16)) (sz 16) & + usize) = + temp_0_ + in + let bit_position:u8 = bit_position in + if is_bit_set bit_pattern bit_position <: bool + then + let byte_shuffles:t_Array (t_Array u8 (sz 16)) (sz 16) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize byte_shuffles + bit_pattern + (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (byte_shuffles.[ + bit_pattern ] + <: + t_Array u8 (sz 16)) + byte_shuffles_index + (bit_position *! 4uy <: u8) + <: + t_Array u8 (sz 16)) + in + let byte_shuffles_index:usize = byte_shuffles_index +! sz 1 in + let byte_shuffles:t_Array (t_Array u8 (sz 16)) (sz 16) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize byte_shuffles + bit_pattern + (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (byte_shuffles.[ + bit_pattern ] + <: + t_Array u8 (sz 16)) + byte_shuffles_index + ((bit_position *! 4uy <: u8) +! 1uy <: u8) + <: + t_Array u8 (sz 16)) + in + let byte_shuffles_index:usize = byte_shuffles_index +! sz 1 in + let byte_shuffles:t_Array (t_Array u8 (sz 16)) (sz 16) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize byte_shuffles + bit_pattern + (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (byte_shuffles.[ + bit_pattern ] + <: + t_Array u8 (sz 16)) + byte_shuffles_index + ((bit_position *! 4uy <: u8) +! 2uy <: u8) + <: + t_Array u8 (sz 16)) + in + let byte_shuffles_index:usize = byte_shuffles_index +! sz 1 in + let byte_shuffles:t_Array (t_Array u8 (sz 16)) (sz 16) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize byte_shuffles + bit_pattern + (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (byte_shuffles.[ + bit_pattern ] + <: + t_Array u8 (sz 16)) + byte_shuffles_index + ((bit_position *! 4uy <: u8) +! 3uy <: u8) + <: + t_Array u8 (sz 16)) + in + let byte_shuffles_index:usize = byte_shuffles_index +! sz 1 in + byte_shuffles, byte_shuffles_index + <: + (t_Array (t_Array u8 (sz 16)) (sz 16) & usize) + else + byte_shuffles, byte_shuffles_index + <: + (t_Array (t_Array u8 (sz 16)) (sz 16) & usize)) + in + byte_shuffles) + in + byte_shuffles diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.fsti new file mode 100644 index 000000000..9586d3a7b --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table.fsti @@ -0,0 +1,140 @@ +module Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Shuffle_table +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let v_SHUFFLE_TABLE: t_Array (t_Array u8 (sz 16)) (sz 16) = + 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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; 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) 16); + Rust_primitives.Hax.array_of_list 16 list + +val is_bit_set (number: usize) (bit_position: u8) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + +val generate_shuffle_table: Prims.unit + -> Prims.Pure (t_Array (t_Array u8 (sz 16)) (sz 16)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Vector_type.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Vector_type.fst new file mode 100644 index 000000000..36529cba7 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Vector_type.fst @@ -0,0 +1,40 @@ +module Libcrux_ml_dsa.Simd.Avx2.Vector_type +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: Core.Convert.t_From t_AVX2SIMDUnit Libcrux_intrinsics.Avx2_extract.t_Vec256 = + { + f_from_pre = (fun (coefficients: Libcrux_intrinsics.Avx2_extract.t_Vec256) -> true); + f_from_post + = + (fun (coefficients: Libcrux_intrinsics.Avx2_extract.t_Vec256) (out: t_AVX2SIMDUnit) -> true); + f_from + = + fun (coefficients: Libcrux_intrinsics.Avx2_extract.t_Vec256) -> + { f_coefficients = coefficients } <: t_AVX2SIMDUnit + } + +let v_ZERO (_: Prims.unit) = + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_intrinsics.Avx2_extract.mm256_setzero_si256 () + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let from_coefficient_array (coefficient_array: t_Slice i32) = + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_intrinsics.Avx2_extract.mm256_loadu_si256_i32 coefficient_array + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256) + +let to_coefficient_array (x: t_AVX2SIMDUnit) = + let coefficient_array:t_Array i32 (sz 8) = Rust_primitives.Hax.repeat 0l (sz 8) in + let coefficient_array:t_Array i32 (sz 8) = + Libcrux_intrinsics.Avx2_extract.mm256_storeu_si256_i32 coefficient_array x.f_coefficients + in + coefficient_array diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Vector_type.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Vector_type.fsti new file mode 100644 index 000000000..94b3d91c9 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.Vector_type.fsti @@ -0,0 +1,17 @@ +module Libcrux_ml_dsa.Simd.Avx2.Vector_type +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +type t_AVX2SIMDUnit = { f_coefficients:Libcrux_intrinsics.Avx2_extract.t_Vec256 } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl:Core.Convert.t_From t_AVX2SIMDUnit Libcrux_intrinsics.Avx2_extract.t_Vec256 + +val v_ZERO: Prims.unit -> Prims.Pure t_AVX2SIMDUnit Prims.l_True (fun _ -> Prims.l_True) + +val from_coefficient_array (coefficient_array: t_Slice i32) + : Prims.Pure t_AVX2SIMDUnit Prims.l_True (fun _ -> Prims.l_True) + +val to_coefficient_array (x: t_AVX2SIMDUnit) + : Prims.Pure (t_Array i32 (sz 8)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.fst new file mode 100644 index 000000000..236abe5bd --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.fst @@ -0,0 +1,564 @@ +module Libcrux_ml_dsa.Simd.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Avx2.Vector_type in + () + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: Libcrux_ml_dsa.Simd.Traits.t_Operations +Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + f_ZERO_pre = (fun (_: Prims.unit) -> true); + f_ZERO_post + = + (fun (_: Prims.unit) (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true); + f_ZERO = (fun (_: Prims.unit) -> Libcrux_ml_dsa.Simd.Avx2.Vector_type.v_ZERO ()); + f_from_coefficient_array_pre = (fun (coefficient_array: t_Slice i32) -> true); + f_from_coefficient_array_post + = + (fun + (coefficient_array: t_Slice i32) + (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_from_coefficient_array + = + (fun (coefficient_array: t_Slice i32) -> + Libcrux_ml_dsa.Simd.Avx2.Vector_type.from_coefficient_array coefficient_array); + f_to_coefficient_array_pre + = + (fun (self: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true); + f_to_coefficient_array_post + = + (fun (self: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) (out: t_Array i32 (sz 8)) -> + true); + f_to_coefficient_array + = + (fun (self: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + Libcrux_ml_dsa.Simd.Avx2.Vector_type.to_coefficient_array self); + f_add_pre + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_add_post + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_add + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.add lhs + .Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + rhs.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_subtract_pre + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_subtract_post + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_subtract + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.subtract lhs + .Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + rhs.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_montgomery_multiply_pre + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_montgomery_multiply_post + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_montgomery_multiply + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.montgomery_multiply lhs + .Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + rhs.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_shift_left_then_reduce_pre + = + (fun (v_SHIFT_BY: i32) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true); + f_shift_left_then_reduce_post + = + (fun + (v_SHIFT_BY: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_shift_left_then_reduce + = + (fun (v_SHIFT_BY: i32) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.shift_left_then_reduce v_SHIFT_BY + simd_unit.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_power2round_pre + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true); + f_power2round_post + = + (fun + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: + (Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit & + Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit)) + -> + true); + f_power2round + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + let lower, upper:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & + Libcrux_intrinsics.Avx2_extract.t_Vec256) = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.power2round simd_unit + .Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + in + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + lower, + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + upper + <: + (Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit & + Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit)); + f_infinity_norm_exceeds_pre + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) (bound: i32) -> true); + f_infinity_norm_exceeds_post + = + (fun + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (bound: i32) + (out: bool) + -> + true); + f_infinity_norm_exceeds + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) (bound: i32) -> + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.infinity_norm_exceeds simd_unit + .Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + bound); + f_decompose_pre + = + (fun (v_GAMMA2: i32) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true); + f_decompose_post + = + (fun + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: + (Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit & + Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit)) + -> + true); + f_decompose + = + (fun (v_GAMMA2: i32) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + let lower, upper:(Libcrux_intrinsics.Avx2_extract.t_Vec256 & + Libcrux_intrinsics.Avx2_extract.t_Vec256) = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.decompose v_GAMMA2 + simd_unit.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + in + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + lower, + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + upper + <: + (Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit & + Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit)); + f_compute_hint_pre + = + (fun + (v_GAMMA2: i32) + (low: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (high: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_compute_hint_post + = + (fun + (v_GAMMA2: i32) + (low: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (high: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: (usize & Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit)) + -> + true); + f_compute_hint + = + (fun + (v_GAMMA2: i32) + (low: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (high: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + let count, hint:(usize & Libcrux_intrinsics.Avx2_extract.t_Vec256) = + Libcrux_ml_dsa.Simd.Avx2.Arithmetic.compute_hint v_GAMMA2 + low.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + high.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + in + count, + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + hint + <: + (usize & Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit)); + f_use_hint_pre + = + (fun + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (hint: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_use_hint_post + = + (fun + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (hint: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_use_hint + = + (fun + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (hint: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Arithmetic.use_hint v_GAMMA2 + simd_unit.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + hint.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_rejection_sample_less_than_field_modulus_pre + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> true); + f_rejection_sample_less_than_field_modulus_post + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) (out2: (t_Slice i32 & usize)) -> true); + f_rejection_sample_less_than_field_modulus + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_field_modulus.sample randomness out + in + let out:t_Slice i32 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i32 & usize)); + f_rejection_sample_less_than_eta_equals_2_pre + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> true); + f_rejection_sample_less_than_eta_equals_2_post + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) (out2: (t_Slice i32 & usize)) -> true); + f_rejection_sample_less_than_eta_equals_2_ + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta.sample (sz 2) randomness out + in + let out:t_Slice i32 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i32 & usize)); + f_rejection_sample_less_than_eta_equals_4_pre + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> true); + f_rejection_sample_less_than_eta_equals_4_post + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) (out2: (t_Slice i32 & usize)) -> true); + f_rejection_sample_less_than_eta_equals_4_ + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Avx2.Rejection_sample.Less_than_eta.sample (sz 4) randomness out + in + let out:t_Slice i32 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i32 & usize)); + f_gamma1_serialize_pre + = + (fun (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + true); + f_gamma1_serialize_post + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: t_Array u8 v_OUTPUT_SIZE) + -> + true); + f_gamma1_serialize + = + (fun (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1.serialize v_OUTPUT_SIZE + simd_unit.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients); + f_gamma1_deserialize_pre = (fun (v_GAMMA1_EXPONENT: usize) (serialized: t_Slice u8) -> true); + f_gamma1_deserialize_post + = + (fun + (v_GAMMA1_EXPONENT: usize) + (serialized: t_Slice u8) + (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_gamma1_deserialize + = + (fun (v_GAMMA1_EXPONENT: usize) (serialized: t_Slice u8) -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Encoding.Gamma1.deserialize v_GAMMA1_EXPONENT serialized + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_commitment_serialize_pre + = + (fun (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + true); + f_commitment_serialize_post + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: t_Array u8 v_OUTPUT_SIZE) + -> + true); + f_commitment_serialize + = + (fun (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + Libcrux_ml_dsa.Simd.Avx2.Encoding.Commitment.serialize v_OUTPUT_SIZE + simd_unit.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients); + f_error_serialize_pre + = + (fun (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + true); + f_error_serialize_post + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: t_Array u8 v_OUTPUT_SIZE) + -> + true); + f_error_serialize + = + (fun (v_OUTPUT_SIZE: usize) (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.serialize v_OUTPUT_SIZE + simd_unit.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients); + f_error_deserialize_pre = (fun (v_ETA: usize) (serialized: t_Slice u8) -> true); + f_error_deserialize_post + = + (fun + (v_ETA: usize) + (serialized: t_Slice u8) + (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + -> + true); + f_error_deserialize + = + (fun (v_ETA: usize) (serialized: t_Slice u8) -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Encoding.Error.deserialize v_ETA serialized + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_t0_serialize_pre + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true); + f_t0_serialize_post + = + (fun + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: t_Array u8 (sz 13)) + -> + true); + f_t0_serialize + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + Libcrux_ml_dsa.Simd.Avx2.Encoding.T0.serialize simd_unit + .Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients); + f_t0_deserialize_pre = (fun (serialized: t_Slice u8) -> true); + f_t0_deserialize_post + = + (fun (serialized: t_Slice u8) (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true + ); + f_t0_deserialize + = + (fun (serialized: t_Slice u8) -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Encoding.T0.deserialize serialized + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_t1_serialize_pre + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true); + f_t1_serialize_post + = + (fun + (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + (out: t_Array u8 (sz 10)) + -> + true); + f_t1_serialize + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> + Libcrux_ml_dsa.Simd.Avx2.Encoding.T1.serialize simd_unit + .Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients); + f_t1_deserialize_pre = (fun (serialized: t_Slice u8) -> true); + f_t1_deserialize_post + = + (fun (serialized: t_Slice u8) (out: Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) -> true + ); + f_t1_deserialize + = + (fun (serialized: t_Slice u8) -> + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_dsa.Simd.Avx2.Encoding.T1.deserialize serialized + <: + Libcrux_intrinsics.Avx2_extract.t_Vec256)); + f_ntt_pre + = + (fun (simd_units: t_Array Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit (sz 32)) -> true); + f_ntt_post + = + (fun + (simd_units: t_Array Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit (sz 32)) + (out: t_Array Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit (sz 32)) + -> + true); + f_ntt + = + (fun (simd_units: t_Array Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit (sz 32)) -> + let result:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Libcrux_ml_dsa.Simd.Avx2.Ntt.ntt (Core.Array.impl_23__map #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + (sz 32) + #Libcrux_intrinsics.Avx2_extract.t_Vec256 + simd_units + (fun x -> + let x:Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit = x in + x.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients) + <: + t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + in + Core.Array.impl_23__map #Libcrux_intrinsics.Avx2_extract.t_Vec256 + (sz 32) + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + result + (fun x -> + let x:Libcrux_intrinsics.Avx2_extract.t_Vec256 = x in + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + x + <: + Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit)); + f_invert_ntt_montgomery_pre + = + (fun (simd_units: t_Array Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit (sz 32)) -> true); + f_invert_ntt_montgomery_post + = + (fun + (simd_units: t_Array Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit (sz 32)) + (out: t_Array Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit (sz 32)) + -> + true); + f_invert_ntt_montgomery + = + fun (simd_units: t_Array Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit (sz 32)) -> + let result:t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32) = + Libcrux_ml_dsa.Simd.Avx2.Invntt.invert_ntt_montgomery (Core.Array.impl_23__map #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + (sz 32) + #Libcrux_intrinsics.Avx2_extract.t_Vec256 + simd_units + (fun x -> + let x:Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit = x in + x.Libcrux_ml_dsa.Simd.Avx2.Vector_type.f_coefficients) + <: + t_Array Libcrux_intrinsics.Avx2_extract.t_Vec256 (sz 32)) + in + Core.Array.impl_23__map #Libcrux_intrinsics.Avx2_extract.t_Vec256 + (sz 32) + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + result + (fun x -> + let x:Libcrux_intrinsics.Avx2_extract.t_Vec256 = x in + Core.Convert.f_into #Libcrux_intrinsics.Avx2_extract.t_Vec256 + #Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit + #FStar.Tactics.Typeclasses.solve + x + <: + Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit) + } diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.fsti new file mode 100644 index 000000000..708395ec3 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Avx2.fsti @@ -0,0 +1,13 @@ +module Libcrux_ml_dsa.Simd.Avx2 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Avx2.Vector_type in + () + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl:Libcrux_ml_dsa.Simd.Traits.t_Operations Libcrux_ml_dsa.Simd.Avx2.Vector_type.t_AVX2SIMDUnit diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Arithmetic.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Arithmetic.fst new file mode 100644 index 000000000..b8a8a4b00 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Arithmetic.fst @@ -0,0 +1,608 @@ +module Libcrux_ml_dsa.Simd.Portable.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let compute_one_hint (v_GAMMA2 low high: i32) = + if + low >. v_GAMMA2 || low <. (Core.Ops.Arith.Neg.neg v_GAMMA2 <: i32) || + low =. (Core.Ops.Arith.Neg.neg v_GAMMA2 <: i32) && high <>. 0l + then 1l + else 0l + +let get_n_least_significant_bits (n: u8) (value: u64) = value &. ((1uL <>! 23l in + fe -! (quotient *! Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: i32) + +let montgomery_reduce_element (value: i64) = + let t:u64 = + (get_n_least_significant_bits v_MONTGOMERY_SHIFT (cast (value <: i64) <: u64) <: u64) *! + Libcrux_ml_dsa.Simd.Traits.v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R + in + let k:i32 = cast (get_n_least_significant_bits v_MONTGOMERY_SHIFT t <: u64) <: i32 in + let k_times_modulus:i64 = + (cast (k <: i32) <: i64) *! (cast (Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: i32) <: i64) + in + let c:i32 = cast (k_times_modulus >>! v_MONTGOMERY_SHIFT <: i64) <: i32 in + let value_high:i32 = cast (value >>! v_MONTGOMERY_SHIFT <: i64) <: i32 in + value_high -! c + +let montgomery_multiply_fe_by_fer (fe fer: i32) = + montgomery_reduce_element ((cast (fe <: i32) <: i64) *! (cast (fer <: i32) <: i64) <: i64) + +let decompose_element (v_GAMMA2 r: i32) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((r >. + (Core.Ops.Arith.Neg.neg Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: i32) + <: + bool) && + (r <. Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: bool)) + in + () + in + let r:i32 = r +! ((r >>! 31l <: i32) &. Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: i32) in + let v_ALPHA:i32 = v_GAMMA2 *! 2l in + let ceil_of_r_by_128_:i32 = (r +! 127l <: i32) >>! 7l in + let r1:i32 = + match v_ALPHA with + | 190464l -> + let result:i32 = + ((ceil_of_r_by_128_ *! 11275l <: i32) +! (1l <>! 24l + in + (result ^. ((43l -! result <: i32) >>! 31l <: i32) <: i32) &. result + | 523776l -> + let result:i32 = + ((ceil_of_r_by_128_ *! 1025l <: i32) +! (1l <>! 22l + in + result &. 15l + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + in + let r0:i32 = r -! (r1 *! v_ALPHA <: i32) in + let r0:i32 = + r0 -! + (((((Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS -! 1l <: i32) /! 2l <: i32) -! r0 <: i32) >>! + 31l + <: + i32) &. + Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS + <: + i32) + in + r0, r1 <: (i32 & i32) + +let infinity_norm_exceeds + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (bound: i32) + = + let exceeds:bool = false in + let exceeds:bool = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Array.Iter.t_IntoIter + i32 (sz 8)) + #FStar.Tactics.Typeclasses.solve + (Core.Iter.Traits.Collect.f_into_iter #(t_Array i32 (sz 8)) + #FStar.Tactics.Typeclasses.solve + simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + <: + Core.Array.Iter.t_IntoIter i32 (sz 8)) + <: + Core.Array.Iter.t_IntoIter i32 (sz 8)) + exceeds + (fun exceeds coefficient -> + let exceeds:bool = exceeds in + let coefficient:i32 = coefficient in + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((coefficient >. + (Core.Ops.Arith.Neg.neg Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: i32) + <: + bool) && + (coefficient <. Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: bool)) + in + () + in + let sign:i32 = coefficient >>! 31l in + let normalized:i32 = coefficient -! (sign &. (2l *! coefficient <: i32) <: i32) in + let exceeds:bool = exceeds || normalized >=. bound in + exceeds) + in + exceeds + +let power2round_element (t: i32) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((t >. + (Core.Ops.Arith.Neg.neg Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: i32) + <: + bool) && + (t <. Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: bool)) + in + () + in + let t:i32 = t +! ((t >>! 31l <: i32) &. Libcrux_ml_dsa.Simd.Traits.v_FIELD_MODULUS <: i32) in + let t1:i32 = + ((t -! 1l <: i32) +! + (1l <>! + Libcrux_ml_dsa.Constants.v_BITS_IN_LOWER_PART_OF_T + in + let t0:i32 = t -! (t1 < + if r0 >. 0l + then if r1 =. 43l then 0l else r1 +! hint + else if r1 =. 0l then 43l else r1 -! hint + | 261888l -> if r0 >. 0l then (r1 +! hint <: i32) &. 15l else (r1 -! hint <: i32) &. 15l + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let power2round (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + let t0_simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let t1_simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let t0_simd_unit, t1_simd_unit:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + Rust_primitives.Hax.Folds.fold_enumerated_slice simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (fun temp_0_ temp_1_ -> + let t0_simd_unit, t1_simd_unit:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (t0_simd_unit, t1_simd_unit + <: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit)) + (fun temp_0_ temp_1_ -> + let t0_simd_unit, t1_simd_unit:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + temp_0_ + in + let i, t:(usize & i32) = temp_1_ in + let t0, t1:(i32 & i32) = power2round_element t in + let t0_simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + t0_simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize t0_simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + t0 + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t1_simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + t1_simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize t1_simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + t1 + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + t0_simd_unit, t1_simd_unit + <: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit)) + in + t0_simd_unit, t1_simd_unit + <: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + +let add (lhs rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + let sum:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let sum:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #i32 + (sum.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + <: + usize) + (fun sum temp_1_ -> + let sum:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = sum in + let _:usize = temp_1_ in + true) + sum + (fun sum i -> + let sum:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = sum in + let i:usize = i in + { + sum with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize sum + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + ((lhs.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) +! + (rhs.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + <: + i32) + <: + t_Array i32 (sz 8) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + sum + +let compute_hint + (v_GAMMA2: i32) + (low high: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let hint:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let one_hints_count:usize = sz 0 in + let hint, one_hints_count:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & usize) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #i32 + (hint.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + <: + usize) + (fun temp_0_ temp_1_ -> + let hint, one_hints_count:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + usize) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (hint, one_hints_count + <: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & usize)) + (fun temp_0_ i -> + let hint, one_hints_count:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + usize) = + temp_0_ + in + let i:usize = i in + let hint:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + hint with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize hint + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + (compute_one_hint v_GAMMA2 + (low.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + (high.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let one_hints_count:usize = + one_hints_count +! + (cast (hint.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + <: + usize) + in + hint, one_hints_count + <: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & usize)) + in + one_hints_count, hint <: (usize & Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + +let decompose + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let low:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let high:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let high, low:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #i32 + (low.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + <: + usize) + (fun temp_0_ temp_1_ -> + let high, low:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + temp_0_ + in + let _:usize = temp_1_ in + true) + (high, low + <: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit)) + (fun temp_0_ i -> + let high, low:(Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + temp_0_ + in + let i:usize = i in + let low_part, high_part:(i32 & i32) = + decompose_element v_GAMMA2 + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + in + let low:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + low with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize low + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + low_part + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let high:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + high with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize high + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + high_part + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + high, low + <: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit)) + in + low, high + <: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + +let montgomery_multiply (lhs rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) = + let product:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let product:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #i32 + (product.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + <: + usize) + (fun product temp_1_ -> + let product:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = product in + let _:usize = temp_1_ in + true) + product + (fun product i -> + let product:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = product in + let i:usize = i in + { + product with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize product + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + (montgomery_reduce_element ((cast (lhs + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] + <: + i32) + <: + i64) *! + (cast (rhs.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + <: + i64) + <: + i64) + <: + i32) + <: + t_Array i32 (sz 8) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + product + +let montgomery_multiply_by_constant + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (c: i32) + = + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #i32 + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + <: + usize) + (fun simd_unit temp_1_ -> + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let _:usize = temp_1_ in + true) + simd_unit + (fun simd_unit i -> + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let i:usize = i in + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + (montgomery_reduce_element ((cast (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] + <: + i32) + <: + i64) *! + (cast (c <: i32) <: i64) + <: + i64) + <: + i32) + <: + t_Array i32 (sz 8) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + simd_unit + +let shift_left_then_reduce + (v_SHIFT_BY: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let out:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let out:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #i32 + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + <: + usize) + (fun out temp_1_ -> + let out:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = out in + let _:usize = temp_1_ in + true) + out + (fun out i -> + let out:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = out in + let i:usize = i in + { + out with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + (reduce_element ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i + ] + <: + i32) < + let difference:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = difference in + let _:usize = temp_1_ in + true) + difference + (fun difference i -> + let difference:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = difference in + let i:usize = i in + { + difference with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize difference + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + ((lhs.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) -! + (rhs.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + <: + i32) + <: + t_Array i32 (sz 8) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + difference + +let use_hint + (v_GAMMA2: i32) + (simd_unit hint: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let result:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let result:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #i32 + (result.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + <: + usize) + (fun result temp_1_ -> + let result:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = result in + let _:usize = temp_1_ in + true) + result + (fun result i -> + let result:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = result in + let i:usize = i in + { + result with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + i + (use_one_hint v_GAMMA2 + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + (hint.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ i ] <: i32) + <: + i32) + <: + t_Array i32 (sz 8) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + result diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Arithmetic.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Arithmetic.fsti new file mode 100644 index 000000000..2a50db3ec --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Arithmetic.fsti @@ -0,0 +1,89 @@ +module Libcrux_ml_dsa.Simd.Portable.Arithmetic +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let v_MONTGOMERY_SHIFT: u8 = 32uy + +val compute_one_hint (v_GAMMA2 low high: i32) : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) + +val get_n_least_significant_bits (n: u8) (value: u64) + : Prims.Pure u64 Prims.l_True (fun _ -> Prims.l_True) + +val reduce_element (fe: i32) : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) + +val montgomery_reduce_element (value: i64) : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) + +val montgomery_multiply_fe_by_fer (fe fer: i32) + : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) + +val decompose_element (v_GAMMA2 r: i32) + : Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) + +val infinity_norm_exceeds + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (bound: i32) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + +val power2round_element (t: i32) : Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) + +val use_one_hint (v_GAMMA2 r hint: i32) : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) + +val power2round (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val add (lhs rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val compute_hint + (v_GAMMA2: i32) + (low high: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (usize & Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val decompose + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + Prims.l_True + (fun _ -> Prims.l_True) + +val montgomery_multiply (lhs rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val montgomery_multiply_by_constant + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (c: i32) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val shift_left_then_reduce + (v_SHIFT_BY: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val subtract (lhs rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val use_hint + (v_GAMMA2: i32) + (simd_unit hint: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment.fst new file mode 100644 index 000000000..ff1788cd5 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment.fst @@ -0,0 +1,72 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let serialize + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let serialized:t_Array u8 v_OUTPUT_SIZE = Rust_primitives.Hax.repeat 0uy v_OUTPUT_SIZE in + match cast (v_OUTPUT_SIZE <: usize) <: u8 with + | 4uy -> + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_chunked_slice (sz 2) + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, coefficients:(usize & t_Slice i32) = temp_1_ in + let coefficient0:u8 = cast (coefficients.[ sz 0 ] <: i32) <: u8 in + let coefficient1:u8 = cast (coefficients.[ sz 1 ] <: i32) <: u8 in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + i + ((coefficient1 < + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_chunked_slice (sz 4) + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, coefficients:(usize & t_Slice i32) = temp_1_ in + let coefficient0:u8 = cast (coefficients.[ sz 0 ] <: i32) <: u8 in + let coefficient1:u8 = cast (coefficients.[ sz 1 ] <: i32) <: u8 in + let coefficient2:u8 = cast (coefficients.[ sz 2 ] <: i32) <: u8 in + let coefficient3:u8 = cast (coefficients.[ sz 3 ] <: i32) <: u8 in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 3 *! i <: usize) + ((coefficient1 <>! 2l <: u8) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 3 *! i <: usize) +! sz 2 <: usize) + ((coefficient3 <>! 4l <: u8) <: u8) + in + serialized) + in + serialized + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment.fsti new file mode 100644 index 000000000..cc50ef52c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment.fsti @@ -0,0 +1,9 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +val serialize + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Error.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Error.fst new file mode 100644 index 000000000..a91008218 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Error.fst @@ -0,0 +1,332 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.Error +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let serialize_when_eta_is_2_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let serialized:t_Array u8 v_OUTPUT_SIZE = Rust_primitives.Hax.repeat 0uy v_OUTPUT_SIZE in + let coefficient0:u8 = + cast (serialize_when_eta_is_2___ETA -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) + <: + i32) + <: + u8 + in + let coefficient1:u8 = + cast (serialize_when_eta_is_2___ETA -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) + <: + i32) + <: + u8 + in + let coefficient2:u8 = + cast (serialize_when_eta_is_2___ETA -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) + <: + i32) + <: + u8 + in + let coefficient3:u8 = + cast (serialize_when_eta_is_2___ETA -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) + <: + i32) + <: + u8 + in + let coefficient4:u8 = + cast (serialize_when_eta_is_2___ETA -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) + <: + i32) + <: + u8 + in + let coefficient5:u8 = + cast (serialize_when_eta_is_2___ETA -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) + <: + i32) + <: + u8 + in + let coefficient6:u8 = + cast (serialize_when_eta_is_2___ETA -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) + <: + i32) + <: + u8 + in + let coefficient7:u8 = + cast (serialize_when_eta_is_2___ETA -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] <: i32) + <: + i32) + <: + u8 + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 0) + (((coefficient2 <>! 2l <: u8) + <: + u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 2) + (((coefficient7 <>! 1l <: u8) + <: + u8) + in + serialized + +let deserialize_when_eta_is_2_ (serialized: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 serialized <: usize) =. sz 3 <: bool) + in + () + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let byte0:i32 = cast (serialized.[ sz 0 ] <: u8) <: i32 in + let byte1:i32 = cast (serialized.[ sz 1 ] <: u8) <: i32 in + let byte2:i32 = cast (serialized.[ sz 2 ] <: u8) <: i32 in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 0) + (deserialize_when_eta_is_2___ETA -! (byte0 &. 7l <: i32) <: i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 1) + (deserialize_when_eta_is_2___ETA -! ((byte0 >>! 3l <: i32) &. 7l <: i32) <: i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 2) + (deserialize_when_eta_is_2___ETA -! + (((byte0 >>! 6l <: i32) |. (byte1 <>! 1l <: i32) &. 7l <: i32) <: i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 4) + (deserialize_when_eta_is_2___ETA -! ((byte1 >>! 4l <: i32) &. 7l <: i32) <: i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 5) + (deserialize_when_eta_is_2___ETA -! + (((byte1 >>! 7l <: i32) |. (byte2 <>! 2l <: i32) &. 7l <: i32) <: i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 7) + (deserialize_when_eta_is_2___ETA -! ((byte2 >>! 5l <: i32) &. 7l <: i32) <: i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + simd_unit + +let deserialize_when_eta_is_4_ (serialized: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 serialized <: usize) =. sz 4 <: bool) + in + () + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Rust_primitives.Hax.Folds.fold_enumerated_slice serialized + (fun simd_unit temp_1_ -> + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let _:usize = temp_1_ in + true) + simd_unit + (fun simd_unit temp_1_ -> + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let i, byte:(usize & u8) = temp_1_ in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 2 *! i <: usize) + (deserialize_when_eta_is_4___ETA -! (cast (byte &. 15uy <: u8) <: i32) <: i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + ((sz 2 *! i <: usize) +! sz 1 <: usize) + (deserialize_when_eta_is_4___ETA -! (cast (byte >>! 4l <: u8) <: i32) <: i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + simd_unit) + in + simd_unit + +let deserialize (v_ETA: usize) (serialized: t_Slice u8) = + match cast (v_ETA <: usize) <: u8 with + | 2uy -> deserialize_when_eta_is_2_ serialized + | 4uy -> deserialize_when_eta_is_4_ serialized + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let serialize_when_eta_is_4_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let serialized:t_Array u8 v_OUTPUT_SIZE = Rust_primitives.Hax.repeat 0uy v_OUTPUT_SIZE in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_chunked_slice (sz 2) + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, coefficients:(usize & t_Slice i32) = temp_1_ in + let coefficient0:u8 = + cast (serialize_when_eta_is_4___ETA -! (coefficients.[ sz 0 ] <: i32) <: i32) <: u8 + in + let coefficient1:u8 = + cast (serialize_when_eta_is_4___ETA -! (coefficients.[ sz 1 ] <: i32) <: i32) <: u8 + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + i + ((coefficient1 < serialize_when_eta_is_2_ v_OUTPUT_SIZE simd_unit + | 4uy -> serialize_when_eta_is_4_ v_OUTPUT_SIZE simd_unit + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Error.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Error.fsti new file mode 100644 index 000000000..e973dc734 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Error.fsti @@ -0,0 +1,42 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.Error +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize_when_eta_is_2___ETA: i32 = 2l + +let deserialize_when_eta_is_4___ETA: i32 = 4l + +let serialize_when_eta_is_2___ETA: i32 = 2l + +let serialize_when_eta_is_4___ETA: i32 = 4l + +val serialize_when_eta_is_2_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val deserialize_when_eta_is_2_ (serialized: t_Slice u8) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize_when_eta_is_4_ (serialized: t_Slice u8) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize (v_ETA: usize) (serialized: t_Slice u8) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val serialize_when_eta_is_4_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val serialize + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1.fst new file mode 100644 index 000000000..ca1f48e87 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1.fst @@ -0,0 +1,376 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize_when_gamma1_is_2_pow_17_ (serialized: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 serialized <: usize) =. sz 18 <: bool) + in + () + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Rust_primitives.Hax.Folds.fold_enumerated_chunked_slice (sz 9) + serialized + (fun simd_unit temp_1_ -> + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let _:usize = temp_1_ in + true) + simd_unit + (fun simd_unit temp_1_ -> + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let i, bytes:(usize & t_Slice u8) = temp_1_ in + let coefficient0:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in + let coefficient0:i32 = + coefficient0 |. ((cast (bytes.[ sz 1 ] <: u8) <: i32) <>! 2l in + let coefficient1:i32 = + coefficient1 |. ((cast (bytes.[ sz 3 ] <: u8) <: i32) <>! 4l in + let coefficient2:i32 = + coefficient2 |. ((cast (bytes.[ sz 5 ] <: u8) <: i32) <>! 6l in + let coefficient3:i32 = + coefficient3 |. ((cast (bytes.[ sz 7 ] <: u8) <: i32) < + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let _:usize = temp_1_ in + true) + simd_unit + (fun simd_unit temp_1_ -> + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let i, bytes:(usize & t_Slice u8) = temp_1_ in + let coefficient0:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in + let coefficient0:i32 = + coefficient0 |. ((cast (bytes.[ sz 1 ] <: u8) <: i32) <>! 4l in + let coefficient1:i32 = + coefficient1 |. ((cast (bytes.[ sz 3 ] <: u8) <: i32) < deserialize_when_gamma1_is_2_pow_17_ serialized + | 19uy -> deserialize_when_gamma1_is_2_pow_19_ serialized + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) + +let serialize_when_gamma1_is_2_pow_17_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let serialized:t_Array u8 v_OUTPUT_SIZE = Rust_primitives.Hax.repeat 0uy v_OUTPUT_SIZE in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_chunked_slice (sz 4) + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, coefficients:(usize & t_Slice i32) = temp_1_ in + let coefficient0:i32 = + serialize_when_gamma1_is_2_pow_17___GAMMA1 -! (coefficients.[ sz 0 ] <: i32) + in + let coefficient1:i32 = + serialize_when_gamma1_is_2_pow_17___GAMMA1 -! (coefficients.[ sz 1 ] <: i32) + in + let coefficient2:i32 = + serialize_when_gamma1_is_2_pow_17___GAMMA1 -! (coefficients.[ sz 2 ] <: i32) + in + let coefficient3:i32 = + serialize_when_gamma1_is_2_pow_17___GAMMA1 -! (coefficients.[ sz 3 ] <: i32) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 9 *! i <: usize) + (cast (coefficient0 <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 9 *! i <: usize) +! sz 1 <: usize) + (cast (coefficient0 >>! 8l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 9 *! i <: usize) +! sz 2 <: usize) + (cast (coefficient0 >>! 16l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 9 *! i <: usize) +! sz 2 <: usize) + ((serialized.[ (sz 9 *! i <: usize) +! sz 2 <: usize ] <: u8) |. + (cast (coefficient1 <>! 6l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 9 *! i <: usize) +! sz 4 <: usize) + (cast (coefficient1 >>! 14l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 9 *! i <: usize) +! sz 4 <: usize) + ((serialized.[ (sz 9 *! i <: usize) +! sz 4 <: usize ] <: u8) |. + (cast (coefficient2 <>! 4l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 9 *! i <: usize) +! sz 6 <: usize) + (cast (coefficient2 >>! 12l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 9 *! i <: usize) +! sz 6 <: usize) + ((serialized.[ (sz 9 *! i <: usize) +! sz 6 <: usize ] <: u8) |. + (cast (coefficient3 <>! 2l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 9 *! i <: usize) +! sz 8 <: usize) + (cast (coefficient3 >>! 10l <: i32) <: u8) + in + serialized) + in + serialized + +let serialize_when_gamma1_is_2_pow_19_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + let serialized:t_Array u8 v_OUTPUT_SIZE = Rust_primitives.Hax.repeat 0uy v_OUTPUT_SIZE in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Folds.fold_enumerated_chunked_slice (sz 2) + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients <: t_Slice i32) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUTPUT_SIZE = serialized in + let i, coefficients:(usize & t_Slice i32) = temp_1_ in + let coefficient0:i32 = + serialize_when_gamma1_is_2_pow_19___GAMMA1 -! (coefficients.[ sz 0 ] <: i32) + in + let coefficient1:i32 = + serialize_when_gamma1_is_2_pow_19___GAMMA1 -! (coefficients.[ sz 1 ] <: i32) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 5 *! i <: usize) + (cast (coefficient0 <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 5 *! i <: usize) +! sz 1 <: usize) + (cast (coefficient0 >>! 8l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 5 *! i <: usize) +! sz 2 <: usize) + (cast (coefficient0 >>! 16l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 5 *! i <: usize) +! sz 2 <: usize) + ((serialized.[ (sz 5 *! i <: usize) +! sz 2 <: usize ] <: u8) |. + (cast (coefficient1 <>! 4l <: i32) <: u8) + in + let serialized:t_Array u8 v_OUTPUT_SIZE = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 5 *! i <: usize) +! sz 4 <: usize) + (cast (coefficient1 >>! 12l <: i32) <: u8) + in + serialized) + in + serialized + +let serialize + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + = + match cast (v_OUTPUT_SIZE <: usize) <: u8 with + | 18uy -> serialize_when_gamma1_is_2_pow_17_ v_OUTPUT_SIZE simd_unit + | 20uy -> serialize_when_gamma1_is_2_pow_19_ v_OUTPUT_SIZE simd_unit + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" + + <: + Rust_primitives.Hax.t_Never) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1.fsti new file mode 100644 index 000000000..a22f485c1 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1.fsti @@ -0,0 +1,48 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize_when_gamma1_is_2_pow_17___GAMMA1: i32 = 1l < Prims.l_True) + +val deserialize_when_gamma1_is_2_pow_19_ (serialized: t_Slice u8) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val deserialize (v_GAMMA1_EXPONENT: usize) (serialized: t_Slice u8) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val serialize_when_gamma1_is_2_pow_17_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val serialize_when_gamma1_is_2_pow_19_ + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) + +val serialize + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (t_Array u8 v_OUTPUT_SIZE) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T0.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T0.fst new file mode 100644 index 000000000..b9ecdb13c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T0.fst @@ -0,0 +1,310 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.T0 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let change_t0_interval (t0: i32) = + (1l <>! 8l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 1) + ((serialized.[ sz 1 ] <: u8) |. (cast (coefficient1 <>! 3l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 3) + (cast (coefficient1 >>! 11l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 3) + ((serialized.[ sz 3 ] <: u8) |. (cast (coefficient2 <>! 6l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 4) + ((serialized.[ sz 4 ] <: u8) |. (cast (coefficient3 <>! 1l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 6) + (cast (coefficient3 >>! 9l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 6) + ((serialized.[ sz 6 ] <: u8) |. (cast (coefficient4 <>! 4l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 8) + (cast (coefficient4 >>! 12l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 8) + ((serialized.[ sz 8 ] <: u8) |. (cast (coefficient5 <>! 7l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 9) + ((serialized.[ sz 9 ] <: u8) |. (cast (coefficient6 <>! 2l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 11) + (cast (coefficient6 >>! 10l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 13) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 11) + ((serialized.[ sz 11 ] <: u8) |. (cast (coefficient7 <>! 5l <: i32) <: u8) + in + serialized + +let deserialize (serialized: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 serialized <: usize) =. sz 13 <: bool) + in + () + in + let byte0:i32 = cast (serialized.[ sz 0 ] <: u8) <: i32 in + let byte1:i32 = cast (serialized.[ sz 1 ] <: u8) <: i32 in + let byte2:i32 = cast (serialized.[ sz 2 ] <: u8) <: i32 in + let byte3:i32 = cast (serialized.[ sz 3 ] <: u8) <: i32 in + let byte4:i32 = cast (serialized.[ sz 4 ] <: u8) <: i32 in + let byte5:i32 = cast (serialized.[ sz 5 ] <: u8) <: i32 in + let byte6:i32 = cast (serialized.[ sz 6 ] <: u8) <: i32 in + let byte7:i32 = cast (serialized.[ sz 7 ] <: u8) <: i32 in + let byte8:i32 = cast (serialized.[ sz 8 ] <: u8) <: i32 in + let byte9:i32 = cast (serialized.[ sz 9 ] <: u8) <: i32 in + let byte10:i32 = cast (serialized.[ sz 10 ] <: u8) <: i32 in + let byte11:i32 = cast (serialized.[ sz 11 ] <: u8) <: i32 in + let byte12:i32 = cast (serialized.[ sz 12 ] <: u8) <: i32 in + let coefficient0:i32 = byte0 in + let coefficient0:i32 = coefficient0 |. (byte1 <>! 5l in + let coefficient1:i32 = coefficient1 |. (byte2 <>! 2l in + let coefficient2:i32 = coefficient2 |. (byte4 <>! 7l in + let coefficient3:i32 = coefficient3 |. (byte5 <>! 4l in + let coefficient4:i32 = coefficient4 |. (byte7 <>! 1l in + let coefficient5:i32 = coefficient5 |. (byte9 <>! 6l in + let coefficient6:i32 = coefficient6 |. (byte10 <>! 3l in + let coefficient7:i32 = coefficient7 |. (byte12 < Prims.l_True) + +let deserialize__BITS_IN_LOWER_PART_OF_T_MASK: i32 = + (1l < Prims.l_True) + +val deserialize (serialized: t_Slice u8) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T1.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T1.fst new file mode 100644 index 000000000..aab3acfcc --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T1.fst @@ -0,0 +1,140 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.T1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let deserialize (serialized: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 serialized <: usize) =. sz 10 <: bool) + in + () + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO () + in + let mask:i32 = (1l < + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let _:usize = temp_1_ in + true) + simd_unit + (fun simd_unit temp_1_ -> + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = simd_unit in + let i, bytes:(usize & t_Slice u8) = temp_1_ in + let byte0:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in + let byte1:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in + let byte2:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in + let byte3:i32 = cast (bytes.[ sz 3 ] <: u8) <: i32 in + let byte4:i32 = cast (bytes.[ sz 4 ] <: u8) <: i32 in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 4 *! i <: usize) + ((byte0 |. (byte1 <>! 2l <: i32) |. (byte2 <>! 4l <: i32) |. (byte3 <>! 6l <: i32) |. (byte4 < + let serialized:t_Array u8 (sz 10) = serialized in + let _:usize = temp_1_ in + true) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 (sz 10) = serialized in + let i, coefficients:(usize & t_Slice i32) = temp_1_ in + let serialized:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 5 *! i <: usize) + (cast ((coefficients.[ sz 0 ] <: i32) &. 255l <: i32) <: u8) + in + let serialized:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 5 *! i <: usize) +! sz 1 <: usize) + (((cast ((coefficients.[ sz 1 ] <: i32) &. 63l <: i32) <: u8) <>! 8l <: i32) &. 3l <: i32) <: u8) + <: + u8) + in + let serialized:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 5 *! i <: usize) +! sz 2 <: usize) + (((cast ((coefficients.[ sz 2 ] <: i32) &. 15l <: i32) <: u8) <>! 6l <: i32) &. 15l <: i32) <: u8) + <: + u8) + in + let serialized:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 5 *! i <: usize) +! sz 3 <: usize) + (((cast ((coefficients.[ sz 3 ] <: i32) &. 3l <: i32) <: u8) <>! 4l <: i32) &. 63l <: i32) <: u8) + <: + u8) + in + let serialized:t_Array u8 (sz 10) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + ((sz 5 *! i <: usize) +! sz 4 <: usize) + (cast (((coefficients.[ sz 3 ] <: i32) >>! 2l <: i32) &. 255l <: i32) <: u8) + in + serialized) + in + serialized diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T1.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T1.fsti new file mode 100644 index 000000000..0d94a5f30 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Encoding.T1.fsti @@ -0,0 +1,12 @@ +module Libcrux_ml_dsa.Simd.Portable.Encoding.T1 +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +val deserialize (serialized: t_Slice u8) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val serialize (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + : Prims.Pure (t_Array u8 (sz 10)) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Invntt.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Invntt.fst new file mode 100644 index 000000000..e4d06be44 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Invntt.fst @@ -0,0 +1,1015 @@ +module Libcrux_ml_dsa.Simd.Portable.Invntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let simd_unit_invert_ntt_at_layer_0_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta0 zeta1 zeta2 zeta3: i32) + = + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 0) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 1) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta0 + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 2) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 3) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta1 + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 4) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 5) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta2 + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 6) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 7) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta3 + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + simd_unit + +let invert_ntt_at_layer_0___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta0 zeta1 zeta2 zeta3: i32) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + index + (simd_unit_invert_ntt_at_layer_0_ (re.[ index ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + zeta0 + zeta1 + zeta2 + zeta3 + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + re + +let invert_ntt_at_layer_0_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 0) 1976782l (-846154l) 1400424l 3937738l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 1) (-1362209l) (-48306l) 3919660l (-554416l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 2) (-3545687l) 1612842l (-976891l) 183443l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 3) (-2286327l) (-420899l) (-2235985l) (-2939036l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 4) (-3833893l) (-260646l) (-1104333l) (-1667432l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 5) 1910376l (-1803090l) 1723600l (-426683l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 6) 472078l 1717735l (-975884l) 2213111l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 7) 269760l 3866901l 3523897l (-3038916l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 8) (-1799107l) (-3694233l) 1652634l 810149l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 9) 3014001l 1616392l 162844l (-3183426l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 10) (-1207385l) 185531l 3369112l 1957272l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 11) (-164721l) 2454455l 2432395l (-2013608l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 12) (-3776993l) 594136l (-3724270l) (-2584293l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 13) (-1846953l) (-1671176l) (-2831860l) (-542412l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 14) 3406031l 2235880l 777191l 1500165l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 15) (-1374803l) (-2546312l) 1917081l (-1279661l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 16) (-1962642l) 3306115l 1312455l (-451100l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 17) (-1430225l) (-3318210l) 1237275l (-1333058l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 18) (-1050970l) 1903435l 1869119l (-2994039l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 19) (-3548272l) 2635921l 1250494l (-3767016l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 20) 1595974l 2486353l 1247620l 4055324l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 21) 1265009l (-2590150l) 2691481l 2842341l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 22) 203044l 1735879l (-3342277l) 3437287l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 23) 4108315l (-2437823l) 286988l 342297l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 24) (-3595838l) (-768622l) (-525098l) (-3556995l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 25) 3207046l 2031748l (-3122442l) (-655327l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 26) (-522500l) (-43260l) (-1613174l) 495491l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 27) 819034l 909542l 1859098l 900702l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 28) (-3193378l) (-1197226l) (-3759364l) (-3520352l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 29) 3513181l (-1235728l) 2434439l 266997l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 30) (-3562462l) (-2446433l) 2244091l (-3342478l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0___round re (sz 31) 3817976l 2316500l 3407706l 2091667l + in + re + +let simd_unit_invert_ntt_at_layer_1_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta0 zeta1: i32) + = + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 0) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 2) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta0 + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 1) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 3) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta0 + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 4) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 6) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta1 + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 5) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 7) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta1 + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + simd_unit + +let invert_ntt_at_layer_1___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta_00_ zeta_01_: i32) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + index + (simd_unit_invert_ntt_at_layer_1_ (re.[ index ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + zeta_00_ + zeta_01_ + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + re + +let invert_ntt_at_layer_1_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 0) 3839961l (-3628969l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 1) (-3881060l) (-3019102l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 2) (-1439742l) (-812732l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 3) (-1584928l) 1285669l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 4) 1341330l 1315589l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 5) (-177440l) (-2409325l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 6) (-1851402l) 3159746l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 7) (-3553272l) 189548l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 8) (-1316856l) 759969l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 9) (-210977l) 2389356l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 10) (-3249728l) 1653064l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 11) (-8578l) (-3724342l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 12) 3958618l 904516l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 13) (-1100098l) 44288l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 14) 3097992l 508951l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 15) 264944l (-3343383l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 16) (-1430430l) 1852771l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 17) 1349076l (-381987l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 18) (-1308169l) (-22981l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 19) (-1228525l) (-671102l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 20) (-2477047l) (-411027l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 21) (-3693493l) (-2967645l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 22) 2715295l 2147896l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 23) (-983419l) 3412210l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 24) 126922l (-3632928l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 25) (-3157330l) (-3190144l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 26) (-1000202l) (-4083598l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 27) 1939314l (-1257611l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 28) (-1585221l) 2176455l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 29) 3475950l (-1452451l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 30) (-3041255l) (-3677745l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1___round re (sz 31) (-1528703l) (-3930395l) + in + re + +let simd_unit_invert_ntt_at_layer_2_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta: i32) + = + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 0) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 4) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta <: i32 + ) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 1) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 5) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta <: i32 + ) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 2) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 6) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta <: i32 + ) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let a_minus_b:i32 = + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] <: i32) -! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 3) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) +! + (simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] <: i32) + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 7) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer a_minus_b zeta <: i32 + ) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + simd_unit + +let invert_ntt_at_layer_2___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta1: i32) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + index + (simd_unit_invert_ntt_at_layer_2_ (re.[ index ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + zeta1 + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + re + +let invert_ntt_at_layer_2_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 0) (-2797779l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 1) 2071892l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 2) (-2556880l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 3) 3900724l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 4) 3881043l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 5) 954230l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 6) 531354l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 7) 811944l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 8) 3699596l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 9) (-1600420l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 10) (-2140649l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 11) 3507263l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 12) (-3821735l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 13) 3505694l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 14) (-1643818l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 15) (-1699267l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 16) (-539299l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 17) 2348700l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 18) (-300467l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 19) 3539968l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 20) (-2867647l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 21) 3574422l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 22) (-3043716l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 23) (-3861115l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 24) 3915439l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 25) (-2537516l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 26) (-3592148l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 27) (-1661693l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 28) 3530437l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 29) 3077325l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 30) 95776l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2___round re (sz 31) 2706023l + in + re + +let outer_3_plus + (v_OFFSET v_STEP_BY: usize) + (v_ZETA: i32) + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Folds.fold_range v_OFFSET + (v_OFFSET +! v_STEP_BY <: usize) + (fun re temp_1_ -> + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = re in + let _:usize = temp_1_ in + true) + re + (fun re j -> + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = re in + let j:usize = j in + let a_minus_b:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.subtract (re.[ j +! v_STEP_BY <: usize ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (re.[ j ] <: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + j + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.add (re.[ j ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (re.[ j +! v_STEP_BY <: usize ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + (j +! v_STEP_BY <: usize) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_by_constant a_minus_b + v_ZETA + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + re) + in + let hax_temp_output:Prims.unit = () <: Prims.unit in + re + +let invert_ntt_at_layer_3_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 1) 280005l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 2) (sz 1) 4010497l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 4) (sz 1) (-19422l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 6) (sz 1) 1757237l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 8) (sz 1) (-3277672l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 10) (sz 1) (-1399561l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 12) (sz 1) (-3859737l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 14) (sz 1) (-2118186l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 16) (sz 1) (-2108549l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 18) (sz 1) 2619752l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 20) (sz 1) (-1119584l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 22) (sz 1) (-549488l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 24) (sz 1) 3585928l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 26) (sz 1) (-1079900l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 28) (sz 1) 1024112l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 30) (sz 1) 2725464l re + in + re + +let invert_ntt_at_layer_4_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 2) 2680103l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 4) (sz 2) 3111497l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 8) (sz 2) (-2884855l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 12) (sz 2) 3119733l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 16) (sz 2) (-2091905l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 20) (sz 2) (-359251l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 24) (sz 2) 2353451l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 28) (sz 2) 1826347l re + in + re + +let invert_ntt_at_layer_5_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 4) 466468l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 8) (sz 4) (-876248l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 16) (sz 4) (-777960l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 24) (sz 4) 237124l re + in + re + +let invert_ntt_at_layer_6_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 8) (-518909l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 16) (sz 8) (-2608894l) re + in + re + +let invert_ntt_at_layer_7_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 16) 25847l re + in + re + +let invert_ntt_montgomery + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_0_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_1_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_2_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_3_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_4_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_5_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_6_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + invert_ntt_at_layer_7_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + (Core.Slice.impl__len #Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + (re <: t_Slice Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + <: + usize) + (fun re temp_1_ -> + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = re in + let _:usize = temp_1_ in + true) + re + (fun re i -> + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = re in + let i:usize = i in + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + i + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_by_constant (re.[ i ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + 41978l + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + <: + t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + in + re diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Invntt.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Invntt.fsti new file mode 100644 index 000000000..341dd3468 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Invntt.fsti @@ -0,0 +1,131 @@ +module Libcrux_ml_dsa.Simd.Portable.Invntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let invert_ntt_at_layer_3___STEP: usize = sz 8 + +let invert_ntt_at_layer_3___STEP_BY: usize = sz 1 + +let invert_ntt_at_layer_4___STEP: usize = sz 16 + +let invert_ntt_at_layer_4___STEP_BY: usize = sz 2 + +let invert_ntt_at_layer_5___STEP: usize = sz 32 + +let invert_ntt_at_layer_5___STEP_BY: usize = sz 4 + +let invert_ntt_at_layer_6___STEP: usize = sz 64 + +let invert_ntt_at_layer_6___STEP_BY: usize = sz 8 + +let invert_ntt_at_layer_7___STEP: usize = sz 128 + +let invert_ntt_at_layer_7___STEP_BY: usize = sz 16 + +val simd_unit_invert_ntt_at_layer_0_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta0 zeta1 zeta2 zeta3: i32) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_0___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta0 zeta1 zeta2 zeta3: i32) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_0_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val simd_unit_invert_ntt_at_layer_1_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta0 zeta1: i32) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_1___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta_00_ zeta_01_: i32) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_1_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val simd_unit_invert_ntt_at_layer_2_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta: i32) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_2___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta1: i32) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_2_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val outer_3_plus + (v_OFFSET v_STEP_BY: usize) + (v_ZETA: i32) + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_3_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_4_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_5_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_6_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_at_layer_7_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val invert_ntt_montgomery + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Ntt.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Ntt.fst new file mode 100644 index 000000000..6e1832690 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Ntt.fst @@ -0,0 +1,1019 @@ +module Libcrux_ml_dsa.Simd.Portable.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let simd_unit_ntt_at_layer_0_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta0 zeta1 zeta2 zeta3: i32) + = + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] + <: + i32) + zeta0 + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 1) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 0) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] + <: + i32) + zeta1 + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 3) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 2) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] + <: + i32) + zeta2 + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 5) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 4) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] + <: + i32) + zeta3 + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 7) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 6) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + simd_unit + +let ntt_at_layer_0___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta_0_ zeta_1_ zeta_2_ zeta_3_: i32) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + index + (simd_unit_ntt_at_layer_0_ (re.[ index ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + zeta_0_ + zeta_1_ + zeta_2_ + zeta_3_ + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + re + +let ntt_at_layer_0_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 0) 2091667l 3407706l 2316500l 3817976l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 1) (-3342478l) 2244091l (-2446433l) (-3562462l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 2) 266997l 2434439l (-1235728l) 3513181l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 3) (-3520352l) (-3759364l) (-1197226l) (-3193378l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 4) 900702l 1859098l 909542l 819034l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 5) 495491l (-1613174l) (-43260l) (-522500l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 6) (-655327l) (-3122442l) 2031748l 3207046l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 7) (-3556995l) (-525098l) (-768622l) (-3595838l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 8) 342297l 286988l (-2437823l) 4108315l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 9) 3437287l (-3342277l) 1735879l 203044l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 10) 2842341l 2691481l (-2590150l) 1265009l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 11) 4055324l 1247620l 2486353l 1595974l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 12) (-3767016l) 1250494l 2635921l (-3548272l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 13) (-2994039l) 1869119l 1903435l (-1050970l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 14) (-1333058l) 1237275l (-3318210l) (-1430225l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 15) (-451100l) 1312455l 3306115l (-1962642l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 16) (-1279661l) 1917081l (-2546312l) (-1374803l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 17) 1500165l 777191l 2235880l 3406031l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 18) (-542412l) (-2831860l) (-1671176l) (-1846953l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 19) (-2584293l) (-3724270l) 594136l (-3776993l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 20) (-2013608l) 2432395l 2454455l (-164721l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 21) 1957272l 3369112l 185531l (-1207385l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 22) (-3183426l) 162844l 1616392l 3014001l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 23) 810149l 1652634l (-3694233l) (-1799107l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 24) (-3038916l) 3523897l 3866901l 269760l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 25) 2213111l (-975884l) 1717735l 472078l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 26) (-426683l) 1723600l (-1803090l) 1910376l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 27) (-1667432l) (-1104333l) (-260646l) (-3833893l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 28) (-2939036l) (-2235985l) (-420899l) (-2286327l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 29) 183443l (-976891l) 1612842l (-3545687l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 30) (-554416l) 3919660l (-48306l) (-1362209l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0___round re (sz 31) 3937738l 1400424l (-846154l) 1976782l + in + re + +let simd_unit_ntt_at_layer_1_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta1 zeta2: i32) + = + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] + <: + i32) + zeta1 + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 2) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 0) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] + <: + i32) + zeta1 + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 3) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 1) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] + <: + i32) + zeta2 + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 6) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 4) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] + <: + i32) + zeta2 + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 7) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 5) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + simd_unit + +let ntt_at_layer_1___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta_0_ zeta_1_: i32) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + index + (simd_unit_ntt_at_layer_1_ (re.[ index ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + zeta_0_ + zeta_1_ + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + re + +let ntt_at_layer_1_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 0) (-3930395l) (-1528703l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 1) (-3677745l) (-3041255l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 2) (-1452451l) 3475950l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 3) 2176455l (-1585221l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 4) (-1257611l) 1939314l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 5) (-4083598l) (-1000202l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 6) (-3190144l) (-3157330l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 7) (-3632928l) 126922l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 8) 3412210l (-983419l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 9) 2147896l 2715295l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 10) (-2967645l) (-3693493l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 11) (-411027l) (-2477047l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 12) (-671102l) (-1228525l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 13) (-22981l) (-1308169l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 14) (-381987l) 1349076l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 15) 1852771l (-1430430l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 16) (-3343383l) 264944l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 17) 508951l 3097992l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 18) 44288l (-1100098l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 19) 904516l 3958618l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 20) (-3724342l) (-8578l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 21) 1653064l (-3249728l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 22) 2389356l (-210977l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 23) 759969l (-1316856l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 24) 189548l (-3553272l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 25) 3159746l (-1851402l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 26) (-2409325l) (-177440l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 27) 1315589l 1341330l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 28) 1285669l (-1584928l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 29) (-812732l) (-1439742l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 30) (-3019102l) (-3881060l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1___round re (sz 31) (-3628969l) 3839961l + in + re + +let simd_unit_ntt_at_layer_2_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta: i32) + = + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 4 ] + <: + i32) + zeta + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 4) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 0) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 0 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 5 ] + <: + i32) + zeta + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 5) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 1) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 1 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 6 ] + <: + i32) + zeta + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 6) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 2) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 2 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let t:i32 = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_fe_by_fer (simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 7 ] + <: + i32) + zeta + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 7) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) -! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + let simd_unit:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + simd_unit with + Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize simd_unit + .Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients + (sz 3) + ((simd_unit.Libcrux_ml_dsa.Simd.Portable.Vector_type.f_coefficients.[ sz 3 ] <: i32) +! t + <: + i32) + } + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + in + simd_unit + +let ntt_at_layer_2___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta: i32) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + index + (simd_unit_ntt_at_layer_2_ (re.[ index ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + zeta + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + re + +let ntt_at_layer_2_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 0) 2706023l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 1) 95776l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 2) 3077325l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 3) 3530437l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 4) (-1661693l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 5) (-3592148l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 6) (-2537516l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 7) 3915439l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 8) (-3861115l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 9) (-3043716l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 10) 3574422l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 11) (-2867647l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 12) 3539968l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 13) (-300467l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 14) 2348700l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 15) (-539299l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 16) (-1699267l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 17) (-1643818l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 18) 3505694l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 19) (-3821735l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 20) 3507263l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 21) (-2140649l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 22) (-1600420l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 23) 3699596l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 24) 811944l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 25) 531354l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 26) 954230l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 27) 3881043l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 28) 3900724l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 29) (-2556880l) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 30) 2071892l + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2___round re (sz 31) (-2797779l) + in + re + +let outer_3_plus + (v_OFFSET v_STEP_BY: usize) + (v_ZETA: i32) + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Folds.fold_range v_OFFSET + (v_OFFSET +! v_STEP_BY <: usize) + (fun re temp_1_ -> + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = re in + let _:usize = temp_1_ in + true) + re + (fun re j -> + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = re in + let j:usize = j in + let t:Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply_by_constant (re.[ j +! + v_STEP_BY + <: + usize ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + v_ZETA + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + (j +! v_STEP_BY <: usize) + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.subtract (re.[ j ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + t + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + j + (Libcrux_ml_dsa.Simd.Portable.Arithmetic.add (re.[ j ] + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + t + <: + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + in + re) + in + let hax_temp_output:Prims.unit = () <: Prims.unit in + re + +let ntt_at_layer_3_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 1) 2725464l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 2) (sz 1) 1024112l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 4) (sz 1) (-1079900l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 6) (sz 1) 3585928l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 8) (sz 1) (-549488l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 10) (sz 1) (-1119584l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 12) (sz 1) 2619752l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 14) (sz 1) (-2108549l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 16) (sz 1) (-2118186l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 18) (sz 1) (-3859737l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 20) (sz 1) (-1399561l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 22) (sz 1) (-3277672l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 24) (sz 1) 1757237l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 26) (sz 1) (-19422l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 28) (sz 1) 4010497l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 30) (sz 1) 280005l re + in + re + +let ntt_at_layer_4_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 2) 1826347l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 4) (sz 2) 2353451l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 8) (sz 2) (-359251l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 12) (sz 2) (-2091905l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 16) (sz 2) 3119733l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 20) (sz 2) (-2884855l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 24) (sz 2) 3111497l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 28) (sz 2) 2680103l re + in + re + +let ntt_at_layer_5_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 4) 237124l re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 8) (sz 4) (-777960l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 16) (sz 4) (-876248l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 24) (sz 4) 466468l re + in + re + +let ntt_at_layer_6_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 8) (-2608894l) re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 16) (sz 8) (-518909l) re + in + re + +let ntt_at_layer_7_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + outer_3_plus (sz 0) (sz 16) 25847l re + in + re + +let ntt (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) = + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_7_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_6_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_5_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_4_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_3_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_2_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_1_ re + in + let re:t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32) = + ntt_at_layer_0_ re + in + re diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Ntt.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Ntt.fsti new file mode 100644 index 000000000..08682c48d --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Ntt.fsti @@ -0,0 +1,130 @@ +module Libcrux_ml_dsa.Simd.Portable.Ntt +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let ntt_at_layer_3___STEP: usize = sz 8 + +let ntt_at_layer_3___STEP_BY: usize = sz 1 + +let ntt_at_layer_4___STEP: usize = sz 16 + +let ntt_at_layer_4___STEP_BY: usize = sz 2 + +let ntt_at_layer_5___STEP: usize = sz 32 + +let ntt_at_layer_5___STEP_BY: usize = sz 4 + +let ntt_at_layer_6___STEP: usize = sz 64 + +let ntt_at_layer_6___STEP_BY: usize = sz 8 + +let ntt_at_layer_7___STEP: usize = sz 128 + +let ntt_at_layer_7___STEP_BY: usize = sz 16 + +val simd_unit_ntt_at_layer_0_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta0 zeta1 zeta2 zeta3: i32) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_0___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta_0_ zeta_1_ zeta_2_ zeta_3_: i32) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_0_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val simd_unit_ntt_at_layer_1_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta1 zeta2: i32) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_1___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta_0_ zeta_1_: i32) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_1_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val simd_unit_ntt_at_layer_2_ + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (zeta: i32) + : Prims.Pure Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_2___round + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (index: usize) + (zeta: i32) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_2_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val outer_3_plus + (v_OFFSET v_STEP_BY: usize) + (v_ZETA: i32) + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_3_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_4_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_5_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_6_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt_at_layer_7_ + (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +val ntt (re: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + : Prims.Pure (t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Sample.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Sample.fst new file mode 100644 index 000000000..25f533de9 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Sample.fst @@ -0,0 +1,123 @@ +module Libcrux_ml_dsa.Simd.Portable.Sample +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let rejection_sample_less_than_eta_equals_2_ (randomness: t_Slice u8) (out: t_Slice i32) = + let sampled:usize = sz 0 in + let out, sampled:(t_Slice i32 & usize) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(t_Slice u8) + #FStar.Tactics.Typeclasses.solve + randomness + <: + Core.Slice.Iter.t_Iter u8) + (out, sampled <: (t_Slice i32 & usize)) + (fun temp_0_ byte -> + let out, sampled:(t_Slice i32 & usize) = temp_0_ in + let byte:u8 = byte in + let try_0_:u8 = byte &. 15uy in + let try_1_:u8 = byte >>! 4l in + let out, sampled:(t_Slice i32 & usize) = + if try_0_ <. 15uy + then + let try_0_:i32 = cast (try_0_ <: u8) <: i32 in + let try_0_mod_5_:i32 = + try_0_ -! (((try_0_ *! 26l <: i32) >>! 7l <: i32) *! 5l <: i32) + in + let out:t_Slice i32 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + sampled + (2l -! try_0_mod_5_ <: i32) + in + let sampled:usize = sampled +! sz 1 in + out, sampled <: (t_Slice i32 & usize) + else out, sampled <: (t_Slice i32 & usize) + in + if try_1_ <. 15uy + then + let try_1_:i32 = cast (try_1_ <: u8) <: i32 in + let try_1_mod_5_:i32 = + try_1_ -! (((try_1_ *! 26l <: i32) >>! 7l <: i32) *! 5l <: i32) + in + let out:t_Slice i32 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + sampled + (2l -! try_1_mod_5_ <: i32) + in + let sampled:usize = sampled +! sz 1 in + out, sampled <: (t_Slice i32 & usize) + else out, sampled <: (t_Slice i32 & usize)) + in + let hax_temp_output:usize = sampled in + out, hax_temp_output <: (t_Slice i32 & usize) + +let rejection_sample_less_than_eta_equals_4_ (randomness: t_Slice u8) (out: t_Slice i32) = + let sampled:usize = sz 0 in + let out, sampled:(t_Slice i32 & usize) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(t_Slice u8) + #FStar.Tactics.Typeclasses.solve + randomness + <: + Core.Slice.Iter.t_Iter u8) + (out, sampled <: (t_Slice i32 & usize)) + (fun temp_0_ byte -> + let out, sampled:(t_Slice i32 & usize) = temp_0_ in + let byte:u8 = byte in + let try_0_:u8 = byte &. 15uy in + let try_1_:u8 = byte >>! 4l in + let out, sampled:(t_Slice i32 & usize) = + if try_0_ <. 9uy + then + let out:t_Slice i32 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + sampled + (4l -! (cast (try_0_ <: u8) <: i32) <: i32) + in + let sampled:usize = sampled +! sz 1 in + out, sampled <: (t_Slice i32 & usize) + else out, sampled <: (t_Slice i32 & usize) + in + if try_1_ <. 9uy + then + let out:t_Slice i32 = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out + sampled + (4l -! (cast (try_1_ <: u8) <: i32) <: i32) + in + let sampled:usize = sampled +! sz 1 in + out, sampled <: (t_Slice i32 & usize) + else out, sampled <: (t_Slice i32 & usize)) + in + let hax_temp_output:usize = sampled in + out, hax_temp_output <: (t_Slice i32 & usize) + +let rejection_sample_less_than_field_modulus (randomness: t_Slice u8) (out: t_Slice i32) = + let sampled:usize = sz 0 in + let out, sampled:(t_Slice i32 & usize) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter #(Core.Slice.Iter.t_Chunks + u8) + #FStar.Tactics.Typeclasses.solve + (Core.Slice.impl__chunks #u8 randomness (sz 3) <: Core.Slice.Iter.t_Chunks u8) + <: + Core.Slice.Iter.t_Chunks u8) + (out, sampled <: (t_Slice i32 & usize)) + (fun temp_0_ bytes -> + let out, sampled:(t_Slice i32 & usize) = temp_0_ in + let bytes:t_Slice u8 = bytes in + let b0:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in + let b1:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in + let b2:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in + let coefficient:i32 = + (((b2 < Prims.l_True) + +val rejection_sample_less_than_eta_equals_4_ (randomness: t_Slice u8) (out: t_Slice i32) + : Prims.Pure (t_Slice i32 & usize) Prims.l_True (fun _ -> Prims.l_True) + +val rejection_sample_less_than_field_modulus (randomness: t_Slice u8) (out: t_Slice i32) + : Prims.Pure (t_Slice i32 & usize) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Vector_type.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Vector_type.fst new file mode 100644 index 000000000..338234407 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Vector_type.fst @@ -0,0 +1,29 @@ +module Libcrux_ml_dsa.Simd.Portable.Vector_type +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let from_coefficient_array (array: t_Slice i32) = + { + f_coefficients + = + Core.Result.impl__unwrap #(t_Array i32 (sz 8)) + #Core.Array.t_TryFromSliceError + (Core.Convert.f_try_into #(t_Slice i32) + #(t_Array i32 (sz 8)) + #FStar.Tactics.Typeclasses.solve + (array.[ { Core.Ops.Range.f_start = sz 0; Core.Ops.Range.f_end = sz 8 } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice i32) + <: + Core.Result.t_Result (t_Array i32 (sz 8)) Core.Array.t_TryFromSliceError) + } + <: + t_PortableSIMDUnit + +let to_coefficient_array (x: t_PortableSIMDUnit) = x.f_coefficients + +let v_ZERO (_: Prims.unit) = + { f_coefficients = Rust_primitives.Hax.repeat 0l (sz 8) } <: t_PortableSIMDUnit diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Vector_type.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Vector_type.fsti new file mode 100644 index 000000000..0b3010e59 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.Vector_type.fsti @@ -0,0 +1,14 @@ +module Libcrux_ml_dsa.Simd.Portable.Vector_type +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +type t_PortableSIMDUnit = { f_coefficients:t_Array i32 (sz 8) } + +val from_coefficient_array (array: t_Slice i32) + : Prims.Pure t_PortableSIMDUnit Prims.l_True (fun _ -> Prims.l_True) + +val to_coefficient_array (x: t_PortableSIMDUnit) + : Prims.Pure (t_Array i32 (sz 8)) Prims.l_True (fun _ -> Prims.l_True) + +val v_ZERO: Prims.unit -> Prims.Pure t_PortableSIMDUnit Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.fst new file mode 100644 index 000000000..b5c72724c --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.fst @@ -0,0 +1,462 @@ +module Libcrux_ml_dsa.Simd.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Portable.Vector_type in + () + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: Libcrux_ml_dsa.Simd.Traits.t_Operations +Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + f_ZERO_pre = (fun (_: Prims.unit) -> true); + f_ZERO_post + = + (fun (_: Prims.unit) (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> true); + f_ZERO = (fun (_: Prims.unit) -> Libcrux_ml_dsa.Simd.Portable.Vector_type.v_ZERO ()); + f_from_coefficient_array_pre = (fun (array: t_Slice i32) -> true); + f_from_coefficient_array_post + = + (fun (array: t_Slice i32) (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> + true); + f_from_coefficient_array + = + (fun (array: t_Slice i32) -> + Libcrux_ml_dsa.Simd.Portable.Vector_type.from_coefficient_array array); + f_to_coefficient_array_pre + = + (fun (self: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> true); + f_to_coefficient_array_post + = + (fun + (self: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: t_Array i32 (sz 8)) + -> + true); + f_to_coefficient_array + = + (fun (self: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> + Libcrux_ml_dsa.Simd.Portable.Vector_type.to_coefficient_array self); + f_add_pre + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_add_post + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_add + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.add lhs rhs); + f_subtract_pre + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_subtract_post + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_subtract + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.subtract lhs rhs); + f_montgomery_multiply_pre + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_montgomery_multiply_post + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_montgomery_multiply + = + (fun + (lhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (rhs: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.montgomery_multiply lhs rhs); + f_shift_left_then_reduce_pre + = + (fun + (v_SHIFT_BY: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_shift_left_then_reduce_post + = + (fun + (v_SHIFT_BY: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_shift_left_then_reduce + = + (fun + (v_SHIFT_BY: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.shift_left_then_reduce v_SHIFT_BY simd_unit); + f_power2round_pre + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> true); + f_power2round_post + = + (fun + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit)) + -> + true); + f_power2round + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.power2round simd_unit); + f_infinity_norm_exceeds_pre + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) (bound: i32) -> + true); + f_infinity_norm_exceeds_post + = + (fun + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (bound: i32) + (out: bool) + -> + true); + f_infinity_norm_exceeds + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) (bound: i32) -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.infinity_norm_exceeds simd_unit bound); + f_decompose_pre + = + (fun (v_GAMMA2: i32) (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> + true); + f_decompose_post + = + (fun + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: + (Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit & + Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit)) + -> + true); + f_decompose + = + (fun (v_GAMMA2: i32) (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.decompose v_GAMMA2 simd_unit); + f_compute_hint_pre + = + (fun + (v_GAMMA2: i32) + (low: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (high: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_compute_hint_post + = + (fun + (v_GAMMA2: i32) + (low: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (high: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: (usize & Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit)) + -> + true); + f_compute_hint + = + (fun + (v_GAMMA2: i32) + (low: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (high: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.compute_hint v_GAMMA2 low high); + f_use_hint_pre + = + (fun + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (hint: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_use_hint_post + = + (fun + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (hint: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_use_hint + = + (fun + (v_GAMMA2: i32) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (hint: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Arithmetic.use_hint v_GAMMA2 simd_unit hint); + f_rejection_sample_less_than_field_modulus_pre + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> true); + f_rejection_sample_less_than_field_modulus_post + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) (out2: (t_Slice i32 & usize)) -> true); + f_rejection_sample_less_than_field_modulus + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Portable.Sample.rejection_sample_less_than_field_modulus randomness + out + in + let out:t_Slice i32 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i32 & usize)); + f_rejection_sample_less_than_eta_equals_2_pre + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> true); + f_rejection_sample_less_than_eta_equals_2_post + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) (out2: (t_Slice i32 & usize)) -> true); + f_rejection_sample_less_than_eta_equals_2_ + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Portable.Sample.rejection_sample_less_than_eta_equals_2_ randomness + out + in + let out:t_Slice i32 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i32 & usize)); + f_rejection_sample_less_than_eta_equals_4_pre + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> true); + f_rejection_sample_less_than_eta_equals_4_post + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) (out2: (t_Slice i32 & usize)) -> true); + f_rejection_sample_less_than_eta_equals_4_ + = + (fun (randomness: t_Slice u8) (out: t_Slice i32) -> + let tmp0, out1:(t_Slice i32 & usize) = + Libcrux_ml_dsa.Simd.Portable.Sample.rejection_sample_less_than_eta_equals_4_ randomness + out + in + let out:t_Slice i32 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i32 & usize)); + f_gamma1_serialize_pre + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_gamma1_serialize_post + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: t_Array u8 v_OUTPUT_SIZE) + -> + true); + f_gamma1_serialize + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1.serialize v_OUTPUT_SIZE simd_unit); + f_gamma1_deserialize_pre = (fun (v_GAMMA1_EXPONENT: usize) (serialized: t_Slice u8) -> true); + f_gamma1_deserialize_post + = + (fun + (v_GAMMA1_EXPONENT: usize) + (serialized: t_Slice u8) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_gamma1_deserialize + = + (fun (v_GAMMA1_EXPONENT: usize) (serialized: t_Slice u8) -> + Libcrux_ml_dsa.Simd.Portable.Encoding.Gamma1.deserialize v_GAMMA1_EXPONENT serialized); + f_commitment_serialize_pre + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_commitment_serialize_post + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: t_Array u8 v_OUTPUT_SIZE) + -> + true); + f_commitment_serialize + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Encoding.Commitment.serialize v_OUTPUT_SIZE simd_unit); + f_error_serialize_pre + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_error_serialize_post + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: t_Array u8 v_OUTPUT_SIZE) + -> + true); + f_error_serialize + = + (fun + (v_OUTPUT_SIZE: usize) + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + Libcrux_ml_dsa.Simd.Portable.Encoding.Error.serialize v_OUTPUT_SIZE simd_unit); + f_error_deserialize_pre = (fun (v_ETA: usize) (serialized: t_Slice u8) -> true); + f_error_deserialize_post + = + (fun + (v_ETA: usize) + (serialized: t_Slice u8) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_error_deserialize + = + (fun (v_ETA: usize) (serialized: t_Slice u8) -> + Libcrux_ml_dsa.Simd.Portable.Encoding.Error.deserialize v_ETA serialized); + f_t0_serialize_pre + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> true); + f_t0_serialize_post + = + (fun + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: t_Array u8 (sz 13)) + -> + true); + f_t0_serialize + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> + Libcrux_ml_dsa.Simd.Portable.Encoding.T0.serialize simd_unit); + f_t0_deserialize_pre = (fun (serialized: t_Slice u8) -> true); + f_t0_deserialize_post + = + (fun + (serialized: t_Slice u8) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_t0_deserialize + = + (fun (serialized: t_Slice u8) -> Libcrux_ml_dsa.Simd.Portable.Encoding.T0.deserialize serialized + ); + f_t1_serialize_pre + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> true); + f_t1_serialize_post + = + (fun + (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + (out: t_Array u8 (sz 10)) + -> + true); + f_t1_serialize + = + (fun (simd_unit: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) -> + Libcrux_ml_dsa.Simd.Portable.Encoding.T1.serialize simd_unit); + f_t1_deserialize_pre = (fun (serialized: t_Slice u8) -> true); + f_t1_deserialize_post + = + (fun + (serialized: t_Slice u8) + (out: Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit) + -> + true); + f_t1_deserialize + = + (fun (serialized: t_Slice u8) -> Libcrux_ml_dsa.Simd.Portable.Encoding.T1.deserialize serialized + ); + f_ntt_pre + = + (fun + (simd_units: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + -> + true); + f_ntt_post + = + (fun + (simd_units: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (out: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + -> + true); + f_ntt + = + (fun + (simd_units: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + -> + Libcrux_ml_dsa.Simd.Portable.Ntt.ntt simd_units); + f_invert_ntt_montgomery_pre + = + (fun + (simd_units: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + -> + true); + f_invert_ntt_montgomery_post + = + (fun + (simd_units: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + (out: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) + -> + true); + f_invert_ntt_montgomery + = + fun (simd_units: t_Array Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit (sz 32)) -> + Libcrux_ml_dsa.Simd.Portable.Invntt.invert_ntt_montgomery simd_units + } diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.fsti new file mode 100644 index 000000000..c3bcf3d6d --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Portable.fsti @@ -0,0 +1,14 @@ +module Libcrux_ml_dsa.Simd.Portable +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Portable.Vector_type in + () + +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl:Libcrux_ml_dsa.Simd.Traits.t_Operations +Libcrux_ml_dsa.Simd.Portable.Vector_type.t_PortableSIMDUnit diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Traits.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Traits.fsti new file mode 100644 index 000000000..280e421e6 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Simd.Traits.fsti @@ -0,0 +1,164 @@ +module Libcrux_ml_dsa.Simd.Traits +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +class t_Operations (v_Self: Type0) = { + [@@@ FStar.Tactics.Typeclasses.no_method]_super_11581440318597584651:Core.Marker.t_Copy v_Self; + [@@@ FStar.Tactics.Typeclasses.no_method]_super_9442900250278684536:Core.Clone.t_Clone v_Self; + f_ZERO_pre:Prims.unit -> Type0; + f_ZERO_post:Prims.unit -> v_Self -> Type0; + f_ZERO:x0: Prims.unit -> Prims.Pure v_Self (f_ZERO_pre x0) (fun result -> f_ZERO_post x0 result); + f_from_coefficient_array_pre:t_Slice i32 -> Type0; + f_from_coefficient_array_post:t_Slice i32 -> v_Self -> Type0; + f_from_coefficient_array:x0: t_Slice i32 + -> Prims.Pure v_Self + (f_from_coefficient_array_pre x0) + (fun result -> f_from_coefficient_array_post x0 result); + f_to_coefficient_array_pre:v_Self -> Type0; + f_to_coefficient_array_post:v_Self -> t_Array i32 (sz 8) -> Type0; + f_to_coefficient_array:x0: v_Self + -> Prims.Pure (t_Array i32 (sz 8)) + (f_to_coefficient_array_pre x0) + (fun result -> f_to_coefficient_array_post x0 result); + f_add_pre:v_Self -> v_Self -> Type0; + f_add_post:v_Self -> v_Self -> v_Self -> Type0; + f_add:x0: v_Self -> x1: v_Self + -> Prims.Pure v_Self (f_add_pre x0 x1) (fun result -> f_add_post x0 x1 result); + f_subtract_pre:v_Self -> v_Self -> Type0; + f_subtract_post:v_Self -> v_Self -> v_Self -> Type0; + f_subtract:x0: v_Self -> x1: v_Self + -> Prims.Pure v_Self (f_subtract_pre x0 x1) (fun result -> f_subtract_post x0 x1 result); + f_infinity_norm_exceeds_pre:v_Self -> i32 -> Type0; + f_infinity_norm_exceeds_post:v_Self -> i32 -> bool -> Type0; + f_infinity_norm_exceeds:x0: v_Self -> x1: i32 + -> Prims.Pure bool + (f_infinity_norm_exceeds_pre x0 x1) + (fun result -> f_infinity_norm_exceeds_post x0 x1 result); + f_decompose_pre:v_GAMMA2: i32 -> v_Self -> Type0; + f_decompose_post:v_GAMMA2: i32 -> v_Self -> (v_Self & v_Self) -> Type0; + f_decompose:v_GAMMA2: i32 -> x0: v_Self + -> Prims.Pure (v_Self & v_Self) + (f_decompose_pre v_GAMMA2 x0) + (fun result -> f_decompose_post v_GAMMA2 x0 result); + f_compute_hint_pre:v_GAMMA2: i32 -> v_Self -> v_Self -> Type0; + f_compute_hint_post:v_GAMMA2: i32 -> v_Self -> v_Self -> (usize & v_Self) -> Type0; + f_compute_hint:v_GAMMA2: i32 -> x0: v_Self -> x1: v_Self + -> Prims.Pure (usize & v_Self) + (f_compute_hint_pre v_GAMMA2 x0 x1) + (fun result -> f_compute_hint_post v_GAMMA2 x0 x1 result); + f_use_hint_pre:v_GAMMA2: i32 -> v_Self -> v_Self -> Type0; + f_use_hint_post:v_GAMMA2: i32 -> v_Self -> v_Self -> v_Self -> Type0; + f_use_hint:v_GAMMA2: i32 -> x0: v_Self -> x1: v_Self + -> Prims.Pure v_Self + (f_use_hint_pre v_GAMMA2 x0 x1) + (fun result -> f_use_hint_post v_GAMMA2 x0 x1 result); + f_montgomery_multiply_pre:v_Self -> v_Self -> Type0; + f_montgomery_multiply_post:v_Self -> v_Self -> v_Self -> Type0; + f_montgomery_multiply:x0: v_Self -> x1: v_Self + -> Prims.Pure v_Self + (f_montgomery_multiply_pre x0 x1) + (fun result -> f_montgomery_multiply_post x0 x1 result); + f_shift_left_then_reduce_pre:v_SHIFT_BY: i32 -> v_Self -> Type0; + f_shift_left_then_reduce_post:v_SHIFT_BY: i32 -> v_Self -> v_Self -> Type0; + f_shift_left_then_reduce:v_SHIFT_BY: i32 -> x0: v_Self + -> Prims.Pure v_Self + (f_shift_left_then_reduce_pre v_SHIFT_BY x0) + (fun result -> f_shift_left_then_reduce_post v_SHIFT_BY x0 result); + f_power2round_pre:v_Self -> Type0; + f_power2round_post:v_Self -> (v_Self & v_Self) -> Type0; + f_power2round:x0: v_Self + -> Prims.Pure (v_Self & v_Self) + (f_power2round_pre x0) + (fun result -> f_power2round_post x0 result); + f_rejection_sample_less_than_field_modulus_pre:t_Slice u8 -> t_Slice i32 -> Type0; + f_rejection_sample_less_than_field_modulus_post:t_Slice u8 -> t_Slice i32 -> (t_Slice i32 & usize) + -> Type0; + f_rejection_sample_less_than_field_modulus:x0: t_Slice u8 -> x1: t_Slice i32 + -> Prims.Pure (t_Slice i32 & usize) + (f_rejection_sample_less_than_field_modulus_pre x0 x1) + (fun result -> f_rejection_sample_less_than_field_modulus_post x0 x1 result); + f_rejection_sample_less_than_eta_equals_2_pre:t_Slice u8 -> t_Slice i32 -> Type0; + f_rejection_sample_less_than_eta_equals_2_post:t_Slice u8 -> t_Slice i32 -> (t_Slice i32 & usize) + -> Type0; + f_rejection_sample_less_than_eta_equals_2_:x0: t_Slice u8 -> x1: t_Slice i32 + -> Prims.Pure (t_Slice i32 & usize) + (f_rejection_sample_less_than_eta_equals_2_pre x0 x1) + (fun result -> f_rejection_sample_less_than_eta_equals_2_post x0 x1 result); + f_rejection_sample_less_than_eta_equals_4_pre:t_Slice u8 -> t_Slice i32 -> Type0; + f_rejection_sample_less_than_eta_equals_4_post:t_Slice u8 -> t_Slice i32 -> (t_Slice i32 & usize) + -> Type0; + f_rejection_sample_less_than_eta_equals_4_:x0: t_Slice u8 -> x1: t_Slice i32 + -> Prims.Pure (t_Slice i32 & usize) + (f_rejection_sample_less_than_eta_equals_4_pre x0 x1) + (fun result -> f_rejection_sample_less_than_eta_equals_4_post x0 x1 result); + f_gamma1_serialize_pre:v_OUTPUT_SIZE: usize -> v_Self -> Type0; + f_gamma1_serialize_post:v_OUTPUT_SIZE: usize -> v_Self -> t_Array u8 v_OUTPUT_SIZE -> Type0; + f_gamma1_serialize:v_OUTPUT_SIZE: usize -> x0: v_Self + -> Prims.Pure (t_Array u8 v_OUTPUT_SIZE) + (f_gamma1_serialize_pre v_OUTPUT_SIZE x0) + (fun result -> f_gamma1_serialize_post v_OUTPUT_SIZE x0 result); + f_gamma1_deserialize_pre:v_GAMMA1_EXPONENT: usize -> t_Slice u8 -> Type0; + f_gamma1_deserialize_post:v_GAMMA1_EXPONENT: usize -> t_Slice u8 -> v_Self -> Type0; + f_gamma1_deserialize:v_GAMMA1_EXPONENT: usize -> x0: t_Slice u8 + -> Prims.Pure v_Self + (f_gamma1_deserialize_pre v_GAMMA1_EXPONENT x0) + (fun result -> f_gamma1_deserialize_post v_GAMMA1_EXPONENT x0 result); + f_commitment_serialize_pre:v_OUTPUT_SIZE: usize -> v_Self -> Type0; + f_commitment_serialize_post:v_OUTPUT_SIZE: usize -> v_Self -> t_Array u8 v_OUTPUT_SIZE -> Type0; + f_commitment_serialize:v_OUTPUT_SIZE: usize -> x0: v_Self + -> Prims.Pure (t_Array u8 v_OUTPUT_SIZE) + (f_commitment_serialize_pre v_OUTPUT_SIZE x0) + (fun result -> f_commitment_serialize_post v_OUTPUT_SIZE x0 result); + f_error_serialize_pre:v_OUTPUT_SIZE: usize -> v_Self -> Type0; + f_error_serialize_post:v_OUTPUT_SIZE: usize -> v_Self -> t_Array u8 v_OUTPUT_SIZE -> Type0; + f_error_serialize:v_OUTPUT_SIZE: usize -> x0: v_Self + -> Prims.Pure (t_Array u8 v_OUTPUT_SIZE) + (f_error_serialize_pre v_OUTPUT_SIZE x0) + (fun result -> f_error_serialize_post v_OUTPUT_SIZE x0 result); + f_error_deserialize_pre:v_ETA: usize -> t_Slice u8 -> Type0; + f_error_deserialize_post:v_ETA: usize -> t_Slice u8 -> v_Self -> Type0; + f_error_deserialize:v_ETA: usize -> x0: t_Slice u8 + -> Prims.Pure v_Self + (f_error_deserialize_pre v_ETA x0) + (fun result -> f_error_deserialize_post v_ETA x0 result); + f_t0_serialize_pre:v_Self -> Type0; + f_t0_serialize_post:v_Self -> t_Array u8 (sz 13) -> Type0; + f_t0_serialize:x0: v_Self + -> Prims.Pure (t_Array u8 (sz 13)) + (f_t0_serialize_pre x0) + (fun result -> f_t0_serialize_post x0 result); + f_t0_deserialize_pre:t_Slice u8 -> Type0; + f_t0_deserialize_post:t_Slice u8 -> v_Self -> Type0; + f_t0_deserialize:x0: t_Slice u8 + -> Prims.Pure v_Self (f_t0_deserialize_pre x0) (fun result -> f_t0_deserialize_post x0 result); + f_t1_serialize_pre:v_Self -> Type0; + f_t1_serialize_post:v_Self -> t_Array u8 (sz 10) -> Type0; + f_t1_serialize:x0: v_Self + -> Prims.Pure (t_Array u8 (sz 10)) + (f_t1_serialize_pre x0) + (fun result -> f_t1_serialize_post x0 result); + f_t1_deserialize_pre:t_Slice u8 -> Type0; + f_t1_deserialize_post:t_Slice u8 -> v_Self -> Type0; + f_t1_deserialize:x0: t_Slice u8 + -> Prims.Pure v_Self (f_t1_deserialize_pre x0) (fun result -> f_t1_deserialize_post x0 result); + f_ntt_pre:t_Array v_Self (sz 32) -> Type0; + f_ntt_post:t_Array v_Self (sz 32) -> t_Array v_Self (sz 32) -> Type0; + f_ntt:x0: t_Array v_Self (sz 32) + -> Prims.Pure (t_Array v_Self (sz 32)) (f_ntt_pre x0) (fun result -> f_ntt_post x0 result); + f_invert_ntt_montgomery_pre:t_Array v_Self (sz 32) -> Type0; + f_invert_ntt_montgomery_post:t_Array v_Self (sz 32) -> t_Array v_Self (sz 32) -> Type0; + f_invert_ntt_montgomery:x0: t_Array v_Self (sz 32) + -> Prims.Pure (t_Array v_Self (sz 32)) + (f_invert_ntt_montgomery_pre x0) + (fun result -> f_invert_ntt_montgomery_post x0 result) +} + +let v_COEFFICIENTS_IN_SIMD_UNIT: usize = sz 8 + +let v_FIELD_MODULUS: i32 = 8380417l + +let v_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R: u64 = 58728449uL + +let v_SIMD_UNITS_IN_RING_ELEMENT: usize = + Libcrux_ml_dsa.Constants.v_COEFFICIENTS_IN_RING_ELEMENT /! v_COEFFICIENTS_IN_SIMD_UNIT diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Types.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Types.fst new file mode 100644 index 000000000..8af0ff228 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Types.fst @@ -0,0 +1,34 @@ +module Libcrux_ml_dsa.Types +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +let impl__len (v_SIZE: usize) (_: Prims.unit) = v_SIZE + +let impl_2__len (v_SIZE: usize) (_: Prims.unit) = v_SIZE + +let impl_4__len (v_SIZE: usize) (_: Prims.unit) = v_SIZE + +let t_SigningError_cast_to_repr (x: t_SigningError) = + match x with + | SigningError_RejectionSamplingError -> isz 0 + | SigningError_ContextTooLongError -> isz 1 + +let t_VerificationError_cast_to_repr (x: t_VerificationError) = + match x with + | VerificationError_MalformedHintError -> isz 0 + | VerificationError_SignerResponseExceedsBoundError -> isz 1 + | VerificationError_CommitmentHashesDontMatchError -> isz 3 + | VerificationError_ContextTooLongError -> isz 6 + +let impl__as_slice (v_SIZE: usize) (self: t_MLDSASigningKey v_SIZE) = self._0 <: t_Slice u8 + +let impl_2__as_slice (v_SIZE: usize) (self: t_MLDSAVerificationKey v_SIZE) = self._0 <: t_Slice u8 + +let impl_4__as_slice (v_SIZE: usize) (self: t_MLDSASignature v_SIZE) = self._0 <: t_Slice u8 diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Types.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Types.fsti new file mode 100644 index 000000000..f121066d7 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Types.fsti @@ -0,0 +1,77 @@ +module Libcrux_ml_dsa.Types +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_dsa.Simd.Traits in + () + +/// The number of bytes +val impl__len: v_SIZE: usize -> Prims.unit -> Prims.Pure usize Prims.l_True (fun _ -> Prims.l_True) + +/// The number of bytes +val impl_2__len: v_SIZE: usize -> Prims.unit + -> Prims.Pure usize Prims.l_True (fun _ -> Prims.l_True) + +/// The number of bytes +val impl_4__len: v_SIZE: usize -> Prims.unit + -> Prims.Pure usize Prims.l_True (fun _ -> Prims.l_True) + +///An ML-DSA signature. +type t_MLDSASignature (v_SIZE: usize) = + | MLDSASignature : t_Array u8 v_SIZE -> t_MLDSASignature v_SIZE + +///An ML-DSA signature key. +type t_MLDSASigningKey (v_SIZE: usize) = + | MLDSASigningKey : t_Array u8 v_SIZE -> t_MLDSASigningKey v_SIZE + +///An ML-DSA verification key. +type t_MLDSAVerificationKey (v_SIZE: usize) = + | MLDSAVerificationKey : t_Array u8 v_SIZE -> t_MLDSAVerificationKey v_SIZE + +/// An ML-DSA key pair. +type t_MLDSAKeyPair (v_VERIFICATION_KEY_SIZE: usize) (v_SIGNING_KEY_SIZE: usize) = { + f_signing_key:t_MLDSASigningKey v_SIGNING_KEY_SIZE; + f_verification_key:t_MLDSAVerificationKey v_VERIFICATION_KEY_SIZE +} + +type t_Signature + (v_SIMDUnit: Type0) (v_COMMITMENT_HASH_SIZE: usize) (v_COLUMNS_IN_A: usize) (v_ROWS_IN_A: usize) + {| i1: Libcrux_ml_dsa.Simd.Traits.t_Operations v_SIMDUnit |} + = { + f_commitment_hash:t_Array u8 v_COMMITMENT_HASH_SIZE; + f_signer_response:t_Array (Libcrux_ml_dsa.Polynomial.t_PolynomialRingElement v_SIMDUnit) + v_COLUMNS_IN_A; + f_hint:t_Array (t_Array i32 (sz 256)) v_ROWS_IN_A +} + +type t_SigningError = + | SigningError_RejectionSamplingError : t_SigningError + | SigningError_ContextTooLongError : t_SigningError + +val t_SigningError_cast_to_repr (x: t_SigningError) + : Prims.Pure isize Prims.l_True (fun _ -> Prims.l_True) + +type t_VerificationError = + | VerificationError_MalformedHintError : t_VerificationError + | VerificationError_SignerResponseExceedsBoundError : t_VerificationError + | VerificationError_CommitmentHashesDontMatchError : t_VerificationError + | VerificationError_ContextTooLongError : t_VerificationError + +val t_VerificationError_cast_to_repr (x: t_VerificationError) + : Prims.Pure isize Prims.l_True (fun _ -> Prims.l_True) + +/// A reference to the raw byte slice. +val impl__as_slice (v_SIZE: usize) (self: t_MLDSASigningKey v_SIZE) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A reference to the raw byte slice. +val impl_2__as_slice (v_SIZE: usize) (self: t_MLDSAVerificationKey v_SIZE) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) + +/// A reference to the raw byte slice. +val impl_4__as_slice (v_SIZE: usize) (self: t_MLDSASignature v_SIZE) + : Prims.Pure (t_Slice u8) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Utils.fst b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Utils.fst new file mode 100644 index 000000000..82aa84965 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Utils.fst @@ -0,0 +1,37 @@ +module Libcrux_ml_dsa.Utils +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +let into_padded_array (v_LEN: usize) (slice: t_Slice u8) = + let _:Prims.unit = + if true + then + let _:Prims.unit = + Hax_lib.v_assert ((Core.Slice.impl__len #u8 slice <: usize) <=. v_LEN <: bool) + in + () + in + let out:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in + let out:t_Array u8 v_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Core.Slice.impl__len #u8 slice <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (out.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Core.Slice.impl__len #u8 slice <: usize + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + slice + <: + t_Slice u8) + in + out diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Utils.fsti b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Utils.fsti new file mode 100644 index 000000000..112de368e --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Libcrux_ml_dsa.Utils.fsti @@ -0,0 +1,8 @@ +module Libcrux_ml_dsa.Utils +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +open Core +open FStar.Mul + +/// Pad the `slice` with `0`s at the end. +val into_padded_array (v_LEN: usize) (slice: t_Slice u8) + : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/Makefile b/libcrux-ml-dsa/proofs/fstar/extraction/Makefile new file mode 100644 index 000000000..f88297130 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/Makefile @@ -0,0 +1,7 @@ +SLOW_MODULES += +ADMIT_MODULES = +FSTAR_INCLUDE_DIRS_EXTRA += $(shell git rev-parse --show-toplevel)/fstar-helpers/fstar-bitvec \ + $(shell git rev-parse --show-toplevel)/libcrux-ml-kem/proofs/fstar/spec \ + $(shell git rev-parse --show-toplevel)/libcrux-intrinsics/proofs/fstar/extraction + +include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.base diff --git a/libcrux-ml-dsa/proofs/fstar/extraction/dep.graph b/libcrux-ml-dsa/proofs/fstar/extraction/dep.graph new file mode 100644 index 000000000..ddce2bce1 --- /dev/null +++ b/libcrux-ml-dsa/proofs/fstar/extraction/dep.graph @@ -0,0 +1,4883 @@ +digraph { + "fstar_reflection_const" -> "fstar_pervasives" + "fstar_reflection_const" -> "fstar_pervasives" + "fstar_reflection_const" -> "prims" + "fstar_reflection_const" -> "prims" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "core_result" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "core" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "prims" + "libcrux_ml_dsa_ntt" -> "fstar_int32" + "libcrux_ml_dsa_ntt" -> "fstar_int32" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_ntt" -> "core_slice" + "libcrux_ml_dsa_ntt" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_ntt" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_ntt" -> "fstar_pervasives_native" + "libcrux_ml_dsa_ntt" -> "fstar_pervasives_native" + "libcrux_ml_dsa_ntt" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_ntt" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_ntt" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ntt" -> "fstar_mul" + "libcrux_ml_dsa_ntt" -> "fstar_mul" + "libcrux_ml_dsa_ntt" -> "core" + "libcrux_ml_dsa_ntt" -> "core" + "libcrux_ml_dsa_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_ntt" -> "prims" + "libcrux_ml_dsa_ntt" -> "prims" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_ntt" + "libcrux_sha3_portable" -> "libcrux_sha3_generic_keccak" + "libcrux_sha3_portable" -> "libcrux_sha3_generic_keccak" + "libcrux_sha3_portable" -> "fstar_mul" + "libcrux_sha3_portable" -> "fstar_mul" + "libcrux_sha3_portable" -> "core" + "libcrux_sha3_portable" -> "core" + "libcrux_sha3_portable" -> "fstar_pervasives" + "libcrux_sha3_portable" -> "fstar_pervasives" + "libcrux_sha3_portable" -> "prims" + "libcrux_sha3_portable" -> "prims" + "libcrux_ml_dsa_ml_dsa_44_" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_44_" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44_" -> "libcrux_ml_dsa_ml_dsa_generic_multiplexing" + "libcrux_ml_dsa_ml_dsa_44_" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44_" -> "core" + "libcrux_ml_dsa_ml_dsa_44_" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44_" -> "prims" + "libcrux_ml_dsa_ml_dsa_44_" -> "libcrux_ml_dsa_ml_dsa_44_" + "fstar_functionalextensionality" -> "fstar_pervasives" + "fstar_functionalextensionality" -> "fstar_pervasives" + "fstar_functionalextensionality" -> "prims" + "fstar_functionalextensionality" -> "prims" + "core_ops_range" -> "rust_primitives_hax" + "core_ops_range" -> "rust_primitives_hax" + "core_ops_range" -> "fstar_seq" + "core_ops_range" -> "fstar_seq" + "core_ops_range" -> "core_ops_index" + "core_ops_range" -> "core_ops_index" + "core_ops_range" -> "fstar_tactics_typeclasses" + "core_ops_range" -> "fstar_tactics_typeclasses" + "core_ops_range" -> "fstar_pervasives_native" + "core_ops_range" -> "fstar_pervasives_native" + "core_ops_range" -> "core_iter_traits_iterator" + "core_ops_range" -> "core_iter_traits_iterator" + "core_ops_range" -> "rust_primitives" + "core_ops_range" -> "rust_primitives" + "core_ops_range" -> "fstar_pervasives" + "core_ops_range" -> "fstar_pervasives" + "core_ops_range" -> "prims" + "core_ops_range" -> "prims" + "fstar_bitvector" -> "fstar_seq" + "fstar_bitvector" -> "fstar_seq" + "fstar_bitvector" -> "fstar_mul" + "fstar_bitvector" -> "fstar_mul" + "fstar_bitvector" -> "fstar_pervasives" + "fstar_bitvector" -> "fstar_pervasives" + "fstar_bitvector" -> "prims" + "fstar_bitvector" -> "prims" + "fstar_bitvector" -> "fstar_bitvector" + "fstar_sealed_inhabited" -> "fstar_sealed" + "fstar_sealed_inhabited" -> "fstar_pervasives" + "fstar_sealed_inhabited" -> "fstar_pervasives" + "fstar_sealed_inhabited" -> "prims" + "fstar_sealed_inhabited" -> "prims" + "core_fmt" -> "core_fmt_rt" + "core_fmt" -> "fstar_tactics_typeclasses" + "core_fmt" -> "fstar_tactics_typeclasses" + "core_fmt" -> "core_result" + "core_fmt" -> "core_result" + "core_fmt" -> "rust_primitives" + "core_fmt" -> "rust_primitives" + "core_fmt" -> "fstar_pervasives" + "core_fmt" -> "fstar_pervasives" + "core_fmt" -> "prims" + "core_fmt" -> "prims" + "libcrux_sha3_generic_keccak" -> "libcrux_sha3_traits" + "libcrux_sha3_generic_keccak" -> "libcrux_sha3_traits" + "libcrux_sha3_generic_keccak" -> "fstar_mul" + "libcrux_sha3_generic_keccak" -> "fstar_mul" + "libcrux_sha3_generic_keccak" -> "core" + "libcrux_sha3_generic_keccak" -> "core" + "libcrux_sha3_generic_keccak" -> "fstar_pervasives" + "libcrux_sha3_generic_keccak" -> "fstar_pervasives" + "libcrux_sha3_generic_keccak" -> "prims" + "libcrux_sha3_generic_keccak" -> "prims" + "libcrux_sha3_generic_keccak" -> "libcrux_sha3_generic_keccak" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "prims" + "fstar_reflection_v1_derived" -> "fstar_list_tot_base" + "fstar_reflection_v1_derived" -> "fstar_list_tot_base" + "fstar_reflection_v1_derived" -> "fstar_pervasives_native" + "fstar_reflection_v1_derived" -> "fstar_pervasives_native" + "fstar_reflection_v1_derived" -> "fstar_vconfig" + "fstar_reflection_v1_derived" -> "fstar_order" + "fstar_reflection_v1_derived" -> "fstar_order" + "fstar_reflection_v1_derived" -> "fstar_stubs_reflection_v1_data" + "fstar_reflection_v1_derived" -> "fstar_stubs_reflection_v1_builtins" + "fstar_reflection_v1_derived" -> "fstar_reflection_const" + "fstar_reflection_v1_derived" -> "fstar_reflection_const" + "fstar_reflection_v1_derived" -> "fstar_stubs_reflection_types" + "fstar_reflection_v1_derived" -> "fstar_pervasives" + "fstar_reflection_v1_derived" -> "fstar_pervasives" + "fstar_reflection_v1_derived" -> "prims" + "fstar_reflection_v1_derived" -> "prims" + "fstar_tactics_v1_logic" -> "fstar_pervasives_native" + "fstar_tactics_v1_logic" -> "fstar_pervasives_native" + "fstar_tactics_v1_logic" -> "fstar_stubs_tactics_v1_builtins" + "fstar_tactics_v1_logic" -> "fstar_stubs_tactics_types" + "fstar_tactics_v1_logic" -> "fstar_tactics_v1_logic_lemmas" + "fstar_tactics_v1_logic" -> "fstar_tactics_v1_logic_lemmas" + "fstar_tactics_v1_logic" -> "fstar_reflection_v1_formula" + "fstar_tactics_v1_logic" -> "fstar_reflection_v1_formula" + "fstar_tactics_v1_logic" -> "fstar_reflection_v1" + "fstar_tactics_v1_logic" -> "fstar_reflection_v1" + "fstar_tactics_v1_logic" -> "fstar_tactics_effect" + "fstar_tactics_v1_logic" -> "fstar_tactics_effect" + "fstar_tactics_v1_logic" -> "fstar_pervasives" + "fstar_tactics_v1_logic" -> "fstar_pervasives" + "fstar_tactics_v1_logic" -> "prims" + "fstar_tactics_v1_logic" -> "prims" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "core" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "core" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "prims" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "prims" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "libcrux_ml_dsa_simd_avx2_vector_type" + "fstar_uint8" -> "fstar_uint32" + "fstar_uint8" -> "fstar_uint32" + "fstar_uint8" -> "fstar_mul" + "fstar_uint8" -> "fstar_mul" + "fstar_uint8" -> "fstar_uint" + "fstar_uint8" -> "fstar_uint" + "fstar_uint8" -> "fstar_pervasives" + "fstar_uint8" -> "fstar_pervasives" + "fstar_uint8" -> "prims" + "fstar_uint8" -> "prims" + "fstar_tactics_bv" -> "fstar_pervasives_native" + "fstar_tactics_bv" -> "fstar_pervasives_native" + "fstar_tactics_bv" -> "fstar_tactics_bv_lemmas" + "fstar_tactics_bv" -> "fstar_tactics_bv_lemmas" + "fstar_tactics_bv" -> "fstar_uint" + "fstar_tactics_bv" -> "fstar_uint" + "fstar_tactics_bv" -> "fstar_bv" + "fstar_tactics_bv" -> "fstar_bv" + "fstar_tactics_bv" -> "fstar_reflection_v2_arith" + "fstar_tactics_bv" -> "fstar_reflection_v2_arith" + "fstar_tactics_bv" -> "fstar_reflection_v2_formula" + "fstar_tactics_bv" -> "fstar_reflection_v2_formula" + "fstar_tactics_bv" -> "fstar_tactics_v2" + "fstar_tactics_bv" -> "fstar_tactics_v2" + "fstar_tactics_bv" -> "fstar_pervasives" + "fstar_tactics_bv" -> "fstar_pervasives" + "fstar_tactics_bv" -> "prims" + "fstar_tactics_bv" -> "prims" + "fstar_tactics_bv" -> "fstar_tactics_bv" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_int64" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_int64" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core_ops_range" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core_slice" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "libcrux_ml_dsa_simd_avx2_encoding_t0" + "rust_primitives_arrays" -> "fstar_pervasives_native" + "rust_primitives_arrays" -> "fstar_pervasives_native" + "rust_primitives_arrays" -> "lib_inttypes" + "rust_primitives_arrays" -> "lib_inttypes" + "rust_primitives_arrays" -> "fstar_list_tot" + "rust_primitives_arrays" -> "fstar_list_tot" + "rust_primitives_arrays" -> "fstar_seq" + "rust_primitives_arrays" -> "fstar_seq" + "rust_primitives_arrays" -> "fstar_mul" + "rust_primitives_arrays" -> "fstar_mul" + "rust_primitives_arrays" -> "rust_primitives_integers" + "rust_primitives_arrays" -> "rust_primitives_integers" + "rust_primitives_arrays" -> "fstar_pervasives" + "rust_primitives_arrays" -> "fstar_pervasives" + "rust_primitives_arrays" -> "prims" + "rust_primitives_arrays" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "core_num" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "core_ops_range" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_ml_dsa_simd_avx2_encoding_error" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_ml_dsa_simd_avx2_encoding_error" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "core_result" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "prims" + "fstar_seq" -> "fstar_seq_properties" + "fstar_seq" -> "fstar_seq_properties" + "fstar_seq" -> "fstar_seq_base" + "fstar_seq" -> "fstar_seq_base" + "fstar_seq" -> "fstar_pervasives" + "fstar_seq" -> "fstar_pervasives" + "fstar_seq" -> "prims" + "fstar_seq" -> "prims" + "rust_primitives_arrays" -> "fstar_seq" + "rust_primitives_arrays" -> "fstar_seq" + "rust_primitives_arrays" -> "lib_inttypes" + "rust_primitives_arrays" -> "lib_inttypes" + "rust_primitives_arrays" -> "fstar_list_tot" + "rust_primitives_arrays" -> "fstar_list_tot" + "rust_primitives_arrays" -> "rust_primitives_integers" + "rust_primitives_arrays" -> "rust_primitives_integers" + "rust_primitives_arrays" -> "fstar_pervasives" + "rust_primitives_arrays" -> "fstar_pervasives" + "rust_primitives_arrays" -> "prims" + "rust_primitives_arrays" -> "prims" + "rust_primitives_arrays" -> "rust_primitives_arrays" + "fstar_int64" -> "fstar_uint" + "fstar_int64" -> "fstar_uint" + "fstar_int64" -> "fstar_uint32" + "fstar_int64" -> "fstar_uint32" + "fstar_int64" -> "fstar_mul" + "fstar_int64" -> "fstar_mul" + "fstar_int64" -> "fstar_int" + "fstar_int64" -> "fstar_int" + "fstar_int64" -> "fstar_pervasives" + "fstar_int64" -> "fstar_pervasives" + "fstar_int64" -> "prims" + "fstar_int64" -> "prims" + "core_iter_traits_iterator" -> "fstar_tactics_typeclasses" + "core_iter_traits_iterator" -> "fstar_tactics_typeclasses" + "core_iter_traits_iterator" -> "core_iter_adapters_step_by" + "core_iter_traits_iterator" -> "core_iter_adapters_step_by" + "core_iter_traits_iterator" -> "core_iter_adapters_enumerate" + "core_iter_traits_iterator" -> "core_iter_adapters_enumerate" + "core_iter_traits_iterator" -> "rust_primitives" + "core_iter_traits_iterator" -> "rust_primitives" + "core_iter_traits_iterator" -> "fstar_pervasives" + "core_iter_traits_iterator" -> "fstar_pervasives" + "core_iter_traits_iterator" -> "prims" + "core_iter_traits_iterator" -> "prims" + "core_slice_iter" -> "rust_primitives" + "core_slice_iter" -> "rust_primitives" + "core_slice_iter" -> "fstar_pervasives" + "core_slice_iter" -> "fstar_pervasives" + "core_slice_iter" -> "prims" + "core_slice_iter" -> "prims" + "core_option" -> "fstar_pervasives" + "core_option" -> "fstar_pervasives" + "core_option" -> "prims" + "core_option" -> "prims" + "fstar_tactics_bv_lemmas" -> "fstar_uint" + "fstar_tactics_bv_lemmas" -> "fstar_uint" + "fstar_tactics_bv_lemmas" -> "fstar_bv" + "fstar_tactics_bv_lemmas" -> "fstar_bv" + "fstar_tactics_bv_lemmas" -> "fstar_pervasives" + "fstar_tactics_bv_lemmas" -> "fstar_pervasives" + "fstar_tactics_bv_lemmas" -> "prims" + "fstar_tactics_bv_lemmas" -> "prims" + "libcrux_sha3_generic_keccak" -> "fstar_tactics_typeclasses" + "libcrux_sha3_generic_keccak" -> "fstar_tactics_typeclasses" + "libcrux_sha3_generic_keccak" -> "libcrux_sha3_traits" + "libcrux_sha3_generic_keccak" -> "libcrux_sha3_traits" + "libcrux_sha3_generic_keccak" -> "fstar_mul" + "libcrux_sha3_generic_keccak" -> "fstar_mul" + "libcrux_sha3_generic_keccak" -> "core" + "libcrux_sha3_generic_keccak" -> "core" + "libcrux_sha3_generic_keccak" -> "fstar_pervasives" + "libcrux_sha3_generic_keccak" -> "fstar_pervasives" + "libcrux_sha3_generic_keccak" -> "prims" + "libcrux_sha3_generic_keccak" -> "prims" + "fstar_uint" -> "fstar_seq_base" + "fstar_uint" -> "fstar_seq_base" + "fstar_uint" -> "fstar_math_lemmas" + "fstar_uint" -> "fstar_math_lemmas" + "fstar_uint" -> "fstar_bitvector" + "fstar_uint" -> "fstar_bitvector" + "fstar_uint" -> "fstar_mul" + "fstar_uint" -> "fstar_mul" + "fstar_uint" -> "fstar_pervasives" + "fstar_uint" -> "fstar_pervasives" + "fstar_uint" -> "prims" + "fstar_uint" -> "prims" + "fstar_math_lib" -> "fstar_mul" + "fstar_math_lib" -> "fstar_mul" + "fstar_math_lib" -> "fstar_pervasives" + "fstar_math_lib" -> "fstar_pervasives" + "fstar_math_lib" -> "prims" + "fstar_math_lib" -> "prims" + "fstar_reflection_v2_arith" -> "fstar_classical" + "fstar_reflection_v2_arith" -> "fstar_classical" + "fstar_reflection_v2_arith" -> "fstar_list_tot" + "fstar_reflection_v2_arith" -> "fstar_list_tot" + "fstar_reflection_v2_arith" -> "fstar_pervasives_native" + "fstar_reflection_v2_arith" -> "fstar_pervasives_native" + "fstar_reflection_v2_arith" -> "fstar_list_tot_base" + "fstar_reflection_v2_arith" -> "fstar_list_tot_base" + "fstar_reflection_v2_arith" -> "fstar_order" + "fstar_reflection_v2_arith" -> "fstar_order" + "fstar_reflection_v2_arith" -> "fstar_reflection_v2" + "fstar_reflection_v2_arith" -> "fstar_reflection_v2" + "fstar_reflection_v2_arith" -> "fstar_tactics_v2" + "fstar_reflection_v2_arith" -> "fstar_tactics_v2" + "fstar_reflection_v2_arith" -> "fstar_pervasives" + "fstar_reflection_v2_arith" -> "fstar_pervasives" + "fstar_reflection_v2_arith" -> "prims" + "fstar_reflection_v2_arith" -> "prims" + "lib_sequence" -> "fstar_pervasives_native" + "lib_sequence" -> "fstar_pervasives_native" + "lib_sequence" -> "fstar_math_lemmas" + "lib_sequence" -> "fstar_math_lemmas" + "lib_sequence" -> "lib_loopcombinators" + "lib_sequence" -> "lib_loopcombinators" + "lib_sequence" -> "fstar_list_tot" + "lib_sequence" -> "fstar_list_tot" + "lib_sequence" -> "fstar_seq" + "lib_sequence" -> "fstar_seq" + "lib_sequence" -> "lib_inttypes" + "lib_sequence" -> "lib_inttypes" + "lib_sequence" -> "fstar_mul" + "lib_sequence" -> "fstar_mul" + "lib_sequence" -> "fstar_pervasives" + "lib_sequence" -> "fstar_pervasives" + "lib_sequence" -> "prims" + "lib_sequence" -> "prims" + "libcrux_intrinsics_avx2_extract" -> "fstar_mul" + "libcrux_intrinsics_avx2_extract" -> "fstar_mul" + "libcrux_intrinsics_avx2_extract" -> "core" + "libcrux_intrinsics_avx2_extract" -> "core" + "libcrux_intrinsics_avx2_extract" -> "fstar_pervasives" + "libcrux_intrinsics_avx2_extract" -> "fstar_pervasives" + "libcrux_intrinsics_avx2_extract" -> "prims" + "libcrux_intrinsics_avx2_extract" -> "prims" + "libcrux_intrinsics_avx2_extract" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_ml_dsa_65_" -> "core_result" + "libcrux_ml_dsa_ml_dsa_65_" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_65_" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_65_" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_ml_dsa_65_" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_65_" -> "core" + "libcrux_ml_dsa_ml_dsa_65_" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_65_" -> "prims" + "libcrux_ml_dsa_ml_dsa_87_" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_87_" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_87_" -> "libcrux_ml_dsa_ml_dsa_generic_multiplexing" + "libcrux_ml_dsa_ml_dsa_87_" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_87_" -> "core" + "libcrux_ml_dsa_ml_dsa_87_" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_87_" -> "prims" + "libcrux_ml_dsa_ml_dsa_87_" -> "libcrux_ml_dsa_ml_dsa_87_" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_encoding_gamma1" -> "core" + "libcrux_ml_dsa_encoding_gamma1" -> "core" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_gamma1" -> "prims" + "libcrux_ml_dsa_encoding_gamma1" -> "prims" + "libcrux_platform_platform" -> "fstar_mul" + "libcrux_platform_platform" -> "core" + "libcrux_platform_platform" -> "fstar_pervasives" + "libcrux_platform_platform" -> "prims" + "fstar_pervasives" -> "prims" + "fstar_pervasives" -> "prims" + "fstar_pervasives" -> "fstar_pervasives" + "rust_primitives_hax" -> "fstar_list_tot" + "rust_primitives_hax" -> "fstar_list_tot" + "rust_primitives_hax" -> "lib_inttypes" + "rust_primitives_hax" -> "lib_inttypes" + "rust_primitives_hax" -> "core_slice" + "rust_primitives_hax" -> "fstar_tactics_typeclasses" + "rust_primitives_hax" -> "fstar_tactics_typeclasses" + "rust_primitives_hax" -> "core_ops_index" + "rust_primitives_hax" -> "core_ops_index" + "rust_primitives_hax" -> "fstar_seq" + "rust_primitives_hax" -> "fstar_seq" + "rust_primitives_hax" -> "rust_primitives_arrays" + "rust_primitives_hax" -> "rust_primitives_arrays" + "rust_primitives_hax" -> "rust_primitives_integers" + "rust_primitives_hax" -> "rust_primitives_integers" + "rust_primitives_hax" -> "fstar_pervasives" + "rust_primitives_hax" -> "fstar_pervasives" + "rust_primitives_hax" -> "prims" + "rust_primitives_hax" -> "prims" + "libcrux_ml_dsa_hash_functions_shake256" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_shake256" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_shake256" -> "core" + "libcrux_ml_dsa_hash_functions_shake256" -> "core" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_shake256" -> "prims" + "libcrux_ml_dsa_hash_functions_shake256" -> "prims" + "fstar_set" -> "fstar_pervasives" + "fstar_set" -> "fstar_pervasives" + "fstar_set" -> "prims" + "fstar_set" -> "prims" + "fstar_squash" -> "fstar_pervasives" + "fstar_squash" -> "fstar_pervasives" + "fstar_squash" -> "prims" + "fstar_squash" -> "prims" + "libcrux_ml_dsa_simd_traits" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_traits" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_traits" -> "fstar_list_tot" + "libcrux_ml_dsa_simd_traits" -> "fstar_list_tot" + "libcrux_ml_dsa_simd_traits" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_traits" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_traits" -> "fstar_uint64" + "libcrux_ml_dsa_simd_traits" -> "fstar_uint64" + "libcrux_ml_dsa_simd_traits" -> "fstar_int32" + "libcrux_ml_dsa_simd_traits" -> "fstar_int32" + "libcrux_ml_dsa_simd_traits" -> "core_clone" + "libcrux_ml_dsa_simd_traits" -> "core_clone" + "libcrux_ml_dsa_simd_traits" -> "core_marker" + "libcrux_ml_dsa_simd_traits" -> "core_marker" + "libcrux_ml_dsa_simd_traits" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_traits" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_traits" -> "fstar_mul" + "libcrux_ml_dsa_simd_traits" -> "fstar_mul" + "libcrux_ml_dsa_simd_traits" -> "core" + "libcrux_ml_dsa_simd_traits" -> "core" + "libcrux_ml_dsa_simd_traits" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_traits" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_traits" -> "prims" + "libcrux_ml_dsa_simd_traits" -> "prims" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "core" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "prims" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "libcrux_ml_dsa_ml_dsa_65__neon" + "libcrux_ml_dsa_encoding_t0" -> "core_ops_range" + "libcrux_ml_dsa_encoding_t0" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_t0" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_ntt" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_ntt" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_encoding_t0" -> "core_iter_adapters_enumerate" + "libcrux_ml_dsa_encoding_t0" -> "core_iter_adapters_enumerate" + "libcrux_ml_dsa_encoding_t0" -> "core_iter_traits_collect" + "libcrux_ml_dsa_encoding_t0" -> "core_iter_traits_collect" + "libcrux_ml_dsa_encoding_t0" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_t0" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_t0" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_t0" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_t0" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_t0" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_t0" -> "core_option" + "libcrux_ml_dsa_encoding_t0" -> "core_option" + "libcrux_ml_dsa_encoding_t0" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_t0" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_t0" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_t0" -> "core_slice" + "libcrux_ml_dsa_encoding_t0" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_t0" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_t0" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_t0" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_encoding_t0" -> "core" + "libcrux_ml_dsa_encoding_t0" -> "core" + "libcrux_ml_dsa_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_t0" -> "prims" + "libcrux_ml_dsa_encoding_t0" -> "prims" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_encoding_t0" + "fstar_heap" -> "fstar_preorder" + "fstar_heap" -> "fstar_preorder" + "fstar_heap" -> "fstar_monotonic_heap" + "fstar_heap" -> "fstar_monotonic_heap" + "fstar_heap" -> "fstar_pervasives" + "fstar_heap" -> "fstar_pervasives" + "fstar_heap" -> "prims" + "fstar_heap" -> "prims" + "fstar_reflection_v1_compare" -> "fstar_reflection_v2_compare" + "fstar_reflection_v1_compare" -> "fstar_reflection_v2_compare" + "fstar_reflection_v1_compare" -> "fstar_pervasives" + "fstar_reflection_v1_compare" -> "fstar_pervasives" + "fstar_reflection_v1_compare" -> "prims" + "fstar_reflection_v1_compare" -> "prims" + "fstar_issue" -> "fstar_stubs_pprint" + "fstar_issue" -> "fstar_range" + "fstar_issue" -> "fstar_pervasives" + "fstar_issue" -> "fstar_pervasives" + "fstar_issue" -> "prims" + "fstar_issue" -> "prims" + "fstar_monotonic_witnessed" -> "fstar_preorder" + "fstar_monotonic_witnessed" -> "fstar_preorder" + "fstar_monotonic_witnessed" -> "fstar_pervasives" + "fstar_monotonic_witnessed" -> "fstar_pervasives" + "fstar_monotonic_witnessed" -> "prims" + "fstar_monotonic_witnessed" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "libcrux_platform_platform" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "libcrux_ml_dsa_ml_dsa_generic_multiplexing" + "fstar_ghost" -> "fstar_pervasives" + "fstar_ghost" -> "fstar_pervasives" + "fstar_ghost" -> "prims" + "fstar_ghost" -> "prims" + "fstar_ghost" -> "fstar_ghost" + "fstar_reflection_v1_derived_lemmas" -> "fstar_classical" + "fstar_reflection_v1_derived_lemmas" -> "fstar_classical" + "fstar_reflection_v1_derived_lemmas" -> "fstar_pervasives_native" + "fstar_reflection_v1_derived_lemmas" -> "fstar_pervasives_native" + "fstar_reflection_v1_derived_lemmas" -> "fstar_list_tot" + "fstar_reflection_v1_derived_lemmas" -> "fstar_list_tot" + "fstar_reflection_v1_derived_lemmas" -> "fstar_reflection_v1_derived" + "fstar_reflection_v1_derived_lemmas" -> "fstar_reflection_v1_derived" + "fstar_reflection_v1_derived_lemmas" -> "fstar_stubs_reflection_v1_data" + "fstar_reflection_v1_derived_lemmas" -> "fstar_stubs_reflection_v1_builtins" + "fstar_reflection_v1_derived_lemmas" -> "fstar_stubs_reflection_types" + "fstar_reflection_v1_derived_lemmas" -> "fstar_pervasives" + "fstar_reflection_v1_derived_lemmas" -> "fstar_pervasives" + "fstar_reflection_v1_derived_lemmas" -> "prims" + "fstar_reflection_v1_derived_lemmas" -> "prims" + "fstar_stubs_errors_msg" -> "fstar_stubs_pprint" + "fstar_stubs_errors_msg" -> "fstar_pervasives" + "fstar_stubs_errors_msg" -> "fstar_pervasives" + "fstar_stubs_errors_msg" -> "prims" + "fstar_stubs_errors_msg" -> "prims" + "fstar_string" -> "fstar_all" + "fstar_string" -> "fstar_all" + "fstar_string" -> "fstar_list" + "fstar_string" -> "fstar_list" + "fstar_string" -> "fstar_char" + "fstar_string" -> "fstar_list_tot" + "fstar_string" -> "fstar_list_tot" + "fstar_string" -> "fstar_pervasives" + "fstar_string" -> "fstar_pervasives" + "fstar_string" -> "prims" + "fstar_string" -> "prims" + "spec_sha3" -> "fstar_pervasives_native" + "spec_sha3" -> "fstar_pervasives_native" + "spec_sha3" -> "spec_sha3_constants" + "spec_sha3" -> "spec_sha3_constants" + "spec_sha3" -> "lib_loopcombinators" + "spec_sha3" -> "lib_loopcombinators" + "spec_sha3" -> "fstar_mul" + "spec_sha3" -> "fstar_mul" + "spec_sha3" -> "lib_bytesequence" + "spec_sha3" -> "lib_bytesequence" + "spec_sha3" -> "lib_sequence" + "spec_sha3" -> "lib_sequence" + "spec_sha3" -> "lib_inttypes" + "spec_sha3" -> "lib_inttypes" + "spec_sha3" -> "fstar_pervasives" + "spec_sha3" -> "fstar_pervasives" + "spec_sha3" -> "prims" + "spec_sha3" -> "prims" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_sha3_avx2_x4" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_sha3_portable_incremental" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_uint8" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_uint8" + "libcrux_ml_dsa_hash_functions_simd256" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_simd256" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_pervasives_native" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_pervasives_native" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_sha3_portable" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_sha3_portable" + "libcrux_ml_dsa_hash_functions_simd256" -> "libcrux_sha3_avx2_x4_incremental" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_simd256" -> "core" + "libcrux_ml_dsa_hash_functions_simd256" -> "core" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_simd256" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_simd256" -> "prims" + "libcrux_ml_dsa_hash_functions_simd256" -> "prims" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_simd_portable_encoding_commitment" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_simd_portable_sample" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_int32" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_uint8" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "prims" + "fstar_calc" -> "fstar_classical" + "fstar_calc" -> "fstar_classical" + "fstar_calc" -> "fstar_preorder" + "fstar_calc" -> "fstar_preorder" + "fstar_calc" -> "fstar_squash" + "fstar_calc" -> "fstar_squash" + "fstar_calc" -> "fstar_pervasives" + "fstar_calc" -> "fstar_pervasives" + "fstar_calc" -> "prims" + "fstar_calc" -> "prims" + "fstar_calc" -> "fstar_calc" + "spec_utils" -> "rust_primitives_integers" + "spec_utils" -> "rust_primitives_integers" + "spec_utils" -> "fstar_calc" + "spec_utils" -> "fstar_calc" + "spec_utils" -> "fstar_int32" + "spec_utils" -> "fstar_int32" + "spec_utils" -> "fstar_int16" + "spec_utils" -> "fstar_int16" + "spec_utils" -> "fstar_math_lemmas" + "spec_utils" -> "fstar_math_lemmas" + "spec_utils" -> "fstar_classical_sugar" + "spec_utils" -> "fstar_classical_sugar" + "spec_utils" -> "rust_primitives_hax_monomorphized_update_at" + "spec_utils" -> "rust_primitives_hax_monomorphized_update_at" + "spec_utils" -> "core_ops_range" + "spec_utils" -> "lib_inttypes" + "spec_utils" -> "lib_inttypes" + "spec_utils" -> "lib_rawinttypes" + "spec_utils" -> "lib_rawinttypes" + "spec_utils" -> "spec_sha3" + "spec_utils" -> "spec_sha3" + "spec_utils" -> "fstar_list_tot" + "spec_utils" -> "fstar_list_tot" + "spec_utils" -> "rust_primitives_hax" + "spec_utils" -> "rust_primitives_hax" + "spec_utils" -> "lib_loopcombinators" + "spec_utils" -> "lib_loopcombinators" + "spec_utils" -> "fstar_seq" + "spec_utils" -> "fstar_seq" + "spec_utils" -> "core" + "spec_utils" -> "core" + "spec_utils" -> "fstar_mul" + "spec_utils" -> "fstar_mul" + "spec_utils" -> "fstar_pervasives" + "spec_utils" -> "fstar_pervasives" + "spec_utils" -> "prims" + "spec_utils" -> "prims" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "core_num" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "core_ops_arith_neg" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "core" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "core" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "prims" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "prims" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_ml_dsa_simd_avx2_arithmetic" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_simd_avx2" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_simd256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "prims" + "fstar_stubs_reflection_types" -> "fstar_sealed" + "fstar_stubs_reflection_types" -> "fstar_range" + "fstar_stubs_reflection_types" -> "fstar_pervasives" + "fstar_stubs_reflection_types" -> "fstar_pervasives" + "fstar_stubs_reflection_types" -> "prims" + "fstar_stubs_reflection_types" -> "prims" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_namedview" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_namedview" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_effect" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_effect" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_reflection_v2" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_reflection_v2" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_pervasives" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_pervasives" + "fstar_tactics_v2_syntaxhelpers" -> "prims" + "fstar_tactics_v2_syntaxhelpers" -> "prims" + "lib_inttypes" -> "fstar_uint" + "lib_inttypes" -> "fstar_uint" + "lib_inttypes" -> "fstar_int" + "lib_inttypes" -> "fstar_int" + "lib_inttypes" -> "fstar_int128" + "lib_inttypes" -> "fstar_int128" + "lib_inttypes" -> "fstar_int64" + "lib_inttypes" -> "fstar_int64" + "lib_inttypes" -> "fstar_int32" + "lib_inttypes" -> "fstar_int32" + "lib_inttypes" -> "fstar_int16" + "lib_inttypes" -> "fstar_int16" + "lib_inttypes" -> "fstar_int8" + "lib_inttypes" -> "fstar_int8" + "lib_inttypes" -> "fstar_uint128" + "lib_inttypes" -> "fstar_uint128" + "lib_inttypes" -> "fstar_uint64" + "lib_inttypes" -> "fstar_uint64" + "lib_inttypes" -> "fstar_uint32" + "lib_inttypes" -> "fstar_uint32" + "lib_inttypes" -> "fstar_uint16" + "lib_inttypes" -> "fstar_uint16" + "lib_inttypes" -> "fstar_uint8" + "lib_inttypes" -> "fstar_uint8" + "lib_inttypes" -> "fstar_mul" + "lib_inttypes" -> "fstar_mul" + "lib_inttypes" -> "fstar_pervasives" + "lib_inttypes" -> "fstar_pervasives" + "lib_inttypes" -> "prims" + "lib_inttypes" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_t0" -> "prims" + "core_iter_traits_collect" -> "core_iter_traits_iterator" + "core_iter_traits_collect" -> "core_iter_traits_iterator" + "core_iter_traits_collect" -> "fstar_tactics_typeclasses" + "core_iter_traits_collect" -> "fstar_tactics_typeclasses" + "core_iter_traits_collect" -> "fstar_pervasives" + "core_iter_traits_collect" -> "fstar_pervasives" + "core_iter_traits_collect" -> "prims" + "core_iter_traits_collect" -> "prims" + "libcrux_ml_dsa_encoding_signature" -> "core_convert" + "libcrux_ml_dsa_encoding_signature" -> "core_convert" + "libcrux_ml_dsa_encoding_signature" -> "core_array" + "libcrux_ml_dsa_encoding_signature" -> "core_array" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_encoding_signature" -> "core_result" + "libcrux_ml_dsa_encoding_signature" -> "core_result" + "libcrux_ml_dsa_encoding_signature" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_signature" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_signature" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_signature" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_signature" -> "rust_primitives" + "libcrux_ml_dsa_encoding_signature" -> "rust_primitives" + "libcrux_ml_dsa_encoding_signature" -> "fstar_int32" + "libcrux_ml_dsa_encoding_signature" -> "fstar_int32" + "libcrux_ml_dsa_encoding_signature" -> "core_ops_range" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_encoding_gamma1" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_encoding_gamma1" + "libcrux_ml_dsa_encoding_signature" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_signature" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_signature" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_encoding_signature" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_signature" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_signature" -> "core_slice" + "libcrux_ml_dsa_encoding_signature" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_signature" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_signature" -> "fstar_mul" + "libcrux_ml_dsa_encoding_signature" -> "fstar_mul" + "libcrux_ml_dsa_encoding_signature" -> "core" + "libcrux_ml_dsa_encoding_signature" -> "core" + "libcrux_ml_dsa_encoding_signature" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_signature" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_signature" -> "prims" + "libcrux_ml_dsa_encoding_signature" -> "prims" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_encoding_signature" + "hax_lib" -> "fstar_tactics" + "hax_lib" -> "fstar_tactics" + "hax_lib" -> "fstar_pervasives" + "hax_lib" -> "fstar_pervasives" + "hax_lib" -> "prims" + "hax_lib" -> "prims" + "libcrux_ml_dsa_utils" -> "core_ops_range" + "libcrux_ml_dsa_utils" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_utils" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_utils" -> "fstar_uint8" + "libcrux_ml_dsa_utils" -> "fstar_uint8" + "libcrux_ml_dsa_utils" -> "rust_primitives_hax" + "libcrux_ml_dsa_utils" -> "rust_primitives_hax" + "libcrux_ml_dsa_utils" -> "core_slice" + "libcrux_ml_dsa_utils" -> "hax_lib" + "libcrux_ml_dsa_utils" -> "hax_lib" + "libcrux_ml_dsa_utils" -> "fstar_mul" + "libcrux_ml_dsa_utils" -> "fstar_mul" + "libcrux_ml_dsa_utils" -> "core" + "libcrux_ml_dsa_utils" -> "core" + "libcrux_ml_dsa_utils" -> "fstar_pervasives" + "libcrux_ml_dsa_utils" -> "fstar_pervasives" + "libcrux_ml_dsa_utils" -> "prims" + "libcrux_ml_dsa_utils" -> "prims" + "libcrux_ml_dsa_utils" -> "libcrux_ml_dsa_utils" + "fstar_math_lemmas" -> "fstar_calc" + "fstar_math_lemmas" -> "fstar_calc" + "fstar_math_lemmas" -> "fstar_math_lib" + "fstar_math_lemmas" -> "fstar_math_lib" + "fstar_math_lemmas" -> "fstar_mul" + "fstar_math_lemmas" -> "fstar_mul" + "fstar_math_lemmas" -> "fstar_pervasives" + "fstar_math_lemmas" -> "fstar_pervasives" + "fstar_math_lemmas" -> "prims" + "fstar_math_lemmas" -> "prims" + "fstar_math_lemmas" -> "fstar_math_lemmas" + "fstar_calc" -> "fstar_range" + "fstar_calc" -> "fstar_preorder" + "fstar_calc" -> "fstar_preorder" + "fstar_calc" -> "fstar_pervasives" + "fstar_calc" -> "fstar_pervasives" + "fstar_calc" -> "prims" + "fstar_calc" -> "prims" + "fstar_bitvector" -> "fstar_seq_base" + "fstar_bitvector" -> "fstar_seq_base" + "fstar_bitvector" -> "fstar_mul" + "fstar_bitvector" -> "fstar_mul" + "fstar_bitvector" -> "fstar_pervasives" + "fstar_bitvector" -> "fstar_pervasives" + "fstar_bitvector" -> "prims" + "fstar_bitvector" -> "prims" + "fstar_tactics_util" -> "fstar_pervasives_native" + "fstar_tactics_util" -> "fstar_pervasives_native" + "fstar_tactics_util" -> "fstar_list_tot_base" + "fstar_tactics_util" -> "fstar_list_tot_base" + "fstar_tactics_util" -> "fstar_tactics_effect" + "fstar_tactics_util" -> "fstar_tactics_effect" + "fstar_tactics_util" -> "fstar_pervasives" + "fstar_tactics_util" -> "fstar_pervasives" + "fstar_tactics_util" -> "prims" + "fstar_tactics_util" -> "prims" + "core_ops_arith" -> "fstar_tactics_typeclasses" + "core_ops_arith" -> "fstar_tactics_typeclasses" + "core_ops_arith" -> "rust_primitives" + "core_ops_arith" -> "rust_primitives" + "core_ops_arith" -> "fstar_pervasives" + "core_ops_arith" -> "fstar_pervasives" + "core_ops_arith" -> "prims" + "core_ops_arith" -> "prims" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "prims" + "fstar_order" -> "fstar_pervasives_native" + "fstar_order" -> "fstar_pervasives_native" + "fstar_order" -> "fstar_pervasives" + "fstar_order" -> "fstar_pervasives" + "fstar_order" -> "prims" + "fstar_order" -> "prims" + "fstar_tactics_smt" -> "fstar_vconfig" + "fstar_tactics_smt" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_smt" -> "fstar_tactics_effect" + "fstar_tactics_smt" -> "fstar_tactics_effect" + "fstar_tactics_smt" -> "fstar_pervasives" + "fstar_tactics_smt" -> "fstar_pervasives" + "fstar_tactics_smt" -> "prims" + "fstar_tactics_smt" -> "prims" + "fstar_tactics_smt" -> "fstar_tactics_smt" + "rust_primitives_hax_monomorphized_update_at" -> "fstar_seq" + "rust_primitives_hax_monomorphized_update_at" -> "fstar_seq" + "rust_primitives_hax_monomorphized_update_at" -> "core_ops_range" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives_hax" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives_hax" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives" + "rust_primitives_hax_monomorphized_update_at" -> "fstar_pervasives" + "rust_primitives_hax_monomorphized_update_at" -> "fstar_pervasives" + "rust_primitives_hax_monomorphized_update_at" -> "prims" + "rust_primitives_hax_monomorphized_update_at" -> "prims" + "core_core_arch_arm_shared_neon" -> "fstar_pervasives" + "core_core_arch_arm_shared_neon" -> "fstar_pervasives" + "core_core_arch_arm_shared_neon" -> "prims" + "core_core_arch_arm_shared_neon" -> "prims" + "fstar_tactics_smt" -> "fstar_tactics_effect" + "fstar_tactics_smt" -> "fstar_tactics_effect" + "fstar_tactics_smt" -> "fstar_pervasives" + "fstar_tactics_smt" -> "fstar_pervasives" + "fstar_tactics_smt" -> "prims" + "fstar_tactics_smt" -> "prims" + "fstar_stubs_reflection_v2_builtins" -> "fstar_stubs_reflection_v2_data" + "fstar_stubs_reflection_v2_builtins" -> "fstar_stubs_reflection_types" + "fstar_stubs_reflection_v2_builtins" -> "fstar_vconfig" + "fstar_stubs_reflection_v2_builtins" -> "fstar_stubs_syntax_syntax" + "fstar_stubs_reflection_v2_builtins" -> "fstar_order" + "fstar_stubs_reflection_v2_builtins" -> "fstar_order" + "fstar_stubs_reflection_v2_builtins" -> "fstar_pervasives" + "fstar_stubs_reflection_v2_builtins" -> "fstar_pervasives" + "fstar_stubs_reflection_v2_builtins" -> "prims" + "fstar_stubs_reflection_v2_builtins" -> "prims" + "fstar_tactics_names" -> "fstar_tactics_effect" + "fstar_tactics_names" -> "fstar_tactics_effect" + "fstar_tactics_names" -> "fstar_stubs_reflection_types" + "fstar_tactics_names" -> "fstar_pervasives" + "fstar_tactics_names" -> "fstar_pervasives" + "fstar_tactics_names" -> "prims" + "fstar_tactics_names" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_ops_range" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_int16" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_int16" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core_slice" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "libcrux_ml_dsa_simd_avx2_encoding_error" + "fstar_list_tot_properties" -> "fstar_strongexcludedmiddle" + "fstar_list_tot_properties" -> "fstar_strongexcludedmiddle" + "fstar_list_tot_properties" -> "fstar_pervasives_native" + "fstar_list_tot_properties" -> "fstar_pervasives_native" + "fstar_list_tot_properties" -> "fstar_list_tot_base" + "fstar_list_tot_properties" -> "fstar_list_tot_base" + "fstar_list_tot_properties" -> "fstar_pervasives" + "fstar_list_tot_properties" -> "fstar_pervasives" + "fstar_list_tot_properties" -> "prims" + "fstar_list_tot_properties" -> "prims" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_ntt" -> "core" + "libcrux_ml_dsa_simd_avx2_ntt" -> "core" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_ntt" -> "prims" + "libcrux_ml_dsa_simd_avx2_ntt" -> "prims" + "libcrux_sha3_avx2_x4" -> "fstar_mul" + "libcrux_sha3_avx2_x4" -> "fstar_mul" + "libcrux_sha3_avx2_x4" -> "core" + "libcrux_sha3_avx2_x4" -> "core" + "libcrux_sha3_avx2_x4" -> "fstar_pervasives" + "libcrux_sha3_avx2_x4" -> "fstar_pervasives" + "libcrux_sha3_avx2_x4" -> "prims" + "libcrux_sha3_avx2_x4" -> "prims" + "libcrux_ml_dsa_hash_functions_shake128" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_shake128" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_shake128" -> "core" + "libcrux_ml_dsa_hash_functions_shake128" -> "core" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_shake128" -> "prims" + "libcrux_ml_dsa_hash_functions_shake128" -> "prims" + "libcrux_sha3_portable" -> "fstar_mul" + "libcrux_sha3_portable" -> "fstar_mul" + "libcrux_sha3_portable" -> "core" + "libcrux_sha3_portable" -> "core" + "libcrux_sha3_portable" -> "fstar_pervasives" + "libcrux_sha3_portable" -> "fstar_pervasives" + "libcrux_sha3_portable" -> "prims" + "libcrux_sha3_portable" -> "prims" + "libcrux_sha3_portable" -> "libcrux_sha3_portable" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "prims" + "fstar_reflection_termeq" -> "fstar_classical_sugar" + "fstar_reflection_termeq" -> "fstar_classical_sugar" + "fstar_reflection_termeq" -> "fstar_sealed" + "fstar_reflection_termeq" -> "fstar_pervasives_native" + "fstar_reflection_termeq" -> "fstar_pervasives_native" + "fstar_reflection_termeq" -> "fstar_strongexcludedmiddle" + "fstar_reflection_termeq" -> "fstar_strongexcludedmiddle" + "fstar_reflection_termeq" -> "fstar_list_tot" + "fstar_reflection_termeq" -> "fstar_list_tot" + "fstar_reflection_termeq" -> "fstar_stubs_reflection_v2_builtins" + "fstar_reflection_termeq" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_termeq" -> "fstar_stubs_reflection_types" + "fstar_reflection_termeq" -> "fstar_pervasives" + "fstar_reflection_termeq" -> "fstar_pervasives" + "fstar_reflection_termeq" -> "prims" + "fstar_reflection_termeq" -> "prims" + "fstar_reflection_termeq" -> "fstar_reflection_termeq" + "rust_primitives_hax_folds" -> "fstar_math_lemmas" + "rust_primitives_hax_folds" -> "fstar_math_lemmas" + "rust_primitives_hax_folds" -> "lib_inttypes" + "rust_primitives_hax_folds" -> "lib_inttypes" + "rust_primitives_hax_folds" -> "fstar_seq" + "rust_primitives_hax_folds" -> "fstar_seq" + "rust_primitives_hax_folds" -> "fstar_mul" + "rust_primitives_hax_folds" -> "fstar_mul" + "rust_primitives_hax_folds" -> "core_ops_range" + "rust_primitives_hax_folds" -> "rust_primitives" + "rust_primitives_hax_folds" -> "rust_primitives" + "rust_primitives_hax_folds" -> "fstar_pervasives" + "rust_primitives_hax_folds" -> "fstar_pervasives" + "rust_primitives_hax_folds" -> "prims" + "rust_primitives_hax_folds" -> "prims" + "libcrux_ml_dsa_encoding_signing_key" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_signing_key" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_signing_key" -> "core_iter_traits_collect" + "libcrux_ml_dsa_encoding_signing_key" -> "core_iter_traits_collect" + "libcrux_ml_dsa_encoding_signing_key" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_signing_key" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_signing_key" -> "core_ops_range" + "libcrux_ml_dsa_encoding_signing_key" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_signing_key" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_signing_key" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_signing_key" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_signing_key" -> "core_convert" + "libcrux_ml_dsa_encoding_signing_key" -> "core_convert" + "libcrux_ml_dsa_encoding_signing_key" -> "core_array" + "libcrux_ml_dsa_encoding_signing_key" -> "core_array" + "libcrux_ml_dsa_encoding_signing_key" -> "core_result" + "libcrux_ml_dsa_encoding_signing_key" -> "core_result" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_encoding_t0" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_encoding_t0" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_encoding_error" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_encoding_error" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_encoding_signing_key" -> "core_slice" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_mul" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_mul" + "libcrux_ml_dsa_encoding_signing_key" -> "core" + "libcrux_ml_dsa_encoding_signing_key" -> "core" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_signing_key" -> "prims" + "libcrux_ml_dsa_encoding_signing_key" -> "prims" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_encoding_signing_key" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "prims" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "libcrux_ml_dsa_simd_portable_encoding_t0" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_vector_type" -> "prims" + "libcrux_ml_dsa_simd_portable_vector_type" -> "prims" + "core_iter_adapters_step_by" -> "rust_primitives" + "core_iter_adapters_step_by" -> "rust_primitives" + "core_iter_adapters_step_by" -> "fstar_pervasives" + "core_iter_adapters_step_by" -> "fstar_pervasives" + "core_iter_adapters_step_by" -> "prims" + "core_iter_adapters_step_by" -> "prims" + "libcrux_ml_dsa_simd_portable_sample" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_portable_sample" -> "core_slice" + "libcrux_ml_dsa_simd_portable_sample" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_portable_sample" -> "fstar_int32" + "libcrux_ml_dsa_simd_portable_sample" -> "fstar_uint8" + "libcrux_ml_dsa_simd_portable_sample" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_portable_sample" -> "core_slice_iter" + "libcrux_ml_dsa_simd_portable_sample" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_portable_sample" -> "core_iter_traits_collect" + "libcrux_ml_dsa_simd_portable_sample" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_simd_portable_sample" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_sample" -> "core" + "libcrux_ml_dsa_simd_portable_sample" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_sample" -> "prims" + "libcrux_ml_dsa_simd_portable_sample" -> "libcrux_ml_dsa_simd_portable_sample" + "fstar_stubs_tactics_types" -> "fstar_issue" + "fstar_stubs_tactics_types" -> "fstar_range" + "fstar_stubs_tactics_types" -> "fstar_stubs_typechecker_core" + "fstar_stubs_tactics_types" -> "fstar_stubs_tactics_common" + "fstar_stubs_tactics_types" -> "fstar_stubs_reflection_types" + "fstar_stubs_tactics_types" -> "fstar_pervasives" + "fstar_stubs_tactics_types" -> "fstar_pervasives" + "fstar_stubs_tactics_types" -> "prims" + "fstar_stubs_tactics_types" -> "prims" + "libcrux_ml_dsa_samplex4" -> "fstar_uint16" + "libcrux_ml_dsa_samplex4" -> "fstar_uint16" + "libcrux_ml_dsa_samplex4" -> "core_panicking" + "libcrux_ml_dsa_samplex4" -> "core_panicking" + "libcrux_ml_dsa_samplex4" -> "fstar_pervasives_native" + "libcrux_ml_dsa_samplex4" -> "fstar_pervasives_native" + "libcrux_ml_dsa_samplex4" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_samplex4" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_samplex4" -> "fstar_uint8" + "libcrux_ml_dsa_samplex4" -> "fstar_uint8" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_sample" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_sample" + "libcrux_ml_dsa_samplex4" -> "rust_primitives_hax" + "libcrux_ml_dsa_samplex4" -> "rust_primitives_hax" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_samplex4" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_samplex4" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_samplex4" -> "fstar_int32" + "libcrux_ml_dsa_samplex4" -> "fstar_int32" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_samplex4" -> "fstar_mul" + "libcrux_ml_dsa_samplex4" -> "fstar_mul" + "libcrux_ml_dsa_samplex4" -> "core" + "libcrux_ml_dsa_samplex4" -> "core" + "libcrux_ml_dsa_samplex4" -> "fstar_pervasives" + "libcrux_ml_dsa_samplex4" -> "fstar_pervasives" + "libcrux_ml_dsa_samplex4" -> "prims" + "libcrux_ml_dsa_samplex4" -> "prims" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_samplex4" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "prims" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "core" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "core" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "prims" + "libcrux_ml_dsa_simd_avx2_vector_type" -> "prims" + "fstar_stubs_tactics_result" -> "fstar_stubs_tactics_types" + "fstar_stubs_tactics_result" -> "fstar_pervasives" + "fstar_stubs_tactics_result" -> "fstar_pervasives" + "fstar_stubs_tactics_result" -> "prims" + "fstar_stubs_tactics_result" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "prims" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "core_result" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "prims" + "libcrux_ml_dsa_constants" -> "fstar_int32" + "libcrux_ml_dsa_constants" -> "fstar_int32" + "libcrux_ml_dsa_constants" -> "fstar_mul" + "libcrux_ml_dsa_constants" -> "fstar_mul" + "libcrux_ml_dsa_constants" -> "core" + "libcrux_ml_dsa_constants" -> "core" + "libcrux_ml_dsa_constants" -> "fstar_pervasives" + "libcrux_ml_dsa_constants" -> "fstar_pervasives" + "libcrux_ml_dsa_constants" -> "prims" + "libcrux_ml_dsa_constants" -> "prims" + "fstar_int32" -> "fstar_uint" + "fstar_int32" -> "fstar_uint" + "fstar_int32" -> "fstar_uint32" + "fstar_int32" -> "fstar_uint32" + "fstar_int32" -> "fstar_mul" + "fstar_int32" -> "fstar_mul" + "fstar_int32" -> "fstar_int" + "fstar_int32" -> "fstar_int" + "fstar_int32" -> "fstar_pervasives" + "fstar_int32" -> "fstar_pervasives" + "fstar_int32" -> "prims" + "fstar_int32" -> "prims" + "fstar_int" -> "fstar_seq" + "fstar_int" -> "fstar_seq" + "fstar_int" -> "fstar_uint" + "fstar_int" -> "fstar_uint" + "fstar_int" -> "fstar_math_lemmas" + "fstar_int" -> "fstar_math_lemmas" + "fstar_int" -> "fstar_bitvector" + "fstar_int" -> "fstar_bitvector" + "fstar_int" -> "fstar_mul" + "fstar_int" -> "fstar_mul" + "fstar_int" -> "fstar_pervasives" + "fstar_int" -> "fstar_pervasives" + "fstar_int" -> "prims" + "fstar_int" -> "prims" + "libcrux_ml_dsa_matrix" -> "fstar_int32" + "libcrux_ml_dsa_matrix" -> "fstar_int32" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_arithmetic" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_arithmetic" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_ntt" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_ntt" + "libcrux_ml_dsa_matrix" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_matrix" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_matrix" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_matrix" -> "rust_primitives_hax" + "libcrux_ml_dsa_matrix" -> "rust_primitives_hax" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_matrix" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_matrix" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_matrix" -> "fstar_mul" + "libcrux_ml_dsa_matrix" -> "fstar_mul" + "libcrux_ml_dsa_matrix" -> "core" + "libcrux_ml_dsa_matrix" -> "core" + "libcrux_ml_dsa_matrix" -> "fstar_pervasives" + "libcrux_ml_dsa_matrix" -> "fstar_pervasives" + "libcrux_ml_dsa_matrix" -> "prims" + "libcrux_ml_dsa_matrix" -> "prims" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_matrix" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "core" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "core" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "libcrux_ml_dsa_ml_dsa_44__neon" + "fstar_uint16" -> "fstar_uint32" + "fstar_uint16" -> "fstar_uint32" + "fstar_uint16" -> "fstar_mul" + "fstar_uint16" -> "fstar_mul" + "fstar_uint16" -> "fstar_uint" + "fstar_uint16" -> "fstar_uint" + "fstar_uint16" -> "fstar_pervasives" + "fstar_uint16" -> "fstar_pervasives" + "fstar_uint16" -> "prims" + "fstar_uint16" -> "prims" + "fstar_tactics_print" -> "fstar_tactics_namedview" + "fstar_tactics_print" -> "fstar_tactics_namedview" + "fstar_tactics_print" -> "fstar_tactics_v2_derived" + "fstar_tactics_print" -> "fstar_tactics_v2_derived" + "fstar_tactics_print" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_print" -> "fstar_tactics_effect" + "fstar_tactics_print" -> "fstar_tactics_effect" + "fstar_tactics_print" -> "fstar_reflection_v2" + "fstar_tactics_print" -> "fstar_reflection_v2" + "fstar_tactics_print" -> "fstar_pervasives" + "fstar_tactics_print" -> "fstar_pervasives" + "fstar_tactics_print" -> "prims" + "fstar_tactics_print" -> "prims" + "fstar_tactics_print" -> "fstar_tactics_print" + "lib_inttypes" -> "fstar_bitvector" + "lib_inttypes" -> "fstar_bitvector" + "lib_inttypes" -> "fstar_seq" + "lib_inttypes" -> "fstar_seq" + "lib_inttypes" -> "fstar_uint" + "lib_inttypes" -> "fstar_uint" + "lib_inttypes" -> "fstar_pervasives_native" + "lib_inttypes" -> "fstar_pervasives_native" + "lib_inttypes" -> "fstar_int_cast_full" + "lib_inttypes" -> "fstar_int_cast_full" + "lib_inttypes" -> "fstar_int" + "lib_inttypes" -> "fstar_int" + "lib_inttypes" -> "fstar_int_cast" + "lib_inttypes" -> "fstar_int_cast" + "lib_inttypes" -> "fstar_int128" + "lib_inttypes" -> "fstar_int128" + "lib_inttypes" -> "fstar_int64" + "lib_inttypes" -> "fstar_int64" + "lib_inttypes" -> "fstar_int32" + "lib_inttypes" -> "fstar_int32" + "lib_inttypes" -> "fstar_int16" + "lib_inttypes" -> "fstar_int16" + "lib_inttypes" -> "fstar_int8" + "lib_inttypes" -> "fstar_int8" + "lib_inttypes" -> "fstar_uint128" + "lib_inttypes" -> "fstar_uint128" + "lib_inttypes" -> "fstar_uint64" + "lib_inttypes" -> "fstar_uint64" + "lib_inttypes" -> "fstar_uint32" + "lib_inttypes" -> "fstar_uint32" + "lib_inttypes" -> "fstar_uint16" + "lib_inttypes" -> "fstar_uint16" + "lib_inttypes" -> "fstar_uint8" + "lib_inttypes" -> "fstar_uint8" + "lib_inttypes" -> "fstar_math_lemmas" + "lib_inttypes" -> "fstar_math_lemmas" + "lib_inttypes" -> "fstar_pervasives" + "lib_inttypes" -> "fstar_pervasives" + "lib_inttypes" -> "prims" + "lib_inttypes" -> "prims" + "lib_inttypes" -> "lib_inttypes" + "rust_primitives_bitvectors" -> "fstar_uint8" + "rust_primitives_bitvectors" -> "fstar_uint8" + "rust_primitives_bitvectors" -> "fstar_uint16" + "rust_primitives_bitvectors" -> "fstar_uint16" + "rust_primitives_bitvectors" -> "fstar_uint32" + "rust_primitives_bitvectors" -> "fstar_uint32" + "rust_primitives_bitvectors" -> "fstar_int16" + "rust_primitives_bitvectors" -> "fstar_int16" + "rust_primitives_bitvectors" -> "fstar_int32" + "rust_primitives_bitvectors" -> "fstar_int32" + "rust_primitives_bitvectors" -> "fstar_seq" + "rust_primitives_bitvectors" -> "fstar_seq" + "rust_primitives_bitvectors" -> "fstar_functionalextensionality" + "rust_primitives_bitvectors" -> "fstar_functionalextensionality" + "rust_primitives_bitvectors" -> "rust_primitives_integers" + "rust_primitives_bitvectors" -> "rust_primitives_integers" + "rust_primitives_bitvectors" -> "rust_primitives_arrays" + "rust_primitives_bitvectors" -> "rust_primitives_arrays" + "rust_primitives_bitvectors" -> "fstar_mul" + "rust_primitives_bitvectors" -> "fstar_mul" + "rust_primitives_bitvectors" -> "fstar_pervasives" + "rust_primitives_bitvectors" -> "fstar_pervasives" + "rust_primitives_bitvectors" -> "prims" + "rust_primitives_bitvectors" -> "prims" + "fstar_monotonic_witnessed" -> "fstar_classical" + "fstar_monotonic_witnessed" -> "fstar_classical" + "fstar_monotonic_witnessed" -> "fstar_preorder" + "fstar_monotonic_witnessed" -> "fstar_preorder" + "fstar_monotonic_witnessed" -> "fstar_pervasives" + "fstar_monotonic_witnessed" -> "fstar_pervasives" + "fstar_monotonic_witnessed" -> "prims" + "fstar_monotonic_witnessed" -> "prims" + "fstar_monotonic_witnessed" -> "fstar_monotonic_witnessed" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "core_result" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "core" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_65__neon" -> "prims" + "fstar_classical" -> "fstar_squash" + "fstar_classical" -> "fstar_squash" + "fstar_classical" -> "fstar_pervasives" + "fstar_classical" -> "fstar_pervasives" + "fstar_classical" -> "prims" + "fstar_classical" -> "prims" + "fstar_classical" -> "fstar_classical" + "fstar_stubs_typechecker_core" -> "fstar_pervasives" + "fstar_stubs_typechecker_core" -> "fstar_pervasives" + "fstar_stubs_typechecker_core" -> "prims" + "fstar_stubs_typechecker_core" -> "prims" + "fstar_reflection_v1_formula" -> "fstar_pervasives_native" + "fstar_reflection_v1_formula" -> "fstar_pervasives_native" + "fstar_reflection_v1_formula" -> "fstar_stubs_reflection_v1_data" + "fstar_reflection_v1_formula" -> "fstar_reflection_v1_derived" + "fstar_reflection_v1_formula" -> "fstar_reflection_v1_derived" + "fstar_reflection_v1_formula" -> "fstar_stubs_reflection_v1_builtins" + "fstar_reflection_v1_formula" -> "fstar_reflection_const" + "fstar_reflection_v1_formula" -> "fstar_reflection_const" + "fstar_reflection_v1_formula" -> "fstar_stubs_reflection_types" + "fstar_reflection_v1_formula" -> "fstar_stubs_tactics_v1_builtins" + "fstar_reflection_v1_formula" -> "fstar_tactics_effect" + "fstar_reflection_v1_formula" -> "fstar_tactics_effect" + "fstar_reflection_v1_formula" -> "fstar_list_tot_base" + "fstar_reflection_v1_formula" -> "fstar_list_tot_base" + "fstar_reflection_v1_formula" -> "fstar_pervasives" + "fstar_reflection_v1_formula" -> "fstar_pervasives" + "fstar_reflection_v1_formula" -> "prims" + "fstar_reflection_v1_formula" -> "prims" + "fstar_strongexcludedmiddle" -> "fstar_pervasives" + "fstar_strongexcludedmiddle" -> "fstar_pervasives" + "fstar_strongexcludedmiddle" -> "prims" + "fstar_strongexcludedmiddle" -> "prims" + "fstar_tactics_effect" -> "fstar_range" + "fstar_tactics_effect" -> "fstar_stubs_tactics_result" + "fstar_tactics_effect" -> "fstar_stubs_tactics_types" + "fstar_tactics_effect" -> "fstar_stubs_reflection_types" + "fstar_tactics_effect" -> "fstar_monotonic_pure" + "fstar_tactics_effect" -> "fstar_monotonic_pure" + "fstar_tactics_effect" -> "fstar_pervasives" + "fstar_tactics_effect" -> "fstar_pervasives" + "fstar_tactics_effect" -> "prims" + "fstar_tactics_effect" -> "prims" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_encoding_signing_key" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_mul" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_mul" + "libcrux_ml_dsa_encoding_signing_key" -> "core" + "libcrux_ml_dsa_encoding_signing_key" -> "core" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_signing_key" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_signing_key" -> "prims" + "libcrux_ml_dsa_encoding_signing_key" -> "prims" + "fstar_tactics_print" -> "fstar_tactics_effect" + "fstar_tactics_print" -> "fstar_tactics_effect" + "fstar_tactics_print" -> "fstar_stubs_reflection_v2_data" + "fstar_tactics_print" -> "fstar_stubs_reflection_types" + "fstar_tactics_print" -> "fstar_pervasives" + "fstar_tactics_print" -> "fstar_pervasives" + "fstar_tactics_print" -> "prims" + "fstar_tactics_print" -> "prims" + "libcrux_ml_dsa_simd_avx2_ntt" -> "core_slice" + "libcrux_ml_dsa_simd_avx2_ntt" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_ntt" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2_ntt" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_ml_dsa_simd_avx2_arithmetic" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_ml_dsa_simd_avx2_arithmetic" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_ntt" -> "core" + "libcrux_ml_dsa_simd_avx2_ntt" -> "core" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_ntt" -> "prims" + "libcrux_ml_dsa_simd_avx2_ntt" -> "prims" + "libcrux_ml_dsa_simd_avx2_ntt" -> "libcrux_ml_dsa_simd_avx2_ntt" + "fstar_tactics_bv" -> "fstar_tactics_bv_lemmas" + "fstar_tactics_bv" -> "fstar_tactics_bv_lemmas" + "fstar_tactics_bv" -> "fstar_tactics_effect" + "fstar_tactics_bv" -> "fstar_tactics_effect" + "fstar_tactics_bv" -> "fstar_pervasives" + "fstar_tactics_bv" -> "fstar_pervasives" + "fstar_tactics_bv" -> "prims" + "fstar_tactics_bv" -> "prims" + "fstar_stubs_syntax_syntax" -> "fstar_stubs_reflection_types" + "fstar_stubs_syntax_syntax" -> "fstar_pervasives" + "fstar_stubs_syntax_syntax" -> "fstar_pervasives" + "fstar_stubs_syntax_syntax" -> "prims" + "fstar_stubs_syntax_syntax" -> "prims" + "libcrux_ml_dsa_polynomial" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_polynomial" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_polynomial" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_polynomial" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_polynomial" -> "fstar_mul" + "libcrux_ml_dsa_polynomial" -> "fstar_mul" + "libcrux_ml_dsa_polynomial" -> "core" + "libcrux_ml_dsa_polynomial" -> "core" + "libcrux_ml_dsa_polynomial" -> "fstar_pervasives" + "libcrux_ml_dsa_polynomial" -> "fstar_pervasives" + "libcrux_ml_dsa_polynomial" -> "prims" + "libcrux_ml_dsa_polynomial" -> "prims" + "core_fmt_rt" -> "fstar_pervasives" + "core_fmt_rt" -> "fstar_pervasives" + "core_fmt_rt" -> "prims" + "core_fmt_rt" -> "prims" + "libcrux_ml_dsa_types" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_types" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_types" -> "fstar_mul" + "libcrux_ml_dsa_types" -> "fstar_mul" + "libcrux_ml_dsa_types" -> "core" + "libcrux_ml_dsa_types" -> "core" + "libcrux_ml_dsa_types" -> "fstar_pervasives" + "libcrux_ml_dsa_types" -> "fstar_pervasives" + "libcrux_ml_dsa_types" -> "prims" + "libcrux_ml_dsa_types" -> "prims" + "libcrux_ml_dsa_types" -> "libcrux_ml_dsa_types" + "lib_bytesequence" -> "fstar_pervasives_native" + "lib_bytesequence" -> "fstar_pervasives_native" + "lib_bytesequence" -> "fstar_calc" + "lib_bytesequence" -> "fstar_calc" + "lib_bytesequence" -> "fstar_math_lemmas" + "lib_bytesequence" -> "fstar_math_lemmas" + "lib_bytesequence" -> "fstar_classical" + "lib_bytesequence" -> "fstar_classical" + "lib_bytesequence" -> "fstar_uint8" + "lib_bytesequence" -> "fstar_uint8" + "lib_bytesequence" -> "fstar_seq" + "lib_bytesequence" -> "fstar_seq" + "lib_bytesequence" -> "lib_loopcombinators" + "lib_bytesequence" -> "lib_loopcombinators" + "lib_bytesequence" -> "lib_rawinttypes" + "lib_bytesequence" -> "lib_rawinttypes" + "lib_bytesequence" -> "lib_sequence" + "lib_bytesequence" -> "lib_sequence" + "lib_bytesequence" -> "lib_inttypes" + "lib_bytesequence" -> "lib_inttypes" + "lib_bytesequence" -> "fstar_mul" + "lib_bytesequence" -> "fstar_mul" + "lib_bytesequence" -> "fstar_pervasives" + "lib_bytesequence" -> "fstar_pervasives" + "lib_bytesequence" -> "prims" + "lib_bytesequence" -> "prims" + "lib_bytesequence" -> "lib_bytesequence" + "fstar_uint64" -> "fstar_uint32" + "fstar_uint64" -> "fstar_uint32" + "fstar_uint64" -> "fstar_mul" + "fstar_uint64" -> "fstar_mul" + "fstar_uint64" -> "fstar_uint" + "fstar_uint64" -> "fstar_uint" + "fstar_uint64" -> "fstar_pervasives" + "fstar_uint64" -> "fstar_pervasives" + "fstar_uint64" -> "prims" + "fstar_uint64" -> "prims" + "fstar_uint64" -> "fstar_uint64" + "spec_sha3_constants" -> "fstar_uint64" + "spec_sha3_constants" -> "fstar_uint64" + "spec_sha3_constants" -> "fstar_list_tot" + "spec_sha3_constants" -> "fstar_list_tot" + "spec_sha3_constants" -> "fstar_uint32" + "spec_sha3_constants" -> "fstar_uint32" + "spec_sha3_constants" -> "lib_sequence" + "spec_sha3_constants" -> "lib_sequence" + "spec_sha3_constants" -> "lib_inttypes" + "spec_sha3_constants" -> "lib_inttypes" + "spec_sha3_constants" -> "fstar_pervasives" + "spec_sha3_constants" -> "fstar_pervasives" + "spec_sha3_constants" -> "prims" + "spec_sha3_constants" -> "prims" + "libcrux_ml_dsa_pre_hash" -> "rust_primitives_hax" + "libcrux_ml_dsa_pre_hash" -> "rust_primitives_hax" + "libcrux_ml_dsa_pre_hash" -> "fstar_list_tot" + "libcrux_ml_dsa_pre_hash" -> "fstar_list_tot" + "libcrux_ml_dsa_pre_hash" -> "fstar_uint8" + "libcrux_ml_dsa_pre_hash" -> "fstar_uint8" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_pre_hash" -> "core_convert" + "libcrux_ml_dsa_pre_hash" -> "core_convert" + "libcrux_ml_dsa_pre_hash" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_pre_hash" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_pre_hash" -> "core_result" + "libcrux_ml_dsa_pre_hash" -> "core_result" + "libcrux_ml_dsa_pre_hash" -> "core_option" + "libcrux_ml_dsa_pre_hash" -> "core_option" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_pre_hash" -> "fstar_mul" + "libcrux_ml_dsa_pre_hash" -> "fstar_mul" + "libcrux_ml_dsa_pre_hash" -> "core" + "libcrux_ml_dsa_pre_hash" -> "core" + "libcrux_ml_dsa_pre_hash" -> "fstar_pervasives" + "libcrux_ml_dsa_pre_hash" -> "fstar_pervasives" + "libcrux_ml_dsa_pre_hash" -> "prims" + "libcrux_ml_dsa_pre_hash" -> "prims" + "fstar_tactics_v1" -> "fstar_tactics_smt" + "fstar_tactics_v1" -> "fstar_tactics_smt" + "fstar_tactics_v1" -> "fstar_tactics_visit" + "fstar_tactics_v1" -> "fstar_tactics_visit" + "fstar_tactics_v1" -> "fstar_tactics_print" + "fstar_tactics_v1" -> "fstar_tactics_print" + "fstar_tactics_v1" -> "fstar_tactics_util" + "fstar_tactics_v1" -> "fstar_tactics_util" + "fstar_tactics_v1" -> "fstar_tactics_v1_logic" + "fstar_tactics_v1" -> "fstar_tactics_v1_logic" + "fstar_tactics_v1" -> "fstar_tactics_v1_syntaxhelpers" + "fstar_tactics_v1" -> "fstar_tactics_v1_syntaxhelpers" + "fstar_tactics_v1" -> "fstar_tactics_v1_derived" + "fstar_tactics_v1" -> "fstar_tactics_v1_derived" + "fstar_tactics_v1" -> "fstar_stubs_tactics_v1_builtins" + "fstar_tactics_v1" -> "fstar_tactics_effect" + "fstar_tactics_v1" -> "fstar_tactics_effect" + "fstar_tactics_v1" -> "fstar_stubs_tactics_types" + "fstar_tactics_v1" -> "fstar_reflection_v1_compare" + "fstar_tactics_v1" -> "fstar_reflection_v1_formula" + "fstar_tactics_v1" -> "fstar_reflection_v1_formula" + "fstar_tactics_v1" -> "fstar_reflection_v1_derived" + "fstar_tactics_v1" -> "fstar_reflection_v1_derived" + "fstar_tactics_v1" -> "fstar_stubs_reflection_v1_builtins" + "fstar_tactics_v1" -> "fstar_stubs_reflection_v1_data" + "fstar_tactics_v1" -> "fstar_reflection_const" + "fstar_tactics_v1" -> "fstar_reflection_const" + "fstar_tactics_v1" -> "fstar_stubs_reflection_types" + "fstar_tactics_v1" -> "fstar_pervasives" + "fstar_tactics_v1" -> "fstar_pervasives" + "fstar_tactics_v1" -> "prims" + "fstar_tactics_v1" -> "prims" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_ntt" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_ntt" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_t1" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_t1" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_t0" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_t0" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_error" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_error" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_commitment" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_commitment" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_gamma1" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_encoding_gamma1" + "libcrux_ml_dsa_simd_portable" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_portable" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_sample" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_sample" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_arithmetic" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_arithmetic" + "libcrux_ml_dsa_simd_portable" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_portable" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable" -> "core" + "libcrux_ml_dsa_simd_portable" -> "core" + "libcrux_ml_dsa_simd_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable" -> "prims" + "libcrux_ml_dsa_simd_portable" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_error" -> "prims" + "fstar_seq_base" -> "fstar_list_tot" + "fstar_seq_base" -> "fstar_list_tot" + "fstar_seq_base" -> "fstar_pervasives" + "fstar_seq_base" -> "fstar_pervasives" + "fstar_seq_base" -> "prims" + "fstar_seq_base" -> "prims" + "fstar_seq_base" -> "fstar_seq_base" + "fstar_int8" -> "fstar_uint32" + "fstar_int8" -> "fstar_uint32" + "fstar_int8" -> "fstar_math_lemmas" + "fstar_int8" -> "fstar_math_lemmas" + "fstar_int8" -> "fstar_mul" + "fstar_int8" -> "fstar_mul" + "fstar_int8" -> "fstar_int" + "fstar_int8" -> "fstar_int" + "fstar_int8" -> "fstar_pervasives" + "fstar_int8" -> "fstar_pervasives" + "fstar_int8" -> "prims" + "fstar_int8" -> "prims" + "fstar_int8" -> "fstar_int8" + "bitvec_utils" -> "fstar_list_tot" + "bitvec_utils" -> "fstar_list_tot" + "bitvec_utils" -> "rust_primitives_bitvectors" + "bitvec_utils" -> "rust_primitives_bitvectors" + "bitvec_utils" -> "bitvec_equality" + "bitvec_utils" -> "bitvec_equality" + "bitvec_utils" -> "fstar_functionalextensionality" + "bitvec_utils" -> "fstar_functionalextensionality" + "bitvec_utils" -> "core" + "bitvec_utils" -> "core" + "bitvec_utils" -> "fstar_pervasives" + "bitvec_utils" -> "fstar_pervasives" + "bitvec_utils" -> "prims" + "bitvec_utils" -> "prims" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_sha3_portable_incremental" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_sha3_portable" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_sha3_portable" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_portable" -> "core" + "libcrux_ml_dsa_hash_functions_portable" -> "core" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_portable" -> "prims" + "libcrux_ml_dsa_hash_functions_portable" -> "prims" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_ml_dsa_hash_functions_portable" + "core_clone" -> "fstar_tactics_typeclasses" + "core_clone" -> "fstar_tactics_typeclasses" + "core_clone" -> "fstar_pervasives" + "core_clone" -> "fstar_pervasives" + "core_clone" -> "prims" + "core_clone" -> "prims" + "libcrux_ml_dsa_simd_portable_ntt" -> "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" + "libcrux_ml_dsa_simd_portable_ntt" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_ntt" -> "core" + "libcrux_ml_dsa_simd_portable_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_ntt" -> "prims" + "libcrux_ml_dsa_simd_portable_ntt" -> "libcrux_ml_dsa_simd_portable_ntt" + "fstar_bv" -> "fstar_list" + "fstar_bv" -> "fstar_list" + "fstar_bv" -> "fstar_uint" + "fstar_bv" -> "fstar_uint" + "fstar_bv" -> "fstar_pervasives" + "fstar_bv" -> "fstar_pervasives" + "fstar_bv" -> "prims" + "fstar_bv" -> "prims" + "libcrux_ml_dsa_polynomial" -> "core_ops_range" + "libcrux_ml_dsa_polynomial" -> "fstar_int32" + "libcrux_ml_dsa_polynomial" -> "fstar_int32" + "libcrux_ml_dsa_polynomial" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_polynomial" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_polynomial" -> "core_option" + "libcrux_ml_dsa_polynomial" -> "core_option" + "libcrux_ml_dsa_polynomial" -> "fstar_pervasives_native" + "libcrux_ml_dsa_polynomial" -> "fstar_pervasives_native" + "libcrux_ml_dsa_polynomial" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_polynomial" -> "core_slice_iter" + "libcrux_ml_dsa_polynomial" -> "core_slice_iter" + "libcrux_ml_dsa_polynomial" -> "core_slice" + "libcrux_ml_dsa_polynomial" -> "hax_lib" + "libcrux_ml_dsa_polynomial" -> "hax_lib" + "libcrux_ml_dsa_polynomial" -> "rust_primitives_hax" + "libcrux_ml_dsa_polynomial" -> "rust_primitives_hax" + "libcrux_ml_dsa_polynomial" -> "core_array_iter" + "libcrux_ml_dsa_polynomial" -> "core_iter_traits_collect" + "libcrux_ml_dsa_polynomial" -> "core_iter_traits_collect" + "libcrux_ml_dsa_polynomial" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_polynomial" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_polynomial" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_polynomial" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_polynomial" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_polynomial" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_polynomial" -> "fstar_mul" + "libcrux_ml_dsa_polynomial" -> "fstar_mul" + "libcrux_ml_dsa_polynomial" -> "core" + "libcrux_ml_dsa_polynomial" -> "core" + "libcrux_ml_dsa_polynomial" -> "fstar_pervasives" + "libcrux_ml_dsa_polynomial" -> "fstar_pervasives" + "libcrux_ml_dsa_polynomial" -> "prims" + "libcrux_ml_dsa_polynomial" -> "prims" + "libcrux_ml_dsa_polynomial" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_types" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_types" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_types" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_types" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_types" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_types" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_types" -> "fstar_mul" + "libcrux_ml_dsa_types" -> "fstar_mul" + "libcrux_ml_dsa_types" -> "core" + "libcrux_ml_dsa_types" -> "core" + "libcrux_ml_dsa_types" -> "fstar_pervasives" + "libcrux_ml_dsa_types" -> "fstar_pervasives" + "libcrux_ml_dsa_types" -> "prims" + "libcrux_ml_dsa_types" -> "prims" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "core" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "prims" + "fstar_erasedlogic" -> "fstar_ghost" + "fstar_erasedlogic" -> "fstar_ghost" + "fstar_erasedlogic" -> "fstar_pervasives" + "fstar_erasedlogic" -> "fstar_pervasives" + "fstar_erasedlogic" -> "prims" + "fstar_erasedlogic" -> "prims" + "core_array" -> "rust_primitives" + "core_array" -> "rust_primitives" + "core_array" -> "fstar_pervasives" + "core_array" -> "fstar_pervasives" + "core_array" -> "prims" + "core_array" -> "prims" + "fstar_math_lemmas" -> "fstar_mul" + "fstar_math_lemmas" -> "fstar_mul" + "fstar_math_lemmas" -> "fstar_pervasives" + "fstar_math_lemmas" -> "fstar_pervasives" + "fstar_math_lemmas" -> "prims" + "fstar_math_lemmas" -> "prims" + "fstar_tactics_names" -> "fstar_tactics_visit" + "fstar_tactics_names" -> "fstar_tactics_visit" + "fstar_tactics_names" -> "fstar_stubs_reflection_v2_builtins" + "fstar_tactics_names" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_names" -> "fstar_tactics_effect" + "fstar_tactics_names" -> "fstar_tactics_effect" + "fstar_tactics_names" -> "fstar_tactics_namedview" + "fstar_tactics_names" -> "fstar_tactics_namedview" + "fstar_tactics_names" -> "fstar_pervasives" + "fstar_tactics_names" -> "fstar_pervasives" + "fstar_tactics_names" -> "prims" + "fstar_tactics_names" -> "prims" + "fstar_tactics_names" -> "fstar_tactics_names" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_list_tot_base" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_list_tot_base" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_pervasives_native" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_pervasives_native" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_namedview" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_namedview" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_stubs_tactics_types" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_effect" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_effect" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_reflection_v2" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_reflection_v2" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_pervasives" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_pervasives" + "fstar_tactics_v2_syntaxhelpers" -> "prims" + "fstar_tactics_v2_syntaxhelpers" -> "prims" + "fstar_tactics_v2_syntaxhelpers" -> "fstar_tactics_v2_syntaxhelpers" + "rust_primitives_integers" -> "fstar_int_cast" + "rust_primitives_integers" -> "fstar_int_cast" + "rust_primitives_integers" -> "fstar_pervasives" + "rust_primitives_integers" -> "fstar_pervasives" + "rust_primitives_integers" -> "prims" + "rust_primitives_integers" -> "prims" + "rust_primitives_integers" -> "rust_primitives_integers" + "core_marker" -> "fstar_tactics_typeclasses" + "core_marker" -> "fstar_tactics_typeclasses" + "core_marker" -> "fstar_pervasives" + "core_marker" -> "fstar_pervasives" + "core_marker" -> "prims" + "core_marker" -> "prims" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" + "libcrux_ml_dsa_simd_portable" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable" -> "core" + "libcrux_ml_dsa_simd_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable" -> "prims" + "libcrux_ml_dsa_simd_portable" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_verification_key" -> "core_convert" + "libcrux_ml_dsa_encoding_verification_key" -> "core_convert" + "libcrux_ml_dsa_encoding_verification_key" -> "core_array" + "libcrux_ml_dsa_encoding_verification_key" -> "core_array" + "libcrux_ml_dsa_encoding_verification_key" -> "core_result" + "libcrux_ml_dsa_encoding_verification_key" -> "core_result" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_verification_key" -> "core_ops_range" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_encoding_t1" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_encoding_t1" + "libcrux_ml_dsa_encoding_verification_key" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_verification_key" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_verification_key" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_encoding_verification_key" -> "core_slice" + "libcrux_ml_dsa_encoding_verification_key" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_verification_key" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_mul" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_mul" + "libcrux_ml_dsa_encoding_verification_key" -> "core" + "libcrux_ml_dsa_encoding_verification_key" -> "core" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_verification_key" -> "prims" + "libcrux_ml_dsa_encoding_verification_key" -> "prims" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_encoding_verification_key" + "core_ops_control_flow" -> "fstar_pervasives" + "core_ops_control_flow" -> "fstar_pervasives" + "core_ops_control_flow" -> "prims" + "core_ops_control_flow" -> "prims" + "fstar_uint32" -> "fstar_mul" + "fstar_uint32" -> "fstar_mul" + "fstar_uint32" -> "fstar_uint" + "fstar_uint32" -> "fstar_uint" + "fstar_uint32" -> "fstar_pervasives" + "fstar_uint32" -> "fstar_pervasives" + "fstar_uint32" -> "prims" + "fstar_uint32" -> "prims" + "fstar_uint32" -> "fstar_uint32" + "fstar_tactics_v2_derived" -> "fstar_propositionalextensionality" + "fstar_tactics_v2_derived" -> "fstar_propositionalextensionality" + "fstar_tactics_v2_derived" -> "fstar_squash" + "fstar_tactics_v2_derived" -> "fstar_squash" + "fstar_tactics_v2_derived" -> "fstar_range" + "fstar_tactics_v2_derived" -> "fstar_pervasives_native" + "fstar_tactics_v2_derived" -> "fstar_pervasives_native" + "fstar_tactics_v2_derived" -> "fstar_reflection_termeq_simple" + "fstar_tactics_v2_derived" -> "fstar_reflection_termeq_simple" + "fstar_tactics_v2_derived" -> "fstar_tactics_visit" + "fstar_tactics_v2_derived" -> "fstar_tactics_visit" + "fstar_tactics_v2_derived" -> "fstar_list_tot_base" + "fstar_tactics_v2_derived" -> "fstar_list_tot_base" + "fstar_tactics_v2_derived" -> "fstar_tactics_names" + "fstar_tactics_v2_derived" -> "fstar_tactics_names" + "fstar_tactics_v2_derived" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_v2_derived" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_v2_derived" -> "fstar_tactics_namedview" + "fstar_tactics_v2_derived" -> "fstar_tactics_namedview" + "fstar_tactics_v2_derived" -> "fstar_vconfig" + "fstar_tactics_v2_derived" -> "fstar_tactics_v2_syntaxhelpers" + "fstar_tactics_v2_derived" -> "fstar_tactics_v2_syntaxhelpers" + "fstar_tactics_v2_derived" -> "fstar_tactics_util" + "fstar_tactics_v2_derived" -> "fstar_tactics_util" + "fstar_tactics_v2_derived" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_v2_derived" -> "fstar_stubs_tactics_result" + "fstar_tactics_v2_derived" -> "fstar_stubs_tactics_types" + "fstar_tactics_v2_derived" -> "fstar_tactics_effect" + "fstar_tactics_v2_derived" -> "fstar_tactics_effect" + "fstar_tactics_v2_derived" -> "fstar_reflection_v2_formula" + "fstar_tactics_v2_derived" -> "fstar_reflection_v2_formula" + "fstar_tactics_v2_derived" -> "fstar_reflection_v2" + "fstar_tactics_v2_derived" -> "fstar_reflection_v2" + "fstar_tactics_v2_derived" -> "fstar_pervasives" + "fstar_tactics_v2_derived" -> "fstar_pervasives" + "fstar_tactics_v2_derived" -> "prims" + "fstar_tactics_v2_derived" -> "prims" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "prims" + "fstar_stubs_pprint" -> "fstar_float" + "fstar_stubs_pprint" -> "fstar_char" + "fstar_stubs_pprint" -> "fstar_pervasives" + "fstar_stubs_pprint" -> "fstar_pervasives" + "fstar_stubs_pprint" -> "prims" + "fstar_stubs_pprint" -> "prims" + "fstar_reflection_termeq" -> "fstar_list_tot" + "fstar_reflection_termeq" -> "fstar_list_tot" + "fstar_reflection_termeq" -> "fstar_stubs_reflection_v2_builtins" + "fstar_reflection_termeq" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_termeq" -> "fstar_stubs_reflection_types" + "fstar_reflection_termeq" -> "fstar_pervasives" + "fstar_reflection_termeq" -> "fstar_pervasives" + "fstar_reflection_termeq" -> "prims" + "fstar_reflection_termeq" -> "prims" + "fstar_st" -> "fstar_set" + "fstar_st" -> "fstar_set" + "fstar_st" -> "fstar_monotonic_witnessed" + "fstar_st" -> "fstar_monotonic_witnessed" + "fstar_st" -> "fstar_preorder" + "fstar_st" -> "fstar_preorder" + "fstar_st" -> "fstar_heap" + "fstar_st" -> "fstar_heap" + "fstar_st" -> "fstar_tset" + "fstar_st" -> "fstar_tset" + "fstar_st" -> "fstar_pervasives" + "fstar_st" -> "fstar_pervasives" + "fstar_st" -> "prims" + "fstar_st" -> "prims" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_list_tot_base" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_list_tot_base" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_pervasives_native" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_pervasives_native" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_stubs_tactics_v1_builtins" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_stubs_tactics_types" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_tactics_effect" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_tactics_effect" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_reflection_v1" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_reflection_v1" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_pervasives" + "fstar_tactics_v1_syntaxhelpers" -> "fstar_pervasives" + "fstar_tactics_v1_syntaxhelpers" -> "prims" + "fstar_tactics_v1_syntaxhelpers" -> "prims" + "lib_rawinttypes" -> "fstar_uint128" + "lib_rawinttypes" -> "fstar_uint128" + "lib_rawinttypes" -> "fstar_uint64" + "lib_rawinttypes" -> "fstar_uint64" + "lib_rawinttypes" -> "fstar_uint32" + "lib_rawinttypes" -> "fstar_uint32" + "lib_rawinttypes" -> "fstar_uint16" + "lib_rawinttypes" -> "fstar_uint16" + "lib_rawinttypes" -> "fstar_uint8" + "lib_rawinttypes" -> "fstar_uint8" + "lib_rawinttypes" -> "lib_inttypes" + "lib_rawinttypes" -> "lib_inttypes" + "lib_rawinttypes" -> "fstar_pervasives" + "lib_rawinttypes" -> "fstar_pervasives" + "lib_rawinttypes" -> "prims" + "lib_rawinttypes" -> "prims" + "fstar_uint8" -> "fstar_uint32" + "fstar_uint8" -> "fstar_uint32" + "fstar_uint8" -> "fstar_mul" + "fstar_uint8" -> "fstar_mul" + "fstar_uint8" -> "fstar_uint" + "fstar_uint8" -> "fstar_uint" + "fstar_uint8" -> "fstar_pervasives" + "fstar_uint8" -> "fstar_pervasives" + "fstar_uint8" -> "prims" + "fstar_uint8" -> "prims" + "fstar_uint8" -> "fstar_uint8" + "libcrux_sha3_traits" -> "fstar_tactics_typeclasses" + "libcrux_sha3_traits" -> "fstar_tactics_typeclasses" + "libcrux_sha3_traits" -> "fstar_mul" + "libcrux_sha3_traits" -> "fstar_mul" + "libcrux_sha3_traits" -> "core" + "libcrux_sha3_traits" -> "core" + "libcrux_sha3_traits" -> "fstar_pervasives" + "libcrux_sha3_traits" -> "fstar_pervasives" + "libcrux_sha3_traits" -> "prims" + "libcrux_sha3_traits" -> "prims" + "rust_primitives" -> "fstar_seq" + "rust_primitives" -> "fstar_seq" + "rust_primitives" -> "fstar_tactics_typeclasses" + "rust_primitives" -> "fstar_tactics_typeclasses" + "rust_primitives" -> "core_ops_control_flow" + "rust_primitives" -> "core_ops_control_flow" + "rust_primitives" -> "core_result" + "rust_primitives" -> "core_result" + "rust_primitives" -> "core_option" + "rust_primitives" -> "core_option" + "rust_primitives" -> "rust_primitives_bitvectors" + "rust_primitives" -> "rust_primitives_bitvectors" + "rust_primitives" -> "rust_primitives_arrays" + "rust_primitives" -> "rust_primitives_arrays" + "rust_primitives" -> "rust_primitives_integers" + "rust_primitives" -> "rust_primitives_integers" + "rust_primitives" -> "fstar_pervasives" + "rust_primitives" -> "fstar_pervasives" + "rust_primitives" -> "prims" + "rust_primitives" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_neon" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_neon" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "prims" + "fstar_int16" -> "fstar_uint32" + "fstar_int16" -> "fstar_uint32" + "fstar_int16" -> "fstar_math_lemmas" + "fstar_int16" -> "fstar_math_lemmas" + "fstar_int16" -> "fstar_mul" + "fstar_int16" -> "fstar_mul" + "fstar_int16" -> "fstar_int" + "fstar_int16" -> "fstar_int" + "fstar_int16" -> "fstar_pervasives" + "fstar_int16" -> "fstar_pervasives" + "fstar_int16" -> "prims" + "fstar_int16" -> "prims" + "fstar_int16" -> "fstar_int16" + "fstar_reflection_v1" -> "fstar_reflection_v1_compare" + "fstar_reflection_v1" -> "fstar_reflection_const" + "fstar_reflection_v1" -> "fstar_reflection_const" + "fstar_reflection_v1" -> "fstar_reflection_v1_derived_lemmas" + "fstar_reflection_v1" -> "fstar_reflection_v1_derived_lemmas" + "fstar_reflection_v1" -> "fstar_reflection_v1_derived" + "fstar_reflection_v1" -> "fstar_reflection_v1_derived" + "fstar_reflection_v1" -> "fstar_stubs_reflection_v1_builtins" + "fstar_reflection_v1" -> "fstar_stubs_reflection_v1_data" + "fstar_reflection_v1" -> "fstar_stubs_reflection_types" + "fstar_reflection_v1" -> "fstar_pervasives" + "fstar_reflection_v1" -> "fstar_pervasives" + "fstar_reflection_v1" -> "prims" + "fstar_reflection_v1" -> "prims" + "fstar_tactics_v2_logic" -> "fstar_pervasives_native" + "fstar_tactics_v2_logic" -> "fstar_pervasives_native" + "fstar_tactics_v2_logic" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_v2_logic" -> "fstar_stubs_tactics_types" + "fstar_tactics_v2_logic" -> "fstar_tactics_v1_logic_lemmas" + "fstar_tactics_v2_logic" -> "fstar_tactics_v1_logic_lemmas" + "fstar_tactics_v2_logic" -> "fstar_tactics_namedview" + "fstar_tactics_v2_logic" -> "fstar_tactics_namedview" + "fstar_tactics_v2_logic" -> "fstar_reflection_v2_formula" + "fstar_tactics_v2_logic" -> "fstar_reflection_v2_formula" + "fstar_tactics_v2_logic" -> "fstar_reflection_v2" + "fstar_tactics_v2_logic" -> "fstar_reflection_v2" + "fstar_tactics_v2_logic" -> "fstar_tactics_effect" + "fstar_tactics_v2_logic" -> "fstar_tactics_effect" + "fstar_tactics_v2_logic" -> "fstar_pervasives" + "fstar_tactics_v2_logic" -> "fstar_pervasives" + "fstar_tactics_v2_logic" -> "prims" + "fstar_tactics_v2_logic" -> "prims" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_samplex4" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_samplex4" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_samplex4" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_samplex4" -> "fstar_mul" + "libcrux_ml_dsa_samplex4" -> "fstar_mul" + "libcrux_ml_dsa_samplex4" -> "core" + "libcrux_ml_dsa_samplex4" -> "core" + "libcrux_ml_dsa_samplex4" -> "fstar_pervasives" + "libcrux_ml_dsa_samplex4" -> "fstar_pervasives" + "libcrux_ml_dsa_samplex4" -> "prims" + "libcrux_ml_dsa_samplex4" -> "prims" + "fstar_functionalextensionality" -> "fstar_pervasives_native" + "fstar_functionalextensionality" -> "fstar_pervasives_native" + "fstar_functionalextensionality" -> "fstar_tactics_effect" + "fstar_functionalextensionality" -> "fstar_tactics_effect" + "fstar_functionalextensionality" -> "fstar_stubs_tactics_types" + "fstar_functionalextensionality" -> "fstar_stubs_reflection_types" + "fstar_functionalextensionality" -> "fstar_stubs_tactics_v2_builtins" + "fstar_functionalextensionality" -> "fstar_pervasives" + "fstar_functionalextensionality" -> "fstar_pervasives" + "fstar_functionalextensionality" -> "prims" + "fstar_functionalextensionality" -> "prims" + "fstar_functionalextensionality" -> "fstar_functionalextensionality" + "rust_primitives_integers" -> "fstar_pervasives_native" + "rust_primitives_integers" -> "fstar_pervasives_native" + "rust_primitives_integers" -> "fstar_int" + "rust_primitives_integers" -> "fstar_int" + "rust_primitives_integers" -> "fstar_int128" + "rust_primitives_integers" -> "fstar_int128" + "rust_primitives_integers" -> "fstar_uint128" + "rust_primitives_integers" -> "fstar_uint128" + "rust_primitives_integers" -> "fstar_int64" + "rust_primitives_integers" -> "fstar_int64" + "rust_primitives_integers" -> "fstar_uint64" + "rust_primitives_integers" -> "fstar_uint64" + "rust_primitives_integers" -> "fstar_int32" + "rust_primitives_integers" -> "fstar_int32" + "rust_primitives_integers" -> "fstar_uint32" + "rust_primitives_integers" -> "fstar_uint32" + "rust_primitives_integers" -> "fstar_int16" + "rust_primitives_integers" -> "fstar_int16" + "rust_primitives_integers" -> "fstar_uint16" + "rust_primitives_integers" -> "fstar_uint16" + "rust_primitives_integers" -> "fstar_int8" + "rust_primitives_integers" -> "fstar_int8" + "rust_primitives_integers" -> "fstar_uint8" + "rust_primitives_integers" -> "fstar_uint8" + "rust_primitives_integers" -> "lib_inttypes" + "rust_primitives_integers" -> "lib_inttypes" + "rust_primitives_integers" -> "fstar_mul" + "rust_primitives_integers" -> "fstar_mul" + "rust_primitives_integers" -> "fstar_pervasives" + "rust_primitives_integers" -> "fstar_pervasives" + "rust_primitives_integers" -> "prims" + "rust_primitives_integers" -> "prims" + "fstar_set" -> "fstar_classical" + "fstar_set" -> "fstar_classical" + "fstar_set" -> "fstar_functionalextensionality" + "fstar_set" -> "fstar_functionalextensionality" + "fstar_set" -> "fstar_pervasives" + "fstar_set" -> "fstar_pervasives" + "fstar_set" -> "prims" + "fstar_set" -> "prims" + "fstar_set" -> "fstar_set" + "fstar_tactics" -> "fstar_tactics_v1" + "fstar_tactics" -> "fstar_tactics_v1" + "fstar_tactics" -> "fstar_pervasives" + "fstar_tactics" -> "fstar_pervasives" + "fstar_tactics" -> "prims" + "fstar_tactics" -> "prims" + "lib_bytesequence" -> "fstar_seq" + "lib_bytesequence" -> "fstar_seq" + "lib_bytesequence" -> "fstar_seq_base" + "lib_bytesequence" -> "fstar_seq_base" + "lib_bytesequence" -> "lib_sequence" + "lib_bytesequence" -> "lib_sequence" + "lib_bytesequence" -> "lib_inttypes" + "lib_bytesequence" -> "lib_inttypes" + "lib_bytesequence" -> "fstar_mul" + "lib_bytesequence" -> "fstar_mul" + "lib_bytesequence" -> "fstar_pervasives" + "lib_bytesequence" -> "fstar_pervasives" + "lib_bytesequence" -> "prims" + "lib_bytesequence" -> "prims" + "rust_primitives_bitvectors" -> "fstar_math_lemmas" + "rust_primitives_bitvectors" -> "fstar_math_lemmas" + "rust_primitives_bitvectors" -> "rust_primitives_integers" + "rust_primitives_bitvectors" -> "rust_primitives_integers" + "rust_primitives_bitvectors" -> "rust_primitives_arrays" + "rust_primitives_bitvectors" -> "rust_primitives_arrays" + "rust_primitives_bitvectors" -> "fstar_mul" + "rust_primitives_bitvectors" -> "fstar_mul" + "rust_primitives_bitvectors" -> "fstar_pervasives" + "rust_primitives_bitvectors" -> "fstar_pervasives" + "rust_primitives_bitvectors" -> "prims" + "rust_primitives_bitvectors" -> "prims" + "rust_primitives_bitvectors" -> "rust_primitives_bitvectors" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_ntt" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_ntt" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_ntt" -> "rust_primitives_hax" + "libcrux_ml_dsa_ntt" -> "rust_primitives_hax" + "libcrux_ml_dsa_ntt" -> "fstar_list_tot" + "libcrux_ml_dsa_ntt" -> "fstar_list_tot" + "libcrux_ml_dsa_ntt" -> "fstar_int32" + "libcrux_ml_dsa_ntt" -> "fstar_int32" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ntt" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ntt" -> "fstar_mul" + "libcrux_ml_dsa_ntt" -> "fstar_mul" + "libcrux_ml_dsa_ntt" -> "core" + "libcrux_ml_dsa_ntt" -> "core" + "libcrux_ml_dsa_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_ntt" -> "prims" + "libcrux_ml_dsa_ntt" -> "prims" + "fstar_classical_sugar" -> "fstar_pervasives" + "fstar_classical_sugar" -> "fstar_pervasives" + "fstar_classical_sugar" -> "prims" + "fstar_classical_sugar" -> "prims" + "fstar_tactics_bv_lemmas" -> "fstar_uint" + "fstar_tactics_bv_lemmas" -> "fstar_uint" + "fstar_tactics_bv_lemmas" -> "fstar_bv" + "fstar_tactics_bv_lemmas" -> "fstar_bv" + "fstar_tactics_bv_lemmas" -> "fstar_pervasives" + "fstar_tactics_bv_lemmas" -> "fstar_pervasives" + "fstar_tactics_bv_lemmas" -> "prims" + "fstar_tactics_bv_lemmas" -> "prims" + "fstar_tactics_bv_lemmas" -> "fstar_tactics_bv_lemmas" + "fstar_int8" -> "fstar_uint" + "fstar_int8" -> "fstar_uint" + "fstar_int8" -> "fstar_uint32" + "fstar_int8" -> "fstar_uint32" + "fstar_int8" -> "fstar_mul" + "fstar_int8" -> "fstar_mul" + "fstar_int8" -> "fstar_int" + "fstar_int8" -> "fstar_int" + "fstar_int8" -> "fstar_pervasives" + "fstar_int8" -> "fstar_pervasives" + "fstar_int8" -> "prims" + "fstar_int8" -> "prims" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_sha3_neon_x2" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_pervasives_native" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_pervasives_native" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_list_tot" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_list_tot" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_sha3_neon_x2_incremental" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_neon" -> "core" + "libcrux_ml_dsa_hash_functions_neon" -> "core" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_neon" -> "prims" + "libcrux_ml_dsa_hash_functions_neon" -> "prims" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_neon" + "libcrux_ml_dsa_ml_dsa_44_" -> "core_result" + "libcrux_ml_dsa_ml_dsa_44_" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44_" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_44_" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_ml_dsa_44_" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44_" -> "core" + "libcrux_ml_dsa_ml_dsa_44_" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44_" -> "prims" + "libcrux_ml_dsa_ml_dsa_87_" -> "core_result" + "libcrux_ml_dsa_ml_dsa_87_" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_87_" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_87_" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_ml_dsa_87_" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_87_" -> "core" + "libcrux_ml_dsa_ml_dsa_87_" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_87_" -> "prims" + "fstar_tactics_unseal" -> "fstar_tactics_effect" + "fstar_tactics_unseal" -> "fstar_tactics_effect" + "fstar_tactics_unseal" -> "fstar_sealed" + "fstar_tactics_unseal" -> "fstar_pervasives" + "fstar_tactics_unseal" -> "fstar_pervasives" + "fstar_tactics_unseal" -> "prims" + "fstar_tactics_unseal" -> "prims" + "libcrux_ml_dsa_pre_hash" -> "core_result" + "libcrux_ml_dsa_pre_hash" -> "core_result" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_pre_hash" -> "core_slice" + "libcrux_ml_dsa_pre_hash" -> "core_option" + "libcrux_ml_dsa_pre_hash" -> "core_option" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_pre_hash" -> "fstar_mul" + "libcrux_ml_dsa_pre_hash" -> "fstar_mul" + "libcrux_ml_dsa_pre_hash" -> "core" + "libcrux_ml_dsa_pre_hash" -> "core" + "libcrux_ml_dsa_pre_hash" -> "fstar_pervasives" + "libcrux_ml_dsa_pre_hash" -> "fstar_pervasives" + "libcrux_ml_dsa_pre_hash" -> "prims" + "libcrux_ml_dsa_pre_hash" -> "prims" + "libcrux_ml_dsa_pre_hash" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "prims" + "fstar_bv" -> "fstar_math_lemmas" + "fstar_bv" -> "fstar_math_lemmas" + "fstar_bv" -> "fstar_seq" + "fstar_bv" -> "fstar_seq" + "fstar_bv" -> "fstar_bitvector" + "fstar_bv" -> "fstar_bitvector" + "fstar_bv" -> "fstar_uint" + "fstar_bv" -> "fstar_uint" + "fstar_bv" -> "fstar_pervasives" + "fstar_bv" -> "fstar_pervasives" + "fstar_bv" -> "prims" + "fstar_bv" -> "prims" + "fstar_bv" -> "fstar_bv" + "fstar_pervasives_native" -> "prims" + "fstar_pervasives_native" -> "prims" + "libcrux_ml_dsa_encoding_gamma1" -> "core_ops_range" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_gamma1" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_gamma1" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_gamma1" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_gamma1" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_gamma1" -> "core_option" + "libcrux_ml_dsa_encoding_gamma1" -> "core_option" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_gamma1" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_gamma1" -> "core_panicking" + "libcrux_ml_dsa_encoding_gamma1" -> "core_panicking" + "libcrux_ml_dsa_encoding_gamma1" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_gamma1" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_gamma1" -> "core_slice" + "libcrux_ml_dsa_encoding_gamma1" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_gamma1" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_encoding_gamma1" -> "core" + "libcrux_ml_dsa_encoding_gamma1" -> "core" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_gamma1" -> "prims" + "libcrux_ml_dsa_encoding_gamma1" -> "prims" + "libcrux_ml_dsa_encoding_gamma1" -> "libcrux_ml_dsa_encoding_gamma1" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_87__avx2" -> "libcrux_ml_dsa_ml_dsa_87__avx2" + "fstar_list_tot_base" -> "fstar_classical_sugar" + "fstar_list_tot_base" -> "fstar_classical_sugar" + "fstar_list_tot_base" -> "fstar_pervasives_native" + "fstar_list_tot_base" -> "fstar_pervasives_native" + "fstar_list_tot_base" -> "fstar_pervasives" + "fstar_list_tot_base" -> "fstar_pervasives" + "fstar_list_tot_base" -> "prims" + "fstar_list_tot_base" -> "prims" + "fstar_option" -> "fstar_pervasives_native" + "fstar_option" -> "fstar_pervasives_native" + "fstar_option" -> "fstar_all" + "fstar_option" -> "fstar_all" + "fstar_option" -> "fstar_pervasives" + "fstar_option" -> "fstar_pervasives" + "fstar_option" -> "prims" + "fstar_option" -> "prims" + "libcrux_ml_dsa_simd_portable_sample" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_sample" -> "core" + "libcrux_ml_dsa_simd_portable_sample" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_sample" -> "prims" + "fstar_reflection_v2_formula" -> "fstar_pervasives_native" + "fstar_reflection_v2_formula" -> "fstar_pervasives_native" + "fstar_reflection_v2_formula" -> "fstar_reflection_termeq_simple" + "fstar_reflection_v2_formula" -> "fstar_reflection_termeq_simple" + "fstar_reflection_v2_formula" -> "fstar_tactics_namedview" + "fstar_reflection_v2_formula" -> "fstar_tactics_namedview" + "fstar_reflection_v2_formula" -> "fstar_stubs_tactics_v2_builtins" + "fstar_reflection_v2_formula" -> "fstar_tactics_effect" + "fstar_reflection_v2_formula" -> "fstar_tactics_effect" + "fstar_reflection_v2_formula" -> "fstar_stubs_tactics_common" + "fstar_reflection_v2_formula" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_v2_formula" -> "fstar_reflection_v2_derived" + "fstar_reflection_v2_formula" -> "fstar_reflection_v2_derived" + "fstar_reflection_v2_formula" -> "fstar_stubs_reflection_v2_builtins" + "fstar_reflection_v2_formula" -> "fstar_reflection_const" + "fstar_reflection_v2_formula" -> "fstar_reflection_const" + "fstar_reflection_v2_formula" -> "fstar_stubs_reflection_types" + "fstar_reflection_v2_formula" -> "fstar_list_tot_base" + "fstar_reflection_v2_formula" -> "fstar_list_tot_base" + "fstar_reflection_v2_formula" -> "fstar_pervasives" + "fstar_reflection_v2_formula" -> "fstar_pervasives" + "fstar_reflection_v2_formula" -> "prims" + "fstar_reflection_v2_formula" -> "prims" + "core_panicking" -> "core_fmt" + "core_panicking" -> "core_option" + "core_panicking" -> "core_option" + "core_panicking" -> "rust_primitives_hax" + "core_panicking" -> "rust_primitives_hax" + "core_panicking" -> "rust_primitives" + "core_panicking" -> "rust_primitives" + "core_panicking" -> "fstar_pervasives" + "core_panicking" -> "fstar_pervasives" + "core_panicking" -> "prims" + "core_panicking" -> "prims" + "fstar_char" -> "fstar_uint32" + "fstar_char" -> "fstar_uint32" + "fstar_char" -> "fstar_pervasives" + "fstar_char" -> "fstar_pervasives" + "fstar_char" -> "prims" + "fstar_char" -> "prims" + "fstar_tactics_mapply" -> "fstar_squash" + "fstar_tactics_mapply" -> "fstar_squash" + "fstar_tactics_mapply" -> "fstar_tactics_typeclasses" + "fstar_tactics_mapply" -> "fstar_tactics_typeclasses" + "fstar_tactics_mapply" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_mapply" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_mapply" -> "fstar_tactics_v2_derived" + "fstar_tactics_mapply" -> "fstar_tactics_v2_derived" + "fstar_tactics_mapply" -> "fstar_tactics_v2_syntaxhelpers" + "fstar_tactics_mapply" -> "fstar_tactics_v2_syntaxhelpers" + "fstar_tactics_mapply" -> "fstar_tactics_namedview" + "fstar_tactics_mapply" -> "fstar_tactics_namedview" + "fstar_tactics_mapply" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_mapply" -> "fstar_tactics_effect" + "fstar_tactics_mapply" -> "fstar_tactics_effect" + "fstar_tactics_mapply" -> "fstar_reflection_v2_formula" + "fstar_tactics_mapply" -> "fstar_reflection_v2_formula" + "fstar_tactics_mapply" -> "fstar_reflection_v2" + "fstar_tactics_mapply" -> "fstar_reflection_v2" + "fstar_tactics_mapply" -> "fstar_pervasives" + "fstar_tactics_mapply" -> "fstar_pervasives" + "fstar_tactics_mapply" -> "prims" + "fstar_tactics_mapply" -> "prims" + "fstar_tactics_mapply" -> "fstar_tactics_mapply" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_error" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_error" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_encoding_error" -> "core" + "libcrux_ml_dsa_encoding_error" -> "core" + "libcrux_ml_dsa_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_error" -> "prims" + "libcrux_ml_dsa_encoding_error" -> "prims" + "lib_loopcombinators" -> "fstar_tactics_effect" + "lib_loopcombinators" -> "fstar_tactics_effect" + "lib_loopcombinators" -> "fstar_propositionalextensionality" + "lib_loopcombinators" -> "fstar_propositionalextensionality" + "lib_loopcombinators" -> "fstar_tactics" + "lib_loopcombinators" -> "fstar_tactics" + "lib_loopcombinators" -> "fstar_pervasives" + "lib_loopcombinators" -> "fstar_pervasives" + "lib_loopcombinators" -> "prims" + "lib_loopcombinators" -> "prims" + "lib_loopcombinators" -> "lib_loopcombinators" + "fstar_seq_base" -> "fstar_list_tot" + "fstar_seq_base" -> "fstar_list_tot" + "fstar_seq_base" -> "fstar_pervasives" + "fstar_seq_base" -> "fstar_pervasives" + "fstar_seq_base" -> "prims" + "fstar_seq_base" -> "prims" + "fstar_uint64" -> "fstar_uint32" + "fstar_uint64" -> "fstar_uint32" + "fstar_uint64" -> "fstar_mul" + "fstar_uint64" -> "fstar_mul" + "fstar_uint64" -> "fstar_uint" + "fstar_uint64" -> "fstar_uint" + "fstar_uint64" -> "fstar_pervasives" + "fstar_uint64" -> "fstar_pervasives" + "fstar_uint64" -> "prims" + "fstar_uint64" -> "prims" + "fstar_classical_sugar" -> "fstar_squash" + "fstar_classical_sugar" -> "fstar_squash" + "fstar_classical_sugar" -> "fstar_pervasives" + "fstar_classical_sugar" -> "fstar_pervasives" + "fstar_classical_sugar" -> "prims" + "fstar_classical_sugar" -> "prims" + "fstar_classical_sugar" -> "fstar_classical_sugar" + "core_result" -> "fstar_pervasives" + "core_result" -> "fstar_pervasives" + "core_result" -> "prims" + "core_result" -> "prims" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_int32" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_int32" + "libcrux_ml_dsa_simd_portable_vector_type" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_portable_vector_type" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core_ops_range" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core_convert" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core_convert" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core_array" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core_array" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core_result" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core_result" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core" + "libcrux_ml_dsa_simd_portable_vector_type" -> "core" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_vector_type" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_vector_type" -> "prims" + "libcrux_ml_dsa_simd_portable_vector_type" -> "prims" + "libcrux_ml_dsa_simd_portable_vector_type" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "prims" + "fstar_exn" -> "fstar_pervasives" + "fstar_exn" -> "fstar_pervasives" + "fstar_exn" -> "prims" + "fstar_exn" -> "prims" + "fstar_reflection_termeq_simple" -> "fstar_stubs_reflection_types" + "fstar_reflection_termeq_simple" -> "fstar_pervasives" + "fstar_reflection_termeq_simple" -> "fstar_pervasives" + "fstar_reflection_termeq_simple" -> "prims" + "fstar_reflection_termeq_simple" -> "prims" + "core_ops" -> "core_ops_index" + "core_ops" -> "core_ops_index" + "core_ops" -> "fstar_tactics_typeclasses" + "core_ops" -> "fstar_tactics_typeclasses" + "core_ops" -> "rust_primitives" + "core_ops" -> "rust_primitives" + "core_ops" -> "fstar_pervasives" + "core_ops" -> "fstar_pervasives" + "core_ops" -> "prims" + "core_ops" -> "prims" + "fstar_tactics_typeclasses" -> "fstar_stubs_reflection_types" + "fstar_tactics_typeclasses" -> "fstar_tactics_effect" + "fstar_tactics_typeclasses" -> "fstar_tactics_effect" + "fstar_tactics_typeclasses" -> "fstar_pervasives" + "fstar_tactics_typeclasses" -> "fstar_pervasives" + "fstar_tactics_typeclasses" -> "prims" + "fstar_tactics_typeclasses" -> "prims" + "fstar_pervasives" -> "fstar_pervasives_native" + "fstar_pervasives" -> "fstar_pervasives_native" + "fstar_pervasives" -> "prims" + "fstar_pervasives" -> "prims" + "libcrux_ml_dsa_utils" -> "fstar_mul" + "libcrux_ml_dsa_utils" -> "fstar_mul" + "libcrux_ml_dsa_utils" -> "core" + "libcrux_ml_dsa_utils" -> "core" + "libcrux_ml_dsa_utils" -> "fstar_pervasives" + "libcrux_ml_dsa_utils" -> "fstar_pervasives" + "libcrux_ml_dsa_utils" -> "prims" + "libcrux_ml_dsa_utils" -> "prims" + "libcrux_sha3_traits" -> "fstar_mul" + "libcrux_sha3_traits" -> "fstar_mul" + "libcrux_sha3_traits" -> "core" + "libcrux_sha3_traits" -> "core" + "libcrux_sha3_traits" -> "fstar_pervasives" + "libcrux_sha3_traits" -> "fstar_pervasives" + "libcrux_sha3_traits" -> "prims" + "libcrux_sha3_traits" -> "prims" + "libcrux_sha3_traits" -> "libcrux_sha3_traits" + "fstar_ghost" -> "fstar_pervasives" + "fstar_ghost" -> "fstar_pervasives" + "fstar_ghost" -> "prims" + "fstar_ghost" -> "prims" + "fstar_list_tot_properties" -> "fstar_classical" + "fstar_list_tot_properties" -> "fstar_classical" + "fstar_list_tot_properties" -> "fstar_classical_sugar" + "fstar_list_tot_properties" -> "fstar_classical_sugar" + "fstar_list_tot_properties" -> "fstar_pervasives_native" + "fstar_list_tot_properties" -> "fstar_pervasives_native" + "fstar_list_tot_properties" -> "fstar_list_tot_base" + "fstar_list_tot_properties" -> "fstar_list_tot_base" + "fstar_list_tot_properties" -> "fstar_pervasives" + "fstar_list_tot_properties" -> "fstar_pervasives" + "fstar_list_tot_properties" -> "prims" + "fstar_list_tot_properties" -> "prims" + "fstar_list_tot_properties" -> "fstar_list_tot_properties" + "fstar_preorder" -> "fstar_pervasives" + "fstar_preorder" -> "fstar_pervasives" + "fstar_preorder" -> "prims" + "fstar_preorder" -> "prims" + "fstar_monotonic_pure" -> "fstar_pervasives" + "fstar_monotonic_pure" -> "fstar_pervasives" + "fstar_monotonic_pure" -> "prims" + "fstar_monotonic_pure" -> "prims" + "fstar_stubs_reflection_v2_data" -> "fstar_sealed_inhabited" + "fstar_stubs_reflection_v2_data" -> "fstar_sealed_inhabited" + "fstar_stubs_reflection_v2_data" -> "fstar_stubs_reflection_types" + "fstar_stubs_reflection_v2_data" -> "fstar_stubs_syntax_syntax" + "fstar_stubs_reflection_v2_data" -> "fstar_pervasives" + "fstar_stubs_reflection_v2_data" -> "fstar_pervasives" + "fstar_stubs_reflection_v2_data" -> "prims" + "fstar_stubs_reflection_v2_data" -> "prims" + "fstar_stubs_tactics_v2_builtins" -> "fstar_issue" + "fstar_stubs_tactics_v2_builtins" -> "fstar_list_tot" + "fstar_stubs_tactics_v2_builtins" -> "fstar_list_tot" + "fstar_stubs_tactics_v2_builtins" -> "fstar_ghost" + "fstar_stubs_tactics_v2_builtins" -> "fstar_ghost" + "fstar_stubs_tactics_v2_builtins" -> "fstar_pervasives_native" + "fstar_stubs_tactics_v2_builtins" -> "fstar_pervasives_native" + "fstar_stubs_tactics_v2_builtins" -> "fstar_stubs_pprint" + "fstar_stubs_tactics_v2_builtins" -> "fstar_tactics_unseal" + "fstar_stubs_tactics_v2_builtins" -> "fstar_stubs_tactics_types" + "fstar_stubs_tactics_v2_builtins" -> "fstar_tactics_effect" + "fstar_stubs_tactics_v2_builtins" -> "fstar_tactics_effect" + "fstar_stubs_tactics_v2_builtins" -> "fstar_stubs_reflection_v2_builtins" + "fstar_stubs_tactics_v2_builtins" -> "fstar_stubs_reflection_v2_data" + "fstar_stubs_tactics_v2_builtins" -> "fstar_reflection_const" + "fstar_stubs_tactics_v2_builtins" -> "fstar_reflection_const" + "fstar_stubs_tactics_v2_builtins" -> "fstar_stubs_reflection_types" + "fstar_stubs_tactics_v2_builtins" -> "fstar_vconfig" + "fstar_stubs_tactics_v2_builtins" -> "fstar_pervasives" + "fstar_stubs_tactics_v2_builtins" -> "fstar_pervasives" + "fstar_stubs_tactics_v2_builtins" -> "prims" + "fstar_stubs_tactics_v2_builtins" -> "prims" + "core_num_error" -> "rust_primitives" + "core_num_error" -> "rust_primitives" + "core_num_error" -> "fstar_pervasives" + "core_num_error" -> "fstar_pervasives" + "core_num_error" -> "prims" + "core_num_error" -> "prims" + "fstar_int_cast_full" -> "fstar_uint128" + "fstar_int_cast_full" -> "fstar_uint128" + "fstar_int_cast_full" -> "fstar_uint64" + "fstar_int_cast_full" -> "fstar_uint64" + "fstar_int_cast_full" -> "fstar_int_cast" + "fstar_int_cast_full" -> "fstar_int_cast" + "fstar_int_cast_full" -> "fstar_pervasives" + "fstar_int_cast_full" -> "fstar_pervasives" + "fstar_int_cast_full" -> "prims" + "fstar_int_cast_full" -> "prims" + "fstar_all" -> "fstar_exn" + "fstar_all" -> "fstar_exn" + "fstar_all" -> "fstar_st" + "fstar_all" -> "fstar_st" + "fstar_all" -> "fstar_heap" + "fstar_all" -> "fstar_heap" + "fstar_all" -> "fstar_pervasives" + "fstar_all" -> "fstar_pervasives" + "fstar_all" -> "prims" + "fstar_all" -> "prims" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "hax_lib" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core_slice" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_uint8" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core_array_iter" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core_iter_traits_collect" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core_fmt_rt" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_list_tot" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core_fmt" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core_panicking" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_uint64" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_int32" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core_ops_arith_neg" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "core" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "prims" + "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" -> "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "core_result" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "core" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "prims" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_encoding_commitment" -> "core" + "libcrux_ml_dsa_encoding_commitment" -> "core" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_commitment" -> "prims" + "libcrux_ml_dsa_encoding_commitment" -> "prims" + "core_convert" -> "rust_primitives_integers" + "core_convert" -> "rust_primitives_integers" + "core_convert" -> "core_slice" + "core_convert" -> "core_array" + "core_convert" -> "core_array" + "core_convert" -> "core_result" + "core_convert" -> "core_result" + "core_convert" -> "fstar_tactics_typeclasses" + "core_convert" -> "fstar_tactics_typeclasses" + "core_convert" -> "rust_primitives" + "core_convert" -> "rust_primitives" + "core_convert" -> "fstar_pervasives" + "core_convert" -> "fstar_pervasives" + "core_convert" -> "prims" + "core_convert" -> "prims" + "libcrux_sha3_portable_incremental" -> "libcrux_sha3_portable" + "libcrux_sha3_portable_incremental" -> "libcrux_sha3_portable" + "libcrux_sha3_portable_incremental" -> "fstar_mul" + "libcrux_sha3_portable_incremental" -> "fstar_mul" + "libcrux_sha3_portable_incremental" -> "core" + "libcrux_sha3_portable_incremental" -> "core" + "libcrux_sha3_portable_incremental" -> "fstar_pervasives" + "libcrux_sha3_portable_incremental" -> "fstar_pervasives" + "libcrux_sha3_portable_incremental" -> "prims" + "libcrux_sha3_portable_incremental" -> "prims" + "fstar_seq_properties" -> "fstar_list_tot_properties" + "fstar_seq_properties" -> "fstar_list_tot_properties" + "fstar_seq_properties" -> "fstar_list_tot_base" + "fstar_seq_properties" -> "fstar_list_tot_base" + "fstar_seq_properties" -> "fstar_list_tot" + "fstar_seq_properties" -> "fstar_list_tot" + "fstar_seq_properties" -> "fstar_pervasives_native" + "fstar_seq_properties" -> "fstar_pervasives_native" + "fstar_seq_properties" -> "fstar_seq_base" + "fstar_seq_properties" -> "fstar_seq_base" + "fstar_seq_properties" -> "fstar_pervasives" + "fstar_seq_properties" -> "fstar_pervasives" + "fstar_seq_properties" -> "prims" + "fstar_seq_properties" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_int16" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_int16" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core_ops_range" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_commitment" -> "libcrux_ml_dsa_simd_avx2_encoding_commitment" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "core" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "prims" + "libcrux_ml_dsa_ml_dsa_87__portable" -> "libcrux_ml_dsa_ml_dsa_87__portable" + "fstar_range" -> "fstar_sealed" + "fstar_range" -> "fstar_pervasives" + "fstar_range" -> "fstar_pervasives" + "fstar_range" -> "prims" + "fstar_range" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_option" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_option" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_sha3_portable_incremental" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic" -> "core" + "libcrux_ml_dsa_ml_dsa_generic" -> "core" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic" -> "prims" + "fstar_squash" -> "fstar_pervasives" + "fstar_squash" -> "fstar_pervasives" + "fstar_squash" -> "prims" + "fstar_squash" -> "prims" + "fstar_squash" -> "fstar_squash" + "fstar_monotonic_heap" -> "fstar_erasedlogic" + "fstar_monotonic_heap" -> "fstar_erasedlogic" + "fstar_monotonic_heap" -> "fstar_squash" + "fstar_monotonic_heap" -> "fstar_squash" + "fstar_monotonic_heap" -> "fstar_set" + "fstar_monotonic_heap" -> "fstar_set" + "fstar_monotonic_heap" -> "fstar_pervasives_native" + "fstar_monotonic_heap" -> "fstar_pervasives_native" + "fstar_monotonic_heap" -> "fstar_functionalextensionality" + "fstar_monotonic_heap" -> "fstar_functionalextensionality" + "fstar_monotonic_heap" -> "fstar_classical" + "fstar_monotonic_heap" -> "fstar_classical" + "fstar_monotonic_heap" -> "fstar_preorder" + "fstar_monotonic_heap" -> "fstar_preorder" + "fstar_monotonic_heap" -> "fstar_pervasives" + "fstar_monotonic_heap" -> "fstar_pervasives" + "fstar_monotonic_heap" -> "prims" + "fstar_monotonic_heap" -> "prims" + "fstar_monotonic_heap" -> "fstar_monotonic_heap" + "fstar_stubs_tactics_v1_builtins" -> "fstar_tactics_unseal" + "fstar_stubs_tactics_v1_builtins" -> "fstar_stubs_tactics_types" + "fstar_stubs_tactics_v1_builtins" -> "fstar_tactics_effect" + "fstar_stubs_tactics_v1_builtins" -> "fstar_tactics_effect" + "fstar_stubs_tactics_v1_builtins" -> "fstar_reflection_const" + "fstar_stubs_tactics_v1_builtins" -> "fstar_reflection_const" + "fstar_stubs_tactics_v1_builtins" -> "fstar_stubs_reflection_v1_data" + "fstar_stubs_tactics_v1_builtins" -> "fstar_stubs_reflection_types" + "fstar_stubs_tactics_v1_builtins" -> "fstar_stubs_reflection_v1_builtins" + "fstar_stubs_tactics_v1_builtins" -> "fstar_vconfig" + "fstar_stubs_tactics_v1_builtins" -> "fstar_pervasives" + "fstar_stubs_tactics_v1_builtins" -> "fstar_pervasives" + "fstar_stubs_tactics_v1_builtins" -> "prims" + "fstar_stubs_tactics_v1_builtins" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_int64" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_int64" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_panicking" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_ops_range" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core_slice" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_gamma1" -> "libcrux_ml_dsa_simd_avx2_encoding_gamma1" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "core_result" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "core_result" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_ml_dsa_generic" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_hash_functions_neon" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" + "bitvec_intrinsics" -> "fstar_string" + "bitvec_intrinsics" -> "fstar_tactics_v2_derived" + "bitvec_intrinsics" -> "fstar_tactics_v2_derived" + "bitvec_intrinsics" -> "fstar_stubs_tactics_v2_builtins" + "bitvec_intrinsics" -> "fstar_int8" + "bitvec_intrinsics" -> "fstar_int8" + "bitvec_intrinsics" -> "fstar_uint8" + "bitvec_intrinsics" -> "fstar_uint8" + "bitvec_intrinsics" -> "fstar_list_tot" + "bitvec_intrinsics" -> "fstar_list_tot" + "bitvec_intrinsics" -> "fstar_tactics_v2" + "bitvec_intrinsics" -> "fstar_tactics_v2" + "bitvec_intrinsics" -> "fstar_int16" + "bitvec_intrinsics" -> "fstar_int16" + "bitvec_intrinsics" -> "fstar_tactics" + "bitvec_intrinsics" -> "fstar_tactics" + "bitvec_intrinsics" -> "fstar_seq" + "bitvec_intrinsics" -> "fstar_seq" + "bitvec_intrinsics" -> "fstar_int32" + "bitvec_intrinsics" -> "fstar_int32" + "bitvec_intrinsics" -> "tactics_utils" + "bitvec_intrinsics" -> "tactics_utils" + "bitvec_intrinsics" -> "bitvec_equality" + "bitvec_intrinsics" -> "bitvec_equality" + "bitvec_intrinsics" -> "bitvec_utils" + "bitvec_intrinsics" -> "bitvec_utils" + "bitvec_intrinsics" -> "fstar_mul" + "bitvec_intrinsics" -> "fstar_mul" + "bitvec_intrinsics" -> "rust_primitives" + "bitvec_intrinsics" -> "rust_primitives" + "bitvec_intrinsics" -> "core" + "bitvec_intrinsics" -> "core" + "bitvec_intrinsics" -> "fstar_pervasives" + "bitvec_intrinsics" -> "fstar_pervasives" + "bitvec_intrinsics" -> "prims" + "bitvec_intrinsics" -> "prims" + "core_ops_arith_neg" -> "rust_primitives" + "core_ops_arith_neg" -> "rust_primitives" + "core_ops_arith_neg" -> "fstar_pervasives" + "core_ops_arith_neg" -> "fstar_pervasives" + "core_ops_arith_neg" -> "prims" + "core_ops_arith_neg" -> "prims" + "libcrux_ml_dsa_arithmetic" -> "fstar_int32" + "libcrux_ml_dsa_arithmetic" -> "fstar_int32" + "libcrux_ml_dsa_arithmetic" -> "core_slice_iter" + "libcrux_ml_dsa_arithmetic" -> "core_slice_iter" + "libcrux_ml_dsa_arithmetic" -> "core_iter_traits_collect" + "libcrux_ml_dsa_arithmetic" -> "core_iter_traits_collect" + "libcrux_ml_dsa_arithmetic" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_arithmetic" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_arithmetic" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_arithmetic" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_arithmetic" -> "core_slice" + "libcrux_ml_dsa_arithmetic" -> "fstar_pervasives_native" + "libcrux_ml_dsa_arithmetic" -> "fstar_pervasives_native" + "libcrux_ml_dsa_arithmetic" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_arithmetic" -> "rust_primitives_hax" + "libcrux_ml_dsa_arithmetic" -> "rust_primitives_hax" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_arithmetic" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_arithmetic" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_arithmetic" -> "core" + "libcrux_ml_dsa_arithmetic" -> "core" + "libcrux_ml_dsa_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_arithmetic" -> "prims" + "libcrux_ml_dsa_arithmetic" -> "prims" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_arithmetic" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" + "fstar_uint128" -> "fstar_pervasives_native" + "fstar_uint128" -> "fstar_pervasives_native" + "fstar_uint128" -> "fstar_int_cast" + "fstar_uint128" -> "fstar_int_cast" + "fstar_uint128" -> "fstar_calc" + "fstar_uint128" -> "fstar_calc" + "fstar_uint128" -> "fstar_classical_sugar" + "fstar_uint128" -> "fstar_classical_sugar" + "fstar_uint128" -> "fstar_tactics_bv_lemmas" + "fstar_uint128" -> "fstar_tactics_bv_lemmas" + "fstar_uint128" -> "fstar_tactics_bv" + "fstar_uint128" -> "fstar_tactics_bv" + "fstar_uint128" -> "fstar_tactics_effect" + "fstar_uint128" -> "fstar_tactics_effect" + "fstar_uint128" -> "fstar_tactics_mapply" + "fstar_uint128" -> "fstar_tactics_mapply" + "fstar_uint128" -> "fstar_tactics_v2_derived" + "fstar_uint128" -> "fstar_tactics_v2_derived" + "fstar_uint128" -> "fstar_stubs_tactics_v2_builtins" + "fstar_uint128" -> "fstar_bv" + "fstar_uint128" -> "fstar_bv" + "fstar_uint128" -> "fstar_math_lemmas" + "fstar_uint128" -> "fstar_math_lemmas" + "fstar_uint128" -> "fstar_uint64" + "fstar_uint128" -> "fstar_uint64" + "fstar_uint128" -> "fstar_uint32" + "fstar_uint128" -> "fstar_uint32" + "fstar_uint128" -> "fstar_bitvector" + "fstar_uint128" -> "fstar_bitvector" + "fstar_uint128" -> "fstar_seq" + "fstar_uint128" -> "fstar_seq" + "fstar_uint128" -> "fstar_uint" + "fstar_uint128" -> "fstar_uint" + "fstar_uint128" -> "fstar_mul" + "fstar_uint128" -> "fstar_mul" + "fstar_uint128" -> "fstar_pervasives" + "fstar_uint128" -> "fstar_pervasives" + "fstar_uint128" -> "prims" + "fstar_uint128" -> "prims" + "fstar_uint128" -> "fstar_uint128" + "fstar_tactics_v1_derived" -> "fstar_propositionalextensionality" + "fstar_tactics_v1_derived" -> "fstar_propositionalextensionality" + "fstar_tactics_v1_derived" -> "fstar_squash" + "fstar_tactics_v1_derived" -> "fstar_squash" + "fstar_tactics_v1_derived" -> "fstar_range" + "fstar_tactics_v1_derived" -> "fstar_pervasives_native" + "fstar_tactics_v1_derived" -> "fstar_pervasives_native" + "fstar_tactics_v1_derived" -> "fstar_tactics_visit" + "fstar_tactics_v1_derived" -> "fstar_tactics_visit" + "fstar_tactics_v1_derived" -> "fstar_list_tot_base" + "fstar_tactics_v1_derived" -> "fstar_list_tot_base" + "fstar_tactics_v1_derived" -> "fstar_tactics_names" + "fstar_tactics_v1_derived" -> "fstar_tactics_names" + "fstar_tactics_v1_derived" -> "fstar_vconfig" + "fstar_tactics_v1_derived" -> "fstar_tactics_v1_syntaxhelpers" + "fstar_tactics_v1_derived" -> "fstar_tactics_v1_syntaxhelpers" + "fstar_tactics_v1_derived" -> "fstar_stubs_tactics_v1_builtins" + "fstar_tactics_v1_derived" -> "fstar_tactics_util" + "fstar_tactics_v1_derived" -> "fstar_tactics_util" + "fstar_tactics_v1_derived" -> "fstar_stubs_tactics_result" + "fstar_tactics_v1_derived" -> "fstar_stubs_tactics_types" + "fstar_tactics_v1_derived" -> "fstar_tactics_effect" + "fstar_tactics_v1_derived" -> "fstar_tactics_effect" + "fstar_tactics_v1_derived" -> "fstar_reflection_v1_formula" + "fstar_tactics_v1_derived" -> "fstar_reflection_v1_formula" + "fstar_tactics_v1_derived" -> "fstar_reflection_v1" + "fstar_tactics_v1_derived" -> "fstar_reflection_v1" + "fstar_tactics_v1_derived" -> "fstar_pervasives" + "fstar_tactics_v1_derived" -> "fstar_pervasives" + "fstar_tactics_v1_derived" -> "prims" + "fstar_tactics_v1_derived" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_ml_dsa_generic" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_hash_functions_portable" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" + "libcrux_ml_dsa_hash_functions_shake128" -> "rust_primitives" + "libcrux_ml_dsa_hash_functions_shake128" -> "rust_primitives" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_shake128" -> "core" + "libcrux_ml_dsa_hash_functions_shake128" -> "core" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_shake128" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_shake128" -> "prims" + "libcrux_ml_dsa_hash_functions_shake128" -> "prims" + "libcrux_ml_dsa_hash_functions_shake128" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_neon" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "core" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "prims" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "libcrux_ml_dsa_ml_dsa_87__neon" + "fstar_tactics_typeclasses" -> "fstar_stubs_pprint" + "fstar_tactics_typeclasses" -> "fstar_list_tot" + "fstar_tactics_typeclasses" -> "fstar_list_tot" + "fstar_tactics_typeclasses" -> "fstar_tactics_util" + "fstar_tactics_typeclasses" -> "fstar_tactics_util" + "fstar_tactics_typeclasses" -> "fstar_reflection_termeq_simple" + "fstar_tactics_typeclasses" -> "fstar_reflection_termeq_simple" + "fstar_tactics_typeclasses" -> "fstar_pervasives_native" + "fstar_tactics_typeclasses" -> "fstar_pervasives_native" + "fstar_tactics_typeclasses" -> "fstar_stubs_reflection_v2_builtins" + "fstar_tactics_typeclasses" -> "fstar_list_tot_base" + "fstar_tactics_typeclasses" -> "fstar_list_tot_base" + "fstar_tactics_typeclasses" -> "fstar_tactics_namedview" + "fstar_tactics_typeclasses" -> "fstar_tactics_namedview" + "fstar_tactics_typeclasses" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_typeclasses" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_typeclasses" -> "fstar_tactics_v2_derived" + "fstar_tactics_typeclasses" -> "fstar_tactics_v2_derived" + "fstar_tactics_typeclasses" -> "fstar_tactics_v2_syntaxhelpers" + "fstar_tactics_typeclasses" -> "fstar_tactics_v2_syntaxhelpers" + "fstar_tactics_typeclasses" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_typeclasses" -> "fstar_tactics_effect" + "fstar_tactics_typeclasses" -> "fstar_tactics_effect" + "fstar_tactics_typeclasses" -> "fstar_stubs_tactics_common" + "fstar_tactics_typeclasses" -> "fstar_reflection_v2" + "fstar_tactics_typeclasses" -> "fstar_reflection_v2" + "fstar_tactics_typeclasses" -> "fstar_pervasives" + "fstar_tactics_typeclasses" -> "fstar_pervasives" + "fstar_tactics_typeclasses" -> "prims" + "fstar_tactics_typeclasses" -> "prims" + "fstar_tactics_typeclasses" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_list_tot" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_list_tot" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" -> "prims" + "core_num" -> "fstar_tactics_typeclasses" + "core_num" -> "fstar_tactics_typeclasses" + "core_num" -> "core_ops_arith" + "core_num" -> "core_num_error" + "core_num" -> "core_result" + "core_num" -> "core_result" + "core_num" -> "fstar_math_lemmas" + "core_num" -> "fstar_math_lemmas" + "core_num" -> "lib_inttypes" + "core_num" -> "lib_inttypes" + "core_num" -> "fstar_uint128" + "core_num" -> "fstar_uint128" + "core_num" -> "fstar_uint32" + "core_num" -> "fstar_uint32" + "core_num" -> "rust_primitives" + "core_num" -> "rust_primitives" + "core_num" -> "fstar_pervasives" + "core_num" -> "fstar_pervasives" + "core_num" -> "prims" + "core_num" -> "prims" + "fstar_tactics_v1_logic" -> "fstar_pervasives_native" + "fstar_tactics_v1_logic" -> "fstar_pervasives_native" + "fstar_tactics_v1_logic" -> "fstar_squash" + "fstar_tactics_v1_logic" -> "fstar_squash" + "fstar_tactics_v1_logic" -> "fstar_tactics_v1_logic_lemmas" + "fstar_tactics_v1_logic" -> "fstar_tactics_v1_logic_lemmas" + "fstar_tactics_v1_logic" -> "fstar_reflection_v1_formula" + "fstar_tactics_v1_logic" -> "fstar_reflection_v1_formula" + "fstar_tactics_v1_logic" -> "fstar_reflection_v1" + "fstar_tactics_v1_logic" -> "fstar_reflection_v1" + "fstar_tactics_v1_logic" -> "fstar_tactics_util" + "fstar_tactics_v1_logic" -> "fstar_tactics_util" + "fstar_tactics_v1_logic" -> "fstar_tactics_v1_derived" + "fstar_tactics_v1_logic" -> "fstar_tactics_v1_derived" + "fstar_tactics_v1_logic" -> "fstar_stubs_tactics_v1_builtins" + "fstar_tactics_v1_logic" -> "fstar_tactics_effect" + "fstar_tactics_v1_logic" -> "fstar_tactics_effect" + "fstar_tactics_v1_logic" -> "fstar_pervasives" + "fstar_tactics_v1_logic" -> "fstar_pervasives" + "fstar_tactics_v1_logic" -> "prims" + "fstar_tactics_v1_logic" -> "prims" + "fstar_tactics_v1_logic" -> "fstar_tactics_v1_logic" + "fstar_classical" -> "fstar_pervasives" + "fstar_classical" -> "fstar_pervasives" + "fstar_classical" -> "prims" + "fstar_classical" -> "prims" + "fstar_int128" -> "fstar_int64" + "fstar_int128" -> "fstar_int64" + "fstar_int128" -> "fstar_uint32" + "fstar_int128" -> "fstar_uint32" + "fstar_int128" -> "fstar_math_lemmas" + "fstar_int128" -> "fstar_math_lemmas" + "fstar_int128" -> "fstar_mul" + "fstar_int128" -> "fstar_mul" + "fstar_int128" -> "fstar_int" + "fstar_int128" -> "fstar_int" + "fstar_int128" -> "fstar_pervasives" + "fstar_int128" -> "fstar_pervasives" + "fstar_int128" -> "prims" + "fstar_int128" -> "prims" + "fstar_int128" -> "fstar_int128" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_uint8" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_uint8" + "libcrux_ml_dsa_hash_functions_portable" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_portable" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_pervasives_native" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_pervasives_native" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_sha3_portable_incremental" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_sha3_portable" + "libcrux_ml_dsa_hash_functions_portable" -> "libcrux_sha3_portable" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_portable" -> "core" + "libcrux_ml_dsa_hash_functions_portable" -> "core" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_portable" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_portable" -> "prims" + "libcrux_ml_dsa_hash_functions_portable" -> "prims" + "libcrux_ml_dsa_simd_avx2" -> "core_array" + "libcrux_ml_dsa_simd_avx2" -> "core_array" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_ntt" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_ntt" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_t1" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_t1" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_t0" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_t0" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_error" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_error" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_commitment" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_commitment" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_gamma1" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_encoding_gamma1" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" + "libcrux_ml_dsa_simd_avx2" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_arithmetic" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_arithmetic" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2" -> "core_convert" + "libcrux_ml_dsa_simd_avx2" -> "core_convert" + "libcrux_ml_dsa_simd_avx2" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_vector_type" + "libcrux_ml_dsa_simd_avx2" -> "libcrux_ml_dsa_simd_avx2_vector_type" + "libcrux_ml_dsa_simd_avx2" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2" -> "core" + "libcrux_ml_dsa_simd_avx2" -> "core" + "libcrux_ml_dsa_simd_avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2" -> "prims" + "libcrux_ml_dsa_simd_avx2" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core_slice" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core_convert" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core_array" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core_result" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core_ops_range" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "core" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "prims" + "libcrux_ml_dsa_simd_avx2_encoding_t1" -> "libcrux_ml_dsa_simd_avx2_encoding_t1" + "libcrux_ml_dsa_hash_functions_shake256" -> "rust_primitives" + "libcrux_ml_dsa_hash_functions_shake256" -> "rust_primitives" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_shake256" -> "core" + "libcrux_ml_dsa_hash_functions_shake256" -> "core" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_shake256" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_shake256" -> "prims" + "libcrux_ml_dsa_hash_functions_shake256" -> "prims" + "libcrux_ml_dsa_hash_functions_shake256" -> "libcrux_ml_dsa_hash_functions_shake256" + "fstar_tactics_v1_logic_lemmas" -> "fstar_squash" + "fstar_tactics_v1_logic_lemmas" -> "fstar_squash" + "fstar_tactics_v1_logic_lemmas" -> "fstar_indefinitedescription" + "fstar_tactics_v1_logic_lemmas" -> "fstar_indefinitedescription" + "fstar_tactics_v1_logic_lemmas" -> "fstar_classical" + "fstar_tactics_v1_logic_lemmas" -> "fstar_classical" + "fstar_tactics_v1_logic_lemmas" -> "fstar_pervasives" + "fstar_tactics_v1_logic_lemmas" -> "fstar_pervasives" + "fstar_tactics_v1_logic_lemmas" -> "prims" + "fstar_tactics_v1_logic_lemmas" -> "prims" + "fstar_tactics_v1_logic_lemmas" -> "fstar_tactics_v1_logic_lemmas" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_t0" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_t0" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_t0" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_encoding_t0" -> "core" + "libcrux_ml_dsa_encoding_t0" -> "core" + "libcrux_ml_dsa_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_t0" -> "prims" + "libcrux_ml_dsa_encoding_t0" -> "prims" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "core" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "core" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "prims" + "libcrux_ml_dsa_simd_avx2_arithmetic" -> "prims" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_sample" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_sample" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_sample" -> "fstar_mul" + "libcrux_ml_dsa_sample" -> "fstar_mul" + "libcrux_ml_dsa_sample" -> "core" + "libcrux_ml_dsa_sample" -> "core" + "libcrux_ml_dsa_sample" -> "fstar_pervasives" + "libcrux_ml_dsa_sample" -> "fstar_pervasives" + "libcrux_ml_dsa_sample" -> "prims" + "libcrux_ml_dsa_sample" -> "prims" + "fstar_sealed" -> "fstar_pervasives" + "fstar_sealed" -> "fstar_pervasives" + "fstar_sealed" -> "prims" + "fstar_sealed" -> "prims" + "fstar_vconfig" -> "fstar_pervasives" + "fstar_vconfig" -> "fstar_pervasives" + "fstar_vconfig" -> "prims" + "fstar_vconfig" -> "prims" + "libcrux_intrinsics_avx2_extract" -> "core_slice" + "libcrux_intrinsics_avx2_extract" -> "bitvec_intrinsics" + "libcrux_intrinsics_avx2_extract" -> "fstar_int32" + "libcrux_intrinsics_avx2_extract" -> "fstar_int32" + "libcrux_intrinsics_avx2_extract" -> "spec_utils" + "libcrux_intrinsics_avx2_extract" -> "spec_utils" + "libcrux_intrinsics_avx2_extract" -> "fstar_seq" + "libcrux_intrinsics_avx2_extract" -> "fstar_seq" + "libcrux_intrinsics_avx2_extract" -> "fstar_mul" + "libcrux_intrinsics_avx2_extract" -> "fstar_mul" + "libcrux_intrinsics_avx2_extract" -> "core" + "libcrux_intrinsics_avx2_extract" -> "core" + "libcrux_intrinsics_avx2_extract" -> "fstar_pervasives" + "libcrux_intrinsics_avx2_extract" -> "fstar_pervasives" + "libcrux_intrinsics_avx2_extract" -> "prims" + "libcrux_intrinsics_avx2_extract" -> "prims" + "fstar_seq_properties" -> "fstar_list_tot_properties" + "fstar_seq_properties" -> "fstar_list_tot_properties" + "fstar_seq_properties" -> "fstar_list_tot_base" + "fstar_seq_properties" -> "fstar_list_tot_base" + "fstar_seq_properties" -> "fstar_squash" + "fstar_seq_properties" -> "fstar_squash" + "fstar_seq_properties" -> "fstar_list_tot" + "fstar_seq_properties" -> "fstar_list_tot" + "fstar_seq_properties" -> "fstar_pervasives_native" + "fstar_seq_properties" -> "fstar_pervasives_native" + "fstar_seq_properties" -> "fstar_classical" + "fstar_seq_properties" -> "fstar_classical" + "fstar_seq_properties" -> "fstar_seq_base" + "fstar_seq_properties" -> "fstar_seq_base" + "fstar_seq_properties" -> "fstar_pervasives" + "fstar_seq_properties" -> "fstar_pervasives" + "fstar_seq_properties" -> "prims" + "fstar_seq_properties" -> "prims" + "fstar_seq_properties" -> "fstar_seq_properties" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_t0" -> "prims" + "core_iter_adapters_enumerate" -> "rust_primitives" + "core_iter_adapters_enumerate" -> "rust_primitives" + "core_iter_adapters_enumerate" -> "fstar_pervasives" + "core_iter_adapters_enumerate" -> "fstar_pervasives" + "core_iter_adapters_enumerate" -> "prims" + "core_iter_adapters_enumerate" -> "prims" + "core_ops_index" -> "fstar_tactics_typeclasses" + "core_ops_index" -> "fstar_tactics_typeclasses" + "core_ops_index" -> "fstar_pervasives" + "core_ops_index" -> "fstar_pervasives" + "core_ops_index" -> "prims" + "core_ops_index" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "core" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "libcrux_ml_dsa_ml_dsa_44__portable" + "fstar_float" -> "fstar_pervasives" + "fstar_float" -> "fstar_pervasives" + "fstar_float" -> "prims" + "fstar_float" -> "prims" + "bitvec_equality" -> "fstar_functionalextensionality" + "bitvec_equality" -> "fstar_functionalextensionality" + "bitvec_equality" -> "fstar_mul" + "bitvec_equality" -> "fstar_mul" + "bitvec_equality" -> "rust_primitives" + "bitvec_equality" -> "rust_primitives" + "bitvec_equality" -> "core" + "bitvec_equality" -> "core" + "bitvec_equality" -> "fstar_pervasives" + "bitvec_equality" -> "fstar_pervasives" + "bitvec_equality" -> "prims" + "bitvec_equality" -> "prims" + "bitvec_equality" -> "bitvec_equality" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "prims" + "rust_primitives_hax_monomorphized_update_at" -> "core_ops_range" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives_hax" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives_hax" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives" + "rust_primitives_hax_monomorphized_update_at" -> "fstar_pervasives" + "rust_primitives_hax_monomorphized_update_at" -> "fstar_pervasives" + "rust_primitives_hax_monomorphized_update_at" -> "prims" + "rust_primitives_hax_monomorphized_update_at" -> "prims" + "rust_primitives_hax_monomorphized_update_at" -> "rust_primitives_hax_monomorphized_update_at" + "fstar_tactics_v2" -> "fstar_reflection_termeq_simple" + "fstar_tactics_v2" -> "fstar_reflection_termeq_simple" + "fstar_tactics_v2" -> "fstar_tactics_smt" + "fstar_tactics_v2" -> "fstar_tactics_smt" + "fstar_tactics_v2" -> "fstar_tactics_mapply" + "fstar_tactics_v2" -> "fstar_tactics_mapply" + "fstar_tactics_v2" -> "fstar_tactics_namedview" + "fstar_tactics_v2" -> "fstar_tactics_namedview" + "fstar_tactics_v2" -> "fstar_tactics_visit" + "fstar_tactics_v2" -> "fstar_tactics_visit" + "fstar_tactics_v2" -> "fstar_tactics_print" + "fstar_tactics_v2" -> "fstar_tactics_print" + "fstar_tactics_v2" -> "fstar_tactics_util" + "fstar_tactics_v2" -> "fstar_tactics_util" + "fstar_tactics_v2" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_v2" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_v2" -> "fstar_tactics_v2_logic" + "fstar_tactics_v2" -> "fstar_tactics_v2_logic" + "fstar_tactics_v2" -> "fstar_tactics_v2_syntaxhelpers" + "fstar_tactics_v2" -> "fstar_tactics_v2_syntaxhelpers" + "fstar_tactics_v2" -> "fstar_tactics_v2_derived" + "fstar_tactics_v2" -> "fstar_tactics_v2_derived" + "fstar_tactics_v2" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_v2" -> "fstar_tactics_effect" + "fstar_tactics_v2" -> "fstar_tactics_effect" + "fstar_tactics_v2" -> "fstar_stubs_tactics_types" + "fstar_tactics_v2" -> "fstar_reflection_v2_formula" + "fstar_tactics_v2" -> "fstar_reflection_v2_formula" + "fstar_tactics_v2" -> "fstar_reflection_v2" + "fstar_tactics_v2" -> "fstar_reflection_v2" + "fstar_tactics_v2" -> "fstar_stubs_reflection_types" + "fstar_tactics_v2" -> "fstar_pervasives" + "fstar_tactics_v2" -> "fstar_pervasives" + "fstar_tactics_v2" -> "prims" + "fstar_tactics_v2" -> "prims" + "fstar_int32" -> "fstar_uint32" + "fstar_int32" -> "fstar_uint32" + "fstar_int32" -> "fstar_math_lemmas" + "fstar_int32" -> "fstar_math_lemmas" + "fstar_int32" -> "fstar_mul" + "fstar_int32" -> "fstar_mul" + "fstar_int32" -> "fstar_int" + "fstar_int32" -> "fstar_int" + "fstar_int32" -> "fstar_pervasives" + "fstar_int32" -> "fstar_pervasives" + "fstar_int32" -> "prims" + "fstar_int32" -> "prims" + "fstar_int32" -> "fstar_int32" + "fstar_reflection_v2_derived" -> "fstar_list_tot_base" + "fstar_reflection_v2_derived" -> "fstar_list_tot_base" + "fstar_reflection_v2_derived" -> "fstar_pervasives_native" + "fstar_reflection_v2_derived" -> "fstar_pervasives_native" + "fstar_reflection_v2_derived" -> "fstar_list_tot" + "fstar_reflection_v2_derived" -> "fstar_list_tot" + "fstar_reflection_v2_derived" -> "fstar_reflection_v2_collect" + "fstar_reflection_v2_derived" -> "fstar_reflection_v2_collect" + "fstar_reflection_v2_derived" -> "fstar_vconfig" + "fstar_reflection_v2_derived" -> "fstar_order" + "fstar_reflection_v2_derived" -> "fstar_order" + "fstar_reflection_v2_derived" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_v2_derived" -> "fstar_stubs_reflection_v2_builtins" + "fstar_reflection_v2_derived" -> "fstar_reflection_const" + "fstar_reflection_v2_derived" -> "fstar_reflection_const" + "fstar_reflection_v2_derived" -> "fstar_stubs_reflection_types" + "fstar_reflection_v2_derived" -> "fstar_pervasives" + "fstar_reflection_v2_derived" -> "fstar_pervasives" + "fstar_reflection_v2_derived" -> "prims" + "fstar_reflection_v2_derived" -> "prims" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_t1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_t1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_encoding_t1" -> "core" + "libcrux_ml_dsa_encoding_t1" -> "core" + "libcrux_ml_dsa_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_t1" -> "prims" + "libcrux_ml_dsa_encoding_t1" -> "prims" + "fstar_uint32" -> "fstar_mul" + "fstar_uint32" -> "fstar_mul" + "fstar_uint32" -> "fstar_uint" + "fstar_uint32" -> "fstar_uint" + "fstar_uint32" -> "fstar_pervasives" + "fstar_uint32" -> "fstar_pervasives" + "fstar_uint32" -> "prims" + "fstar_uint32" -> "prims" + "fstar_tactics_v2_syntaxcoercions" -> "fstar_sealed" + "fstar_tactics_v2_syntaxcoercions" -> "fstar_tactics_namedview" + "fstar_tactics_v2_syntaxcoercions" -> "fstar_tactics_namedview" + "fstar_tactics_v2_syntaxcoercions" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_v2_syntaxcoercions" -> "fstar_pervasives" + "fstar_tactics_v2_syntaxcoercions" -> "fstar_pervasives" + "fstar_tactics_v2_syntaxcoercions" -> "prims" + "fstar_tactics_v2_syntaxcoercions" -> "prims" + "fstar_monotonic_heap" -> "fstar_preorder" + "fstar_monotonic_heap" -> "fstar_preorder" + "fstar_monotonic_heap" -> "fstar_tset" + "fstar_monotonic_heap" -> "fstar_tset" + "fstar_monotonic_heap" -> "fstar_set" + "fstar_monotonic_heap" -> "fstar_set" + "fstar_monotonic_heap" -> "fstar_pervasives" + "fstar_monotonic_heap" -> "fstar_pervasives" + "fstar_monotonic_heap" -> "prims" + "fstar_monotonic_heap" -> "prims" + "fstar_stubs_tactics_common" -> "fstar_range" + "fstar_stubs_tactics_common" -> "fstar_stubs_errors_msg" + "fstar_stubs_tactics_common" -> "fstar_pervasives" + "fstar_stubs_tactics_common" -> "fstar_pervasives" + "fstar_stubs_tactics_common" -> "prims" + "fstar_stubs_tactics_common" -> "prims" + "fstar_int_cast" -> "fstar_int" + "fstar_int_cast" -> "fstar_int" + "fstar_int_cast" -> "fstar_int64" + "fstar_int_cast" -> "fstar_int64" + "fstar_int_cast" -> "fstar_int32" + "fstar_int_cast" -> "fstar_int32" + "fstar_int_cast" -> "fstar_int16" + "fstar_int_cast" -> "fstar_int16" + "fstar_int_cast" -> "fstar_int8" + "fstar_int_cast" -> "fstar_int8" + "fstar_int_cast" -> "fstar_uint64" + "fstar_int_cast" -> "fstar_uint64" + "fstar_int_cast" -> "fstar_uint32" + "fstar_int_cast" -> "fstar_uint32" + "fstar_int_cast" -> "fstar_uint16" + "fstar_int_cast" -> "fstar_uint16" + "fstar_int_cast" -> "fstar_uint8" + "fstar_int_cast" -> "fstar_uint8" + "fstar_int_cast" -> "fstar_pervasives" + "fstar_int_cast" -> "fstar_pervasives" + "fstar_int_cast" -> "prims" + "fstar_int_cast" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "core_result" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "core" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__neon" -> "prims" + "libcrux_ml_dsa_simd_portable_ntt" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable_ntt" -> "rust_primitives" + "libcrux_ml_dsa_simd_portable_ntt" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_ntt" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_ntt" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_ntt" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_portable_ntt" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_simd_portable_ntt" -> "libcrux_ml_dsa_simd_portable" + "libcrux_ml_dsa_simd_portable_ntt" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_ntt" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_ntt" -> "core" + "libcrux_ml_dsa_simd_portable_ntt" -> "core" + "libcrux_ml_dsa_simd_portable_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_ntt" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_ntt" -> "prims" + "libcrux_ml_dsa_simd_portable_ntt" -> "prims" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_commitment" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_commitment" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_commitment" -> "core_iter_traits_collect" + "libcrux_ml_dsa_encoding_commitment" -> "core_iter_traits_collect" + "libcrux_ml_dsa_encoding_commitment" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_commitment" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_commitment" -> "core_panicking" + "libcrux_ml_dsa_encoding_commitment" -> "core_panicking" + "libcrux_ml_dsa_encoding_commitment" -> "core_slice" + "libcrux_ml_dsa_encoding_commitment" -> "core_ops_range" + "libcrux_ml_dsa_encoding_commitment" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_commitment" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_commitment" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_commitment" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_commitment" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_encoding_commitment" -> "core" + "libcrux_ml_dsa_encoding_commitment" -> "core" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_commitment" -> "prims" + "libcrux_ml_dsa_encoding_commitment" -> "prims" + "libcrux_ml_dsa_encoding_commitment" -> "libcrux_ml_dsa_encoding_commitment" + "fstar_reflection_v2" -> "fstar_reflection_v2_collect" + "fstar_reflection_v2" -> "fstar_reflection_v2_collect" + "fstar_reflection_v2" -> "fstar_reflection_v2_compare" + "fstar_reflection_v2" -> "fstar_reflection_v2_compare" + "fstar_reflection_v2" -> "fstar_reflection_const" + "fstar_reflection_v2" -> "fstar_reflection_const" + "fstar_reflection_v2" -> "fstar_reflection_v2_derived_lemmas" + "fstar_reflection_v2" -> "fstar_reflection_v2_derived_lemmas" + "fstar_reflection_v2" -> "fstar_reflection_v2_derived" + "fstar_reflection_v2" -> "fstar_reflection_v2_derived" + "fstar_reflection_v2" -> "fstar_stubs_reflection_v2_builtins" + "fstar_reflection_v2" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_v2" -> "fstar_stubs_reflection_types" + "fstar_reflection_v2" -> "fstar_pervasives" + "fstar_reflection_v2" -> "fstar_pervasives" + "fstar_reflection_v2" -> "prims" + "fstar_reflection_v2" -> "prims" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_sha3_neon_x2" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_uint8" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_uint8" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_pervasives_native" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_pervasives_native" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_neon" -> "rust_primitives_hax" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_list_tot" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_list_tot" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_hash_functions_neon" -> "libcrux_sha3_neon_x2_incremental" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_mul" + "libcrux_ml_dsa_hash_functions_neon" -> "core" + "libcrux_ml_dsa_hash_functions_neon" -> "core" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_neon" -> "fstar_pervasives" + "libcrux_ml_dsa_hash_functions_neon" -> "prims" + "libcrux_ml_dsa_hash_functions_neon" -> "prims" + "lib_rawinttypes" -> "lib_inttypes" + "lib_rawinttypes" -> "lib_inttypes" + "lib_rawinttypes" -> "lib_inttypes" + "lib_rawinttypes" -> "fstar_pervasives" + "lib_rawinttypes" -> "fstar_pervasives" + "lib_rawinttypes" -> "prims" + "lib_rawinttypes" -> "prims" + "lib_rawinttypes" -> "lib_rawinttypes" + "libcrux_sha3_avx2_x4_incremental" -> "libcrux_sha3_neon_x2_incremental" + "libcrux_sha3_avx2_x4_incremental" -> "fstar_mul" + "libcrux_sha3_avx2_x4_incremental" -> "fstar_mul" + "libcrux_sha3_avx2_x4_incremental" -> "core" + "libcrux_sha3_avx2_x4_incremental" -> "core" + "libcrux_sha3_avx2_x4_incremental" -> "fstar_pervasives" + "libcrux_sha3_avx2_x4_incremental" -> "fstar_pervasives" + "libcrux_sha3_avx2_x4_incremental" -> "prims" + "libcrux_sha3_avx2_x4_incremental" -> "prims" + "fstar_tactics_namedview" -> "fstar_range" + "fstar_tactics_namedview" -> "fstar_reflection_v2" + "fstar_tactics_namedview" -> "fstar_reflection_v2" + "fstar_tactics_namedview" -> "fstar_tactics_effect" + "fstar_tactics_namedview" -> "fstar_tactics_effect" + "fstar_tactics_namedview" -> "fstar_pervasives" + "fstar_tactics_namedview" -> "fstar_pervasives" + "fstar_tactics_namedview" -> "prims" + "fstar_tactics_namedview" -> "prims" + "fstar_indefinitedescription" -> "fstar_ghost" + "fstar_indefinitedescription" -> "fstar_ghost" + "fstar_indefinitedescription" -> "fstar_squash" + "fstar_indefinitedescription" -> "fstar_squash" + "fstar_indefinitedescription" -> "fstar_classical" + "fstar_indefinitedescription" -> "fstar_classical" + "fstar_indefinitedescription" -> "fstar_pervasives" + "fstar_indefinitedescription" -> "fstar_pervasives" + "fstar_indefinitedescription" -> "prims" + "fstar_indefinitedescription" -> "prims" + "fstar_indefinitedescription" -> "fstar_indefinitedescription" + "fstar_stubs_reflection_v1_data" -> "fstar_sealed_inhabited" + "fstar_stubs_reflection_v1_data" -> "fstar_sealed_inhabited" + "fstar_stubs_reflection_v1_data" -> "fstar_stubs_reflection_types" + "fstar_stubs_reflection_v1_data" -> "fstar_stubs_reflection_v2_builtins" + "fstar_stubs_reflection_v1_data" -> "fstar_stubs_reflection_v2_data" + "fstar_stubs_reflection_v1_data" -> "fstar_pervasives" + "fstar_stubs_reflection_v1_data" -> "fstar_pervasives" + "fstar_stubs_reflection_v1_data" -> "prims" + "fstar_stubs_reflection_v1_data" -> "prims" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_matrix" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_matrix" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_matrix" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_matrix" -> "fstar_mul" + "libcrux_ml_dsa_matrix" -> "fstar_mul" + "libcrux_ml_dsa_matrix" -> "core" + "libcrux_ml_dsa_matrix" -> "core" + "libcrux_ml_dsa_matrix" -> "fstar_pervasives" + "libcrux_ml_dsa_matrix" -> "fstar_pervasives" + "libcrux_ml_dsa_matrix" -> "prims" + "libcrux_ml_dsa_matrix" -> "prims" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_portable" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "core" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "prims" + "libcrux_ml_dsa_ml_dsa_65__portable" -> "libcrux_ml_dsa_ml_dsa_65__portable" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "core_panicking" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "fstar_int32" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "fstar_uint8" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "libcrux_ml_dsa_simd_portable_vector_type" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "prims" + "libcrux_ml_dsa_simd_portable_encoding_commitment" -> "libcrux_ml_dsa_simd_portable_encoding_commitment" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_arithmetic" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_arithmetic" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_arithmetic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_arithmetic" -> "core" + "libcrux_ml_dsa_arithmetic" -> "core" + "libcrux_ml_dsa_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_arithmetic" -> "prims" + "libcrux_ml_dsa_arithmetic" -> "prims" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_65__avx2" -> "libcrux_ml_dsa_ml_dsa_65__avx2" + "fstar_tactics_namedview" -> "fstar_list_tot" + "fstar_tactics_namedview" -> "fstar_list_tot" + "fstar_tactics_namedview" -> "fstar_pervasives_native" + "fstar_tactics_namedview" -> "fstar_pervasives_native" + "fstar_tactics_namedview" -> "fstar_stubs_reflection_v2_data" + "fstar_tactics_namedview" -> "fstar_reflection_v2" + "fstar_tactics_namedview" -> "fstar_reflection_v2" + "fstar_tactics_namedview" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_namedview" -> "fstar_tactics_util" + "fstar_tactics_namedview" -> "fstar_tactics_util" + "fstar_tactics_namedview" -> "fstar_tactics_effect" + "fstar_tactics_namedview" -> "fstar_tactics_effect" + "fstar_tactics_namedview" -> "fstar_pervasives" + "fstar_tactics_namedview" -> "fstar_pervasives" + "fstar_tactics_namedview" -> "prims" + "fstar_tactics_namedview" -> "prims" + "fstar_tactics_namedview" -> "fstar_tactics_namedview" + "core_slice" -> "fstar_tactics_typeclasses" + "core_slice" -> "fstar_tactics_typeclasses" + "core_slice" -> "core_ops_index" + "core_slice" -> "core_ops_index" + "core_slice" -> "core_slice_iter" + "core_slice" -> "core_slice_iter" + "core_slice" -> "fstar_seq" + "core_slice" -> "fstar_seq" + "core_slice" -> "rust_primitives_integers" + "core_slice" -> "rust_primitives_integers" + "core_slice" -> "rust_primitives_arrays" + "core_slice" -> "rust_primitives_arrays" + "core_slice" -> "fstar_pervasives" + "core_slice" -> "fstar_pervasives" + "core_slice" -> "prims" + "core_slice" -> "prims" + "libcrux_ml_dsa_constants" -> "rust_primitives" + "libcrux_ml_dsa_constants" -> "rust_primitives" + "libcrux_ml_dsa_constants" -> "fstar_mul" + "libcrux_ml_dsa_constants" -> "fstar_mul" + "libcrux_ml_dsa_constants" -> "core" + "libcrux_ml_dsa_constants" -> "core" + "libcrux_ml_dsa_constants" -> "fstar_pervasives" + "libcrux_ml_dsa_constants" -> "fstar_pervasives" + "libcrux_ml_dsa_constants" -> "prims" + "libcrux_ml_dsa_constants" -> "prims" + "libcrux_ml_dsa_constants" -> "libcrux_ml_dsa_constants" + "fstar_tactics_mapply" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_mapply" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_mapply" -> "fstar_tactics_typeclasses" + "fstar_tactics_mapply" -> "fstar_tactics_typeclasses" + "fstar_tactics_mapply" -> "fstar_tactics_effect" + "fstar_tactics_mapply" -> "fstar_tactics_effect" + "fstar_tactics_mapply" -> "fstar_reflection_v2" + "fstar_tactics_mapply" -> "fstar_reflection_v2" + "fstar_tactics_mapply" -> "fstar_pervasives" + "fstar_tactics_mapply" -> "fstar_pervasives" + "fstar_tactics_mapply" -> "prims" + "fstar_tactics_mapply" -> "prims" + "fstar_int" -> "fstar_uint" + "fstar_int" -> "fstar_uint" + "fstar_int" -> "fstar_seq" + "fstar_int" -> "fstar_seq" + "fstar_int" -> "fstar_math_lib" + "fstar_int" -> "fstar_math_lib" + "fstar_int" -> "fstar_math_lemmas" + "fstar_int" -> "fstar_math_lemmas" + "fstar_int" -> "fstar_bitvector" + "fstar_int" -> "fstar_bitvector" + "fstar_int" -> "fstar_mul" + "fstar_int" -> "fstar_mul" + "fstar_int" -> "fstar_pervasives" + "fstar_int" -> "fstar_pervasives" + "fstar_int" -> "prims" + "fstar_int" -> "prims" + "fstar_int" -> "fstar_int" + "fstar_uint16" -> "fstar_uint32" + "fstar_uint16" -> "fstar_uint32" + "fstar_uint16" -> "fstar_mul" + "fstar_uint16" -> "fstar_mul" + "fstar_uint16" -> "fstar_uint" + "fstar_uint16" -> "fstar_uint" + "fstar_uint16" -> "fstar_pervasives" + "fstar_uint16" -> "fstar_pervasives" + "fstar_uint16" -> "prims" + "fstar_uint16" -> "prims" + "fstar_uint16" -> "fstar_uint16" + "fstar_int64" -> "fstar_uint32" + "fstar_int64" -> "fstar_uint32" + "fstar_int64" -> "fstar_math_lemmas" + "fstar_int64" -> "fstar_math_lemmas" + "fstar_int64" -> "fstar_mul" + "fstar_int64" -> "fstar_mul" + "fstar_int64" -> "fstar_int" + "fstar_int64" -> "fstar_int" + "fstar_int64" -> "fstar_pervasives" + "fstar_int64" -> "fstar_pervasives" + "fstar_int64" -> "prims" + "fstar_int64" -> "prims" + "fstar_int64" -> "fstar_int64" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_encoding_verification_key" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_encoding_verification_key" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_convert" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_convert" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_encoding_signature" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_encoding_signature" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_ntt" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_ntt" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_encoding_commitment" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_encoding_commitment" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_arithmetic" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_arithmetic" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_matrix" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_matrix" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_sample" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_sample" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_pervasives_native" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_pervasives_native" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_ml_dsa_generic" -> "rust_primitives" + "libcrux_ml_dsa_ml_dsa_generic" -> "rust_primitives" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_uint16" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_uint16" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_uint8" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_uint8" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_utils" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_utils" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_samplex4" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_samplex4" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_encoding_signing_key" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_encoding_signing_key" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_slice" + "libcrux_ml_dsa_ml_dsa_generic" -> "rust_primitives_hax" + "libcrux_ml_dsa_ml_dsa_generic" -> "rust_primitives_hax" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_list_tot" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_list_tot" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_option" + "libcrux_ml_dsa_ml_dsa_generic" -> "core_option" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_sha3_portable_incremental" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic" -> "core" + "libcrux_ml_dsa_ml_dsa_generic" -> "core" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic" -> "libcrux_ml_dsa_ml_dsa_generic" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "core_result" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "core" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_87__neon" -> "prims" + "fstar_mul" -> "fstar_pervasives" + "fstar_mul" -> "fstar_pervasives" + "fstar_mul" -> "prims" + "fstar_mul" -> "prims" + "fstar_reflection_termeq_simple" -> "fstar_reflection_termeq" + "fstar_reflection_termeq_simple" -> "fstar_reflection_termeq" + "fstar_reflection_termeq_simple" -> "fstar_stubs_reflection_types" + "fstar_reflection_termeq_simple" -> "fstar_pervasives" + "fstar_reflection_termeq_simple" -> "fstar_pervasives" + "fstar_reflection_termeq_simple" -> "prims" + "fstar_reflection_termeq_simple" -> "prims" + "fstar_reflection_termeq_simple" -> "fstar_reflection_termeq_simple" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_simd_avx2_vector_type" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_simd_avx2_vector_type" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_ml_dsa_generic" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_ml_dsa_generic" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_simd_avx2" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_pre_hash" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_simd256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" + "fstar_propositionalextensionality" -> "fstar_pervasives" + "fstar_propositionalextensionality" -> "fstar_pervasives" + "fstar_propositionalextensionality" -> "prims" + "fstar_propositionalextensionality" -> "prims" + "fstar_predicateextensionality" -> "fstar_propositionalextensionality" + "fstar_predicateextensionality" -> "fstar_propositionalextensionality" + "fstar_predicateextensionality" -> "fstar_functionalextensionality" + "fstar_predicateextensionality" -> "fstar_functionalextensionality" + "fstar_predicateextensionality" -> "fstar_pervasives" + "fstar_predicateextensionality" -> "fstar_pervasives" + "fstar_predicateextensionality" -> "prims" + "fstar_predicateextensionality" -> "prims" + "libcrux_ml_dsa_encoding_t1" -> "core_ops_range" + "libcrux_ml_dsa_encoding_t1" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_t1" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_t1" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_t1" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_t1" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_t1" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_t1" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_t1" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_t1" -> "core_option" + "libcrux_ml_dsa_encoding_t1" -> "core_option" + "libcrux_ml_dsa_encoding_t1" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_t1" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_t1" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_t1" -> "core_slice" + "libcrux_ml_dsa_encoding_t1" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_t1" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_t1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_t1" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_encoding_t1" -> "core" + "libcrux_ml_dsa_encoding_t1" -> "core" + "libcrux_ml_dsa_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_t1" -> "prims" + "libcrux_ml_dsa_encoding_t1" -> "prims" + "libcrux_ml_dsa_encoding_t1" -> "libcrux_ml_dsa_encoding_t1" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "core_num" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_shuffle_table" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_int8" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_int32" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "core_ops_range" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_uint8" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "rust_primitives_hax" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "hax_lib" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "core_slice" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_pervasives_native" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" -> "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_field_modulus" + "bitvec_equality" -> "fstar_functionalextensionality" + "bitvec_equality" -> "fstar_functionalextensionality" + "bitvec_equality" -> "fstar_mul" + "bitvec_equality" -> "fstar_mul" + "bitvec_equality" -> "rust_primitives" + "bitvec_equality" -> "rust_primitives" + "bitvec_equality" -> "core" + "bitvec_equality" -> "core" + "bitvec_equality" -> "fstar_pervasives" + "bitvec_equality" -> "fstar_pervasives" + "bitvec_equality" -> "prims" + "bitvec_equality" -> "prims" + "libcrux_ml_dsa_ml_dsa_65_" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_65_" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_65_" -> "libcrux_ml_dsa_ml_dsa_generic_multiplexing" + "libcrux_ml_dsa_ml_dsa_65_" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_65_" -> "core" + "libcrux_ml_dsa_ml_dsa_65_" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_65_" -> "prims" + "libcrux_ml_dsa_ml_dsa_65_" -> "libcrux_ml_dsa_ml_dsa_65_" + "fstar_int16" -> "fstar_uint" + "fstar_int16" -> "fstar_uint" + "fstar_int16" -> "fstar_uint32" + "fstar_int16" -> "fstar_uint32" + "fstar_int16" -> "fstar_mul" + "fstar_int16" -> "fstar_mul" + "fstar_int16" -> "fstar_int" + "fstar_int16" -> "fstar_int" + "fstar_int16" -> "fstar_pervasives" + "fstar_int16" -> "fstar_pervasives" + "fstar_int16" -> "prims" + "fstar_int16" -> "prims" + "libcrux_ml_dsa_sample" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_sample" -> "hax_lib" + "libcrux_ml_dsa_sample" -> "hax_lib" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_encoding_gamma1" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_encoding_gamma1" + "libcrux_ml_dsa_sample" -> "fstar_uint8" + "libcrux_ml_dsa_sample" -> "fstar_uint8" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_sample" -> "rust_primitives" + "libcrux_ml_dsa_sample" -> "rust_primitives" + "libcrux_ml_dsa_sample" -> "core_convert" + "libcrux_ml_dsa_sample" -> "core_convert" + "libcrux_ml_dsa_sample" -> "core_array" + "libcrux_ml_dsa_sample" -> "core_array" + "libcrux_ml_dsa_sample" -> "core_result" + "libcrux_ml_dsa_sample" -> "core_result" + "libcrux_ml_dsa_sample" -> "core_num" + "libcrux_ml_dsa_sample" -> "fstar_uint64" + "libcrux_ml_dsa_sample" -> "fstar_uint64" + "libcrux_ml_dsa_sample" -> "core_panicking" + "libcrux_ml_dsa_sample" -> "core_panicking" + "libcrux_ml_dsa_sample" -> "rust_primitives_hax" + "libcrux_ml_dsa_sample" -> "rust_primitives_hax" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_constants" + "libcrux_ml_dsa_sample" -> "core_ops_range" + "libcrux_ml_dsa_sample" -> "core_slice" + "libcrux_ml_dsa_sample" -> "core_slice_iter" + "libcrux_ml_dsa_sample" -> "core_slice_iter" + "libcrux_ml_dsa_sample" -> "core_iter_traits_collect" + "libcrux_ml_dsa_sample" -> "core_iter_traits_collect" + "libcrux_ml_dsa_sample" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_sample" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_sample" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_sample" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_sample" -> "fstar_pervasives_native" + "libcrux_ml_dsa_sample" -> "fstar_pervasives_native" + "libcrux_ml_dsa_sample" -> "fstar_uint16" + "libcrux_ml_dsa_sample" -> "fstar_uint16" + "libcrux_ml_dsa_sample" -> "fstar_int32" + "libcrux_ml_dsa_sample" -> "fstar_int32" + "libcrux_ml_dsa_sample" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_sample" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_hash_functions_shake256" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_hash_functions_shake128" + "libcrux_ml_dsa_sample" -> "fstar_mul" + "libcrux_ml_dsa_sample" -> "fstar_mul" + "libcrux_ml_dsa_sample" -> "core" + "libcrux_ml_dsa_sample" -> "core" + "libcrux_ml_dsa_sample" -> "fstar_pervasives" + "libcrux_ml_dsa_sample" -> "fstar_pervasives" + "libcrux_ml_dsa_sample" -> "prims" + "libcrux_ml_dsa_sample" -> "prims" + "libcrux_ml_dsa_sample" -> "libcrux_ml_dsa_sample" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "core_result" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "core" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_generic_multiplexing" -> "prims" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "prims" + "libcrux_ml_dsa_simd_portable_encoding_error" -> "libcrux_ml_dsa_simd_portable_encoding_error" + "fstar_int128" -> "fstar_int64" + "fstar_int128" -> "fstar_int64" + "fstar_int128" -> "fstar_uint" + "fstar_int128" -> "fstar_uint" + "fstar_int128" -> "fstar_uint32" + "fstar_int128" -> "fstar_uint32" + "fstar_int128" -> "fstar_mul" + "fstar_int128" -> "fstar_mul" + "fstar_int128" -> "fstar_int" + "fstar_int128" -> "fstar_int" + "fstar_int128" -> "fstar_pervasives" + "fstar_int128" -> "fstar_pervasives" + "fstar_int128" -> "prims" + "fstar_int128" -> "prims" + "lib_loopcombinators" -> "fstar_all" + "lib_loopcombinators" -> "fstar_all" + "lib_loopcombinators" -> "fstar_pervasives" + "lib_loopcombinators" -> "fstar_pervasives" + "lib_loopcombinators" -> "prims" + "lib_loopcombinators" -> "prims" + "lib_sequence" -> "fstar_list_tot" + "lib_sequence" -> "fstar_list_tot" + "lib_sequence" -> "fstar_calc" + "lib_sequence" -> "fstar_calc" + "lib_sequence" -> "fstar_math_lemmas" + "lib_sequence" -> "fstar_math_lemmas" + "lib_sequence" -> "fstar_pervasives_native" + "lib_sequence" -> "fstar_pervasives_native" + "lib_sequence" -> "fstar_seq_properties" + "lib_sequence" -> "fstar_seq_properties" + "lib_sequence" -> "fstar_seq" + "lib_sequence" -> "fstar_seq" + "lib_sequence" -> "lib_loopcombinators" + "lib_sequence" -> "lib_loopcombinators" + "lib_sequence" -> "lib_inttypes" + "lib_sequence" -> "lib_inttypes" + "lib_sequence" -> "fstar_mul" + "lib_sequence" -> "fstar_mul" + "lib_sequence" -> "fstar_pervasives" + "lib_sequence" -> "fstar_pervasives" + "lib_sequence" -> "prims" + "lib_sequence" -> "prims" + "lib_sequence" -> "lib_sequence" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "prims" + "libcrux_ml_dsa_simd_portable_encoding_t1" -> "libcrux_ml_dsa_simd_portable_encoding_t1" + "core" -> "core_ops" + "core" -> "core_ops" + "core" -> "core_iter" + "core" -> "core_num" + "core" -> "rust_primitives" + "core" -> "rust_primitives" + "core" -> "fstar_pervasives" + "core" -> "fstar_pervasives" + "core" -> "prims" + "core" -> "prims" + "fstar_class_printable" -> "fstar_seq" + "fstar_class_printable" -> "fstar_seq" + "fstar_class_printable" -> "fstar_uint64" + "fstar_class_printable" -> "fstar_uint64" + "fstar_class_printable" -> "fstar_int64" + "fstar_class_printable" -> "fstar_int64" + "fstar_class_printable" -> "fstar_uint32" + "fstar_class_printable" -> "fstar_uint32" + "fstar_class_printable" -> "fstar_int32" + "fstar_class_printable" -> "fstar_int32" + "fstar_class_printable" -> "fstar_uint16" + "fstar_class_printable" -> "fstar_uint16" + "fstar_class_printable" -> "fstar_int16" + "fstar_class_printable" -> "fstar_int16" + "fstar_class_printable" -> "fstar_int8" + "fstar_class_printable" -> "fstar_int8" + "fstar_class_printable" -> "fstar_uint8" + "fstar_class_printable" -> "fstar_uint8" + "fstar_class_printable" -> "fstar_char" + "fstar_class_printable" -> "fstar_list_tot" + "fstar_class_printable" -> "fstar_list_tot" + "fstar_class_printable" -> "fstar_tactics_typeclasses" + "fstar_class_printable" -> "fstar_tactics_typeclasses" + "fstar_class_printable" -> "fstar_seq_properties" + "fstar_class_printable" -> "fstar_seq_properties" + "fstar_class_printable" -> "fstar_string" + "fstar_class_printable" -> "fstar_pervasives" + "fstar_class_printable" -> "fstar_pervasives" + "fstar_class_printable" -> "prims" + "fstar_class_printable" -> "prims" + "fstar_uint128" -> "fstar_uint64" + "fstar_uint128" -> "fstar_uint64" + "fstar_uint128" -> "fstar_uint32" + "fstar_uint128" -> "fstar_uint32" + "fstar_uint128" -> "fstar_mul" + "fstar_uint128" -> "fstar_mul" + "fstar_uint128" -> "fstar_uint" + "fstar_uint128" -> "fstar_uint" + "fstar_uint128" -> "fstar_pervasives" + "fstar_uint128" -> "fstar_pervasives" + "fstar_uint128" -> "prims" + "fstar_uint128" -> "prims" + "fstar_tset" -> "fstar_set" + "fstar_tset" -> "fstar_set" + "fstar_tset" -> "fstar_pervasives" + "fstar_tset" -> "fstar_pervasives" + "fstar_tset" -> "prims" + "fstar_tset" -> "prims" + "fstar_list_tot" -> "fstar_list_tot_properties" + "fstar_list_tot" -> "fstar_list_tot_properties" + "fstar_list_tot" -> "fstar_list_tot_base" + "fstar_list_tot" -> "fstar_list_tot_base" + "fstar_list_tot" -> "fstar_pervasives" + "fstar_list_tot" -> "fstar_pervasives" + "fstar_list_tot" -> "prims" + "fstar_list_tot" -> "prims" + "fstar_reflection_v2_compare" -> "fstar_ghost" + "fstar_reflection_v2_compare" -> "fstar_ghost" + "fstar_reflection_v2_compare" -> "fstar_reflection_v2_derived_lemmas" + "fstar_reflection_v2_compare" -> "fstar_reflection_v2_derived_lemmas" + "fstar_reflection_v2_compare" -> "fstar_pervasives_native" + "fstar_reflection_v2_compare" -> "fstar_pervasives_native" + "fstar_reflection_v2_compare" -> "fstar_order" + "fstar_reflection_v2_compare" -> "fstar_order" + "fstar_reflection_v2_compare" -> "fstar_reflection_v2_derived" + "fstar_reflection_v2_compare" -> "fstar_reflection_v2_derived" + "fstar_reflection_v2_compare" -> "fstar_stubs_reflection_v2_builtins" + "fstar_reflection_v2_compare" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_v2_compare" -> "fstar_stubs_reflection_types" + "fstar_reflection_v2_compare" -> "fstar_pervasives" + "fstar_reflection_v2_compare" -> "fstar_pervasives" + "fstar_reflection_v2_compare" -> "prims" + "fstar_reflection_v2_compare" -> "prims" + "fstar_reflection_v2_compare" -> "fstar_reflection_v2_compare" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "core" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "prims" + "libcrux_ml_dsa_simd_portable_encoding_gamma1" -> "libcrux_ml_dsa_simd_portable_encoding_gamma1" + "fstar_list" -> "fstar_pervasives_native" + "fstar_list" -> "fstar_pervasives_native" + "fstar_list" -> "fstar_list_tot" + "fstar_list" -> "fstar_list_tot" + "fstar_list" -> "fstar_all" + "fstar_list" -> "fstar_all" + "fstar_list" -> "fstar_pervasives" + "fstar_list" -> "fstar_pervasives" + "fstar_list" -> "prims" + "fstar_list" -> "prims" + "fstar_indefinitedescription" -> "fstar_ghost" + "fstar_indefinitedescription" -> "fstar_ghost" + "fstar_indefinitedescription" -> "fstar_pervasives" + "fstar_indefinitedescription" -> "fstar_pervasives" + "fstar_indefinitedescription" -> "prims" + "fstar_indefinitedescription" -> "prims" + "fstar_uint" -> "fstar_seq_base" + "fstar_uint" -> "fstar_seq_base" + "fstar_uint" -> "fstar_calc" + "fstar_uint" -> "fstar_calc" + "fstar_uint" -> "fstar_classical" + "fstar_uint" -> "fstar_classical" + "fstar_uint" -> "fstar_seq" + "fstar_uint" -> "fstar_seq" + "fstar_uint" -> "fstar_math_lib" + "fstar_uint" -> "fstar_math_lib" + "fstar_uint" -> "fstar_math_lemmas" + "fstar_uint" -> "fstar_math_lemmas" + "fstar_uint" -> "fstar_bitvector" + "fstar_uint" -> "fstar_bitvector" + "fstar_uint" -> "fstar_mul" + "fstar_uint" -> "fstar_mul" + "fstar_uint" -> "fstar_pervasives" + "fstar_uint" -> "fstar_pervasives" + "fstar_uint" -> "prims" + "fstar_uint" -> "prims" + "fstar_uint" -> "fstar_uint" + "fstar_tset" -> "fstar_squash" + "fstar_tset" -> "fstar_squash" + "fstar_tset" -> "fstar_strongexcludedmiddle" + "fstar_tset" -> "fstar_strongexcludedmiddle" + "fstar_tset" -> "fstar_set" + "fstar_tset" -> "fstar_set" + "fstar_tset" -> "fstar_predicateextensionality" + "fstar_tset" -> "fstar_predicateextensionality" + "fstar_tset" -> "fstar_functionalextensionality" + "fstar_tset" -> "fstar_functionalextensionality" + "fstar_tset" -> "fstar_propositionalextensionality" + "fstar_tset" -> "fstar_propositionalextensionality" + "fstar_tset" -> "fstar_pervasives" + "fstar_tset" -> "fstar_pervasives" + "fstar_tset" -> "prims" + "fstar_tset" -> "prims" + "fstar_tset" -> "fstar_tset" + "libcrux_sha3_neon_x2_incremental" -> "core_core_arch_arm_shared_neon" + "libcrux_sha3_neon_x2_incremental" -> "libcrux_sha3_generic_keccak" + "libcrux_sha3_neon_x2_incremental" -> "libcrux_sha3_generic_keccak" + "libcrux_sha3_neon_x2_incremental" -> "fstar_mul" + "libcrux_sha3_neon_x2_incremental" -> "fstar_mul" + "libcrux_sha3_neon_x2_incremental" -> "core" + "libcrux_sha3_neon_x2_incremental" -> "core" + "libcrux_sha3_neon_x2_incremental" -> "fstar_pervasives" + "libcrux_sha3_neon_x2_incremental" -> "fstar_pervasives" + "libcrux_sha3_neon_x2_incremental" -> "prims" + "libcrux_sha3_neon_x2_incremental" -> "prims" + "fstar_tactics_visit" -> "fstar_pervasives_native" + "fstar_tactics_visit" -> "fstar_pervasives_native" + "fstar_tactics_visit" -> "fstar_tactics_util" + "fstar_tactics_visit" -> "fstar_tactics_util" + "fstar_tactics_visit" -> "fstar_tactics_effect" + "fstar_tactics_visit" -> "fstar_tactics_effect" + "fstar_tactics_visit" -> "fstar_stubs_reflection_v2_builtins" + "fstar_tactics_visit" -> "fstar_stubs_reflection_v2_data" + "fstar_tactics_visit" -> "fstar_stubs_reflection_types" + "fstar_tactics_visit" -> "fstar_pervasives" + "fstar_tactics_visit" -> "fstar_pervasives" + "fstar_tactics_visit" -> "prims" + "fstar_tactics_visit" -> "prims" + "libcrux_ml_dsa_simd_traits" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_traits" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_simd_traits" -> "fstar_mul" + "libcrux_ml_dsa_simd_traits" -> "fstar_mul" + "libcrux_ml_dsa_simd_traits" -> "core" + "libcrux_ml_dsa_simd_traits" -> "core" + "libcrux_ml_dsa_simd_traits" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_traits" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_traits" -> "prims" + "libcrux_ml_dsa_simd_traits" -> "prims" + "libcrux_ml_dsa_simd_traits" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "libcrux_intrinsics_avx2_extract" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_mul" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "core" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "prims" + "libcrux_ml_dsa_simd_avx2_rejection_sample_less_than_eta" -> "prims" + "fstar_reflection_v2_derived_lemmas" -> "fstar_classical" + "fstar_reflection_v2_derived_lemmas" -> "fstar_classical" + "fstar_reflection_v2_derived_lemmas" -> "fstar_pervasives_native" + "fstar_reflection_v2_derived_lemmas" -> "fstar_pervasives_native" + "fstar_reflection_v2_derived_lemmas" -> "fstar_list_tot" + "fstar_reflection_v2_derived_lemmas" -> "fstar_list_tot" + "fstar_reflection_v2_derived_lemmas" -> "fstar_reflection_v2_collect" + "fstar_reflection_v2_derived_lemmas" -> "fstar_reflection_v2_collect" + "fstar_reflection_v2_derived_lemmas" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_v2_derived_lemmas" -> "fstar_stubs_reflection_v2_builtins" + "fstar_reflection_v2_derived_lemmas" -> "fstar_stubs_reflection_types" + "fstar_reflection_v2_derived_lemmas" -> "fstar_pervasives" + "fstar_reflection_v2_derived_lemmas" -> "fstar_pervasives" + "fstar_reflection_v2_derived_lemmas" -> "prims" + "fstar_reflection_v2_derived_lemmas" -> "prims" + "libcrux_ml_dsa_encoding_error" -> "core_ops_range" + "libcrux_ml_dsa_encoding_error" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_error" -> "fstar_uint8" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_ntt" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_ntt" + "libcrux_ml_dsa_encoding_error" -> "core_iter_adapters_enumerate" + "libcrux_ml_dsa_encoding_error" -> "core_iter_adapters_enumerate" + "libcrux_ml_dsa_encoding_error" -> "core_iter_traits_collect" + "libcrux_ml_dsa_encoding_error" -> "core_iter_traits_collect" + "libcrux_ml_dsa_encoding_error" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_error" -> "rust_primitives_hax_monomorphized_update_at" + "libcrux_ml_dsa_encoding_error" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_error" -> "core_iter_traits_iterator" + "libcrux_ml_dsa_encoding_error" -> "core_option" + "libcrux_ml_dsa_encoding_error" -> "core_option" + "libcrux_ml_dsa_encoding_error" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_error" -> "fstar_pervasives_native" + "libcrux_ml_dsa_encoding_error" -> "rust_primitives_hax_folds" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_error" -> "core_panicking" + "libcrux_ml_dsa_encoding_error" -> "core_panicking" + "libcrux_ml_dsa_encoding_error" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_error" -> "rust_primitives_hax" + "libcrux_ml_dsa_encoding_error" -> "core_slice" + "libcrux_ml_dsa_encoding_error" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_error" -> "core_slice_iter" + "libcrux_ml_dsa_encoding_error" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_error" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_encoding_error" -> "fstar_mul" + "libcrux_ml_dsa_encoding_error" -> "core" + "libcrux_ml_dsa_encoding_error" -> "core" + "libcrux_ml_dsa_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_error" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_error" -> "prims" + "libcrux_ml_dsa_encoding_error" -> "prims" + "libcrux_ml_dsa_encoding_error" -> "libcrux_ml_dsa_encoding_error" + "fstar_stubs_reflection_v1_builtins" -> "fstar_vconfig" + "fstar_stubs_reflection_v1_builtins" -> "fstar_stubs_reflection_v1_data" + "fstar_stubs_reflection_v1_builtins" -> "fstar_stubs_reflection_types" + "fstar_stubs_reflection_v1_builtins" -> "fstar_order" + "fstar_stubs_reflection_v1_builtins" -> "fstar_order" + "fstar_stubs_reflection_v1_builtins" -> "fstar_pervasives" + "fstar_stubs_reflection_v1_builtins" -> "fstar_pervasives" + "fstar_stubs_reflection_v1_builtins" -> "prims" + "fstar_stubs_reflection_v1_builtins" -> "prims" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_encoding_signature" -> "core_result" + "libcrux_ml_dsa_encoding_signature" -> "core_result" + "libcrux_ml_dsa_encoding_signature" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_signature" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_signature" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_signature" -> "fstar_mul" + "libcrux_ml_dsa_encoding_signature" -> "fstar_mul" + "libcrux_ml_dsa_encoding_signature" -> "core" + "libcrux_ml_dsa_encoding_signature" -> "core" + "libcrux_ml_dsa_encoding_signature" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_signature" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_signature" -> "prims" + "libcrux_ml_dsa_encoding_signature" -> "prims" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_polynomial" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_tactics_typeclasses" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_verification_key" -> "libcrux_ml_dsa_simd_traits" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_mul" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_mul" + "libcrux_ml_dsa_encoding_verification_key" -> "core" + "libcrux_ml_dsa_encoding_verification_key" -> "core" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_verification_key" -> "fstar_pervasives" + "libcrux_ml_dsa_encoding_verification_key" -> "prims" + "libcrux_ml_dsa_encoding_verification_key" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "core_result" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "core" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__portable" -> "prims" + "fstar_reflection_v2_collect" -> "fstar_list_tot_base" + "fstar_reflection_v2_collect" -> "fstar_list_tot_base" + "fstar_reflection_v2_collect" -> "fstar_pervasives_native" + "fstar_reflection_v2_collect" -> "fstar_pervasives_native" + "fstar_reflection_v2_collect" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_v2_collect" -> "fstar_stubs_reflection_v2_builtins" + "fstar_reflection_v2_collect" -> "fstar_stubs_reflection_types" + "fstar_reflection_v2_collect" -> "fstar_pervasives" + "fstar_reflection_v2_collect" -> "fstar_pervasives" + "fstar_reflection_v2_collect" -> "prims" + "fstar_reflection_v2_collect" -> "prims" + "fstar_reflection_v2_compare" -> "fstar_order" + "fstar_reflection_v2_compare" -> "fstar_order" + "fstar_reflection_v2_compare" -> "fstar_stubs_reflection_v2_data" + "fstar_reflection_v2_compare" -> "fstar_stubs_reflection_types" + "fstar_reflection_v2_compare" -> "fstar_pervasives" + "fstar_reflection_v2_compare" -> "fstar_pervasives" + "fstar_reflection_v2_compare" -> "prims" + "fstar_reflection_v2_compare" -> "prims" + "libcrux_sha3_neon_x2" -> "fstar_mul" + "libcrux_sha3_neon_x2" -> "fstar_mul" + "libcrux_sha3_neon_x2" -> "core" + "libcrux_sha3_neon_x2" -> "core" + "libcrux_sha3_neon_x2" -> "fstar_pervasives" + "libcrux_sha3_neon_x2" -> "fstar_pervasives" + "libcrux_sha3_neon_x2" -> "prims" + "libcrux_sha3_neon_x2" -> "prims" + "fstar_tactics_v1_logic_lemmas" -> "fstar_pervasives" + "fstar_tactics_v1_logic_lemmas" -> "fstar_pervasives" + "fstar_tactics_v1_logic_lemmas" -> "prims" + "fstar_tactics_v1_logic_lemmas" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_int32" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "libcrux_ml_dsa_types" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "libcrux_ml_dsa_ml_dsa_generic_instantiations_avx2" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_mul" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "core" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "fstar_pervasives" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "prims" + "libcrux_ml_dsa_ml_dsa_44__avx2" -> "libcrux_ml_dsa_ml_dsa_44__avx2" + "fstar_tactics_effect" -> "fstar_stubs_tactics_result" + "fstar_tactics_effect" -> "fstar_stubs_tactics_types" + "fstar_tactics_effect" -> "fstar_stubs_reflection_types" + "fstar_tactics_effect" -> "fstar_pervasives" + "fstar_tactics_effect" -> "fstar_pervasives" + "fstar_tactics_effect" -> "prims" + "fstar_tactics_effect" -> "prims" + "fstar_tactics_effect" -> "fstar_tactics_effect" + "core_array_iter" -> "core_iter" + "core_array_iter" -> "rust_primitives" + "core_array_iter" -> "rust_primitives" + "core_array_iter" -> "fstar_pervasives" + "core_array_iter" -> "fstar_pervasives" + "core_array_iter" -> "prims" + "core_array_iter" -> "prims" + "tactics_utils" -> "fstar_tactics_effect" + "tactics_utils" -> "fstar_tactics_effect" + "tactics_utils" -> "fstar_char" + "tactics_utils" -> "fstar_string" + "tactics_utils" -> "fstar_reflection_v2" + "tactics_utils" -> "fstar_reflection_v2" + "tactics_utils" -> "fstar_tactics_util" + "tactics_utils" -> "fstar_tactics_util" + "tactics_utils" -> "fstar_tactics_v1" + "tactics_utils" -> "fstar_tactics_v1" + "tactics_utils" -> "fstar_tactics" + "tactics_utils" -> "fstar_tactics" + "tactics_utils" -> "fstar_pervasives_native" + "tactics_utils" -> "fstar_pervasives_native" + "tactics_utils" -> "fstar_mul" + "tactics_utils" -> "fstar_mul" + "tactics_utils" -> "fstar_class_printable" + "tactics_utils" -> "fstar_class_printable" + "tactics_utils" -> "fstar_tactics_v2_syntaxhelpers" + "tactics_utils" -> "fstar_tactics_v2_syntaxhelpers" + "tactics_utils" -> "fstar_tactics_v2" + "tactics_utils" -> "fstar_tactics_v2" + "tactics_utils" -> "fstar_list_tot" + "tactics_utils" -> "fstar_list_tot" + "tactics_utils" -> "fstar_option" + "tactics_utils" -> "fstar_option" + "tactics_utils" -> "core" + "tactics_utils" -> "core" + "tactics_utils" -> "fstar_pervasives" + "tactics_utils" -> "fstar_pervasives" + "tactics_utils" -> "prims" + "tactics_utils" -> "prims" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "libcrux_ml_dsa_simd_portable_rec_bundle_437004224" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "fstar_mul" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "core" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "fstar_pervasives" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "prims" + "libcrux_ml_dsa_simd_portable_arithmetic" -> "libcrux_ml_dsa_simd_portable_arithmetic" + "fstar_tactics_v2_logic" -> "fstar_pervasives_native" + "fstar_tactics_v2_logic" -> "fstar_pervasives_native" + "fstar_tactics_v2_logic" -> "fstar_squash" + "fstar_tactics_v2_logic" -> "fstar_squash" + "fstar_tactics_v2_logic" -> "fstar_reflection_termeq_simple" + "fstar_tactics_v2_logic" -> "fstar_reflection_termeq_simple" + "fstar_tactics_v2_logic" -> "fstar_tactics_v1_logic_lemmas" + "fstar_tactics_v2_logic" -> "fstar_tactics_v1_logic_lemmas" + "fstar_tactics_v2_logic" -> "fstar_tactics_util" + "fstar_tactics_v2_logic" -> "fstar_tactics_util" + "fstar_tactics_v2_logic" -> "fstar_tactics_namedview" + "fstar_tactics_v2_logic" -> "fstar_tactics_namedview" + "fstar_tactics_v2_logic" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_v2_logic" -> "fstar_tactics_v2_syntaxcoercions" + "fstar_tactics_v2_logic" -> "fstar_tactics_v2_derived" + "fstar_tactics_v2_logic" -> "fstar_tactics_v2_derived" + "fstar_tactics_v2_logic" -> "fstar_stubs_tactics_v2_builtins" + "fstar_tactics_v2_logic" -> "fstar_tactics_effect" + "fstar_tactics_v2_logic" -> "fstar_tactics_effect" + "fstar_tactics_v2_logic" -> "fstar_reflection_v2_formula" + "fstar_tactics_v2_logic" -> "fstar_reflection_v2_formula" + "fstar_tactics_v2_logic" -> "fstar_reflection_v2" + "fstar_tactics_v2_logic" -> "fstar_reflection_v2" + "fstar_tactics_v2_logic" -> "fstar_pervasives" + "fstar_tactics_v2_logic" -> "fstar_pervasives" + "fstar_tactics_v2_logic" -> "prims" + "fstar_tactics_v2_logic" -> "prims" + "fstar_tactics_v2_logic" -> "fstar_tactics_v2_logic" + "core_iter" -> "rust_primitives_arrays" + "core_iter" -> "rust_primitives_arrays" + "core_iter" -> "core_ops_range" + "core_iter" -> "core_iter_adapters_step_by" + "core_iter" -> "core_iter_adapters_step_by" + "core_iter" -> "fstar_pervasives_native" + "core_iter" -> "fstar_pervasives_native" + "core_iter" -> "core_ops" + "core_iter" -> "core_ops" + "core_iter" -> "fstar_tactics_typeclasses" + "core_iter" -> "fstar_tactics_typeclasses" + "core_iter" -> "core_iter_adapters_enumerate" + "core_iter" -> "core_iter_adapters_enumerate" + "core_iter" -> "core_iter_traits_iterator" + "core_iter" -> "core_iter_traits_iterator" + "core_iter" -> "rust_primitives" + "core_iter" -> "rust_primitives" + "core_iter" -> "fstar_pervasives" + "core_iter" -> "fstar_pervasives" + "core_iter" -> "prims" + "core_iter" -> "prims" +} diff --git a/libcrux-ml-dsa/src/arithmetic.rs b/libcrux-ml-dsa/src/arithmetic.rs index 7030bef96..ff91f65a7 100644 --- a/libcrux-ml-dsa/src/arithmetic.rs +++ b/libcrux-ml-dsa/src/arithmetic.rs @@ -14,17 +14,12 @@ pub(crate) fn vector_infinity_norm_exceeds( re: PolynomialRingElement, diff --git a/libcrux-ml-dsa/src/encoding/signature.rs b/libcrux-ml-dsa/src/encoding/signature.rs index 233f3e224..cc94028ee 100644 --- a/libcrux-ml-dsa/src/encoding/signature.rs +++ b/libcrux-ml-dsa/src/encoding/signature.rs @@ -1,6 +1,6 @@ use crate::{ - constants::COEFFICIENTS_IN_RING_ELEMENT, encoding, ml_dsa_generic::Signature, - polynomial::PolynomialRingElement, simd::traits::Operations, VerificationError, + constants::COEFFICIENTS_IN_RING_ELEMENT, encoding, polynomial::PolynomialRingElement, + simd::traits::Operations, types::Signature, VerificationError, }; impl< diff --git a/libcrux-ml-dsa/src/hash_functions.rs b/libcrux-ml-dsa/src/hash_functions.rs index fe32126b2..ff22b6e78 100644 --- a/libcrux-ml-dsa/src/hash_functions.rs +++ b/libcrux-ml-dsa/src/hash_functions.rs @@ -13,18 +13,8 @@ pub(crate) mod shake256 { } pub(crate) trait XofX4 { - fn shake256( - input0: &[u8], - input1: &[u8], - input2: &[u8], - input3: &[u8], - out0: &mut [u8; OUT_LEN], - out1: &mut [u8; OUT_LEN], - out2: &mut [u8; OUT_LEN], - out3: &mut [u8; OUT_LEN], - ); - fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self; - fn squeeze_first_block( + fn init_absorb_x4(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self; + fn squeeze_first_block_x4( &mut self, ) -> ( [u8; BLOCK_SIZE], @@ -32,7 +22,7 @@ pub(crate) mod shake256 { [u8; BLOCK_SIZE], [u8; BLOCK_SIZE], ); - fn squeeze_next_block( + fn squeeze_next_block_x4( &mut self, ) -> ( [u8; BLOCK_SIZE], @@ -40,6 +30,16 @@ pub(crate) mod shake256 { [u8; BLOCK_SIZE], [u8; BLOCK_SIZE], ); + fn shake256_x4( + input0: &[u8], + input1: &[u8], + input2: &[u8], + input3: &[u8], + out0: &mut [u8; OUT_LEN], + out1: &mut [u8; OUT_LEN], + out2: &mut [u8; OUT_LEN], + out3: &mut [u8; OUT_LEN], + ); } } @@ -76,16 +76,14 @@ pub(crate) mod shake128 { /// A portable implementation of [`shake128::Xof`] and [`shake256::Xof`]. pub(crate) mod portable { - use libcrux_sha3::portable::{ - incremental::{self, shake128_absorb_final, shake128_init}, - shake128, shake256, KeccakState, - }; - use super::{shake128, shake256}; + use libcrux_sha3::portable::incremental; + use libcrux_sha3::portable::KeccakState; /// Portable SHAKE 128 x4 state. /// /// We're using a portable implementation so this is actually sequential. + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake128X4 { state0: KeccakState, state1: KeccakState, @@ -93,27 +91,63 @@ pub(crate) mod portable { state3: KeccakState, } - impl shake128::XofX4 for Shake128X4 { - fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { - #[inline(always)] - fn init_absorb(input: &[u8]) -> KeccakState { - let mut state = shake128_init(); - shake128_absorb_final(&mut state, &input); + fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Shake128X4 { + let mut state0 = incremental::shake128_init(); + incremental::shake128_absorb_final(&mut state0, &input0); - state - } + let mut state1 = incremental::shake128_init(); + incremental::shake128_absorb_final(&mut state1, &input1); - let state0 = init_absorb(input0); - let state1 = init_absorb(input1); - let state2 = init_absorb(input2); - let state3 = init_absorb(input3); + let mut state2 = incremental::shake128_init(); + incremental::shake128_absorb_final(&mut state2, &input2); - Self { - state0, - state1, - state2, - state3, - } + let mut state3 = incremental::shake128_init(); + incremental::shake128_absorb_final(&mut state3, &input3); + + Shake128X4 { + state0, + state1, + state2, + state3, + } + } + + fn squeeze_first_five_blocks( + state: &mut Shake128X4, + out0: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out1: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out2: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out3: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + ) { + incremental::shake128_squeeze_first_five_blocks(&mut state.state0, out0); + incremental::shake128_squeeze_first_five_blocks(&mut state.state1, out1); + incremental::shake128_squeeze_first_five_blocks(&mut state.state2, out2); + incremental::shake128_squeeze_first_five_blocks(&mut state.state3, out3); + } + + fn squeeze_next_block( + state: &mut Shake128X4, + ) -> ( + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake128::BLOCK_SIZE]; + incremental::shake128_squeeze_next_block(&mut state.state0, &mut out0); + let mut out1 = [0u8; shake128::BLOCK_SIZE]; + incremental::shake128_squeeze_next_block(&mut state.state1, &mut out1); + let mut out2 = [0u8; shake128::BLOCK_SIZE]; + incremental::shake128_squeeze_next_block(&mut state.state2, &mut out2); + let mut out3 = [0u8; shake128::BLOCK_SIZE]; + incremental::shake128_squeeze_next_block(&mut state.state3, &mut out3); + + (out0, out1, out2, out3) + } + + impl shake128::XofX4 for Shake128X4 { + fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { + init_absorb(input0, input1, input2, input3) } fn squeeze_first_five_blocks( @@ -123,12 +157,8 @@ pub(crate) mod portable { out2: &mut [u8; shake128::FIVE_BLOCKS_SIZE], out3: &mut [u8; shake128::FIVE_BLOCKS_SIZE], ) { - incremental::shake128_squeeze_first_five_blocks(&mut self.state0, out0); - incremental::shake128_squeeze_first_five_blocks(&mut self.state1, out1); - incremental::shake128_squeeze_first_five_blocks(&mut self.state2, out2); - incremental::shake128_squeeze_first_five_blocks(&mut self.state3, out3); + squeeze_first_five_blocks(self, out0, out1, out2, out3); } - fn squeeze_next_block( &mut self, ) -> ( @@ -137,90 +167,147 @@ pub(crate) mod portable { [u8; shake128::BLOCK_SIZE], [u8; shake128::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake128::BLOCK_SIZE]; - incremental::shake128_squeeze_next_block(&mut self.state0, &mut out0); - let mut out1 = [0u8; shake128::BLOCK_SIZE]; - incremental::shake128_squeeze_next_block(&mut self.state1, &mut out1); - let mut out2 = [0u8; shake128::BLOCK_SIZE]; - incremental::shake128_squeeze_next_block(&mut self.state2, &mut out2); - let mut out3 = [0u8; shake128::BLOCK_SIZE]; - incremental::shake128_squeeze_next_block(&mut self.state3, &mut out3); - - (out0, out1, out2, out3) + squeeze_next_block(self) } } /// Portable SHAKE 128 state + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake128 {} + fn shake128(input: &[u8], out: &mut [u8; OUTPUT_LENGTH]) { + libcrux_sha3::portable::shake128(out, input); + } + impl shake128::Xof for Shake128 { fn shake128(input: &[u8], out: &mut [u8; OUTPUT_LENGTH]) { - shake128(out, input); + shake128(input, out); } } /// Portable SHAKE 256 state + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake256 { state: KeccakState, } + + fn shake256(input: &[u8], out: &mut [u8; OUTPUT_LENGTH]) { + libcrux_sha3::portable::shake256(out, input); + } + + fn init_absorb_shake256(input: &[u8]) -> Shake256 { + let mut state = incremental::shake256_init(); + incremental::shake256_absorb_final(&mut state, input); + Shake256 { state } + } + + fn squeeze_first_block_shake256(state: &mut Shake256) -> [u8; shake256::BLOCK_SIZE] { + let mut out = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_first_block(&mut state.state, &mut out); + out + } + + fn squeeze_next_block_shake256(state: &mut Shake256) -> [u8; shake256::BLOCK_SIZE] { + let mut out = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_next_block(&mut state.state, &mut out); + out + } + impl shake256::Xof for Shake256 { fn shake256(input: &[u8], out: &mut [u8; OUTPUT_LENGTH]) { - shake256(out, input); + shake256(input, out); } fn init_absorb(input: &[u8]) -> Self { - let mut state = incremental::shake256_init(); - incremental::shake256_absorb_final(&mut state, input); - - Self { state } + init_absorb_shake256(input) } fn squeeze_first_block(&mut self) -> [u8; shake256::BLOCK_SIZE] { - let mut out = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_first_block(&mut self.state, &mut out); - out + squeeze_first_block_shake256(self) } fn squeeze_next_block(&mut self) -> [u8; shake256::BLOCK_SIZE] { - let mut out = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_next_block(&mut self.state, &mut out); - out + squeeze_next_block_shake256(self) } } /// Portable SHAKE 256 x4 state. /// /// We're using a portable implementation so this is actually sequential. + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake256X4 { - state0: KeccakState, - state1: KeccakState, - state2: KeccakState, - state3: KeccakState, + state0: libcrux_sha3::portable::KeccakState, + state1: libcrux_sha3::portable::KeccakState, + state2: libcrux_sha3::portable::KeccakState, + state3: libcrux_sha3::portable::KeccakState, } + fn init_absorb_x4(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Shake256X4 { + let mut state0 = incremental::shake256_init(); + incremental::shake256_absorb_final(&mut state0, input0); - impl shake256::XofX4 for Shake256X4 { - fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { - let mut state0 = incremental::shake256_init(); - incremental::shake256_absorb_final(&mut state0, input0); + let mut state1 = incremental::shake256_init(); + incremental::shake256_absorb_final(&mut state1, input1); - let mut state1 = incremental::shake256_init(); - incremental::shake256_absorb_final(&mut state1, input1); + let mut state2 = incremental::shake256_init(); + incremental::shake256_absorb_final(&mut state2, input2); - let mut state2 = incremental::shake256_init(); - incremental::shake256_absorb_final(&mut state2, input2); + let mut state3 = incremental::shake256_init(); + incremental::shake256_absorb_final(&mut state3, input3); - let mut state3 = incremental::shake256_init(); - incremental::shake256_absorb_final(&mut state3, input3); + Shake256X4 { + state0, + state1, + state2, + state3, + } + } - Self { - state0, - state1, - state2, - state3, - } + fn squeeze_first_block_x4( + state: &mut Shake256X4, + ) -> ( + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_first_block(&mut state.state0, &mut out0); + let mut out1 = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_first_block(&mut state.state1, &mut out1); + let mut out2 = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_first_block(&mut state.state2, &mut out2); + let mut out3 = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_first_block(&mut state.state3, &mut out3); + + (out0, out1, out2, out3) + } + + fn squeeze_next_block_x4( + state: &mut Shake256X4, + ) -> ( + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_next_block(&mut state.state0, &mut out0); + let mut out1 = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_next_block(&mut state.state1, &mut out1); + let mut out2 = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_next_block(&mut state.state2, &mut out2); + let mut out3 = [0u8; shake256::BLOCK_SIZE]; + incremental::shake256_squeeze_next_block(&mut state.state3, &mut out3); + + (out0, out1, out2, out3) + } + + impl shake256::XofX4 for Shake256X4 { + fn init_absorb_x4(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { + init_absorb_x4(input0, input1, input2, input3) } - fn squeeze_first_block( + fn squeeze_first_block_x4( &mut self, ) -> ( [u8; shake256::BLOCK_SIZE], @@ -228,19 +315,10 @@ pub(crate) mod portable { [u8; shake256::BLOCK_SIZE], [u8; shake256::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_first_block(&mut self.state0, &mut out0); - let mut out1 = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_first_block(&mut self.state1, &mut out1); - let mut out2 = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_first_block(&mut self.state2, &mut out2); - let mut out3 = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_first_block(&mut self.state3, &mut out3); - - (out0, out1, out2, out3) + squeeze_first_block_x4(self) } - fn squeeze_next_block( + fn squeeze_next_block_x4( &mut self, ) -> ( [u8; shake256::BLOCK_SIZE], @@ -248,19 +326,10 @@ pub(crate) mod portable { [u8; shake256::BLOCK_SIZE], [u8; shake256::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_next_block(&mut self.state0, &mut out0); - let mut out1 = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_next_block(&mut self.state1, &mut out1); - let mut out2 = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_next_block(&mut self.state2, &mut out2); - let mut out3 = [0u8; shake256::BLOCK_SIZE]; - incremental::shake256_squeeze_next_block(&mut self.state3, &mut out3); - - (out0, out1, out2, out3) + squeeze_next_block_x4(self) } - fn shake256( + fn shake256_x4( input0: &[u8], input1: &[u8], input2: &[u8], @@ -270,41 +339,113 @@ pub(crate) mod portable { out2: &mut [u8; OUT_LEN], out3: &mut [u8; OUT_LEN], ) { - shake256(out0, input0); - shake256(out1, input1); - shake256(out2, input2); - shake256(out3, input3); + shake256(input0, out0); + shake256(input1, out1); + shake256(input2, out2); + shake256(input3, out3); } } + + #[cfg_attr(hax, hax_lib::opaque_type)] + pub(crate) struct Shake256Absorb { + state: libcrux_sha3::portable::incremental::Shake256Absorb, + } + + #[cfg_attr(hax, hax_lib::opaque_type)] + pub(crate) struct Shake256Squeeze { + state: libcrux_sha3::portable::incremental::Shake256Squeeze, + } + + use libcrux_sha3::portable::incremental::{XofAbsorb, XofSqueeze}; + + pub(crate) fn shake256_init() -> Shake256Absorb { + Shake256Absorb { + state: libcrux_sha3::portable::incremental::Shake256Absorb::new(), + } + } + pub(crate) fn shake256_absorb(st: &mut Shake256Absorb, input: &[u8]) { + st.state.absorb(input) + } + pub(crate) fn shake256_absorb_final(st: Shake256Absorb, input: &[u8]) -> Shake256Squeeze { + Shake256Squeeze { + state: st.state.absorb_final(input), + } + } + pub(crate) fn shake256_squeeze(st: &mut Shake256Squeeze, out: &mut [u8]) { + st.state.squeeze(out) + } } /// A SIMD256 implementation of [`shake128::XofX4`] and [`shake256::Xof`] for AVX2. #[cfg(feature = "simd256")] pub(crate) mod simd256 { - use libcrux_sha3::{ - avx2::x4::{self, incremental::KeccakState}, - portable, - }; - use super::{shake128, shake256}; + use libcrux_sha3::avx2::x4; /// AVX2 SHAKE 128 state /// /// This only implements the XofX4 API. For the single Xof, the portable /// version is used. + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake128x4 { - state: KeccakState, + state: libcrux_sha3::avx2::x4::incremental::KeccakState, + } + + /// Init the state and absorb 4 blocks in parallel. + fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Shake128x4 { + let mut state = x4::incremental::init(); + x4::incremental::shake128_absorb_final(&mut state, &input0, &input1, &input2, &input3); + Shake128x4 { state } + } + + fn squeeze_first_five_blocks( + state: &mut Shake128x4, + out0: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out1: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out2: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out3: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + ) { + x4::incremental::shake128_squeeze_first_five_blocks( + &mut state.state, + out0, + out1, + out2, + out3, + ); + } + + fn squeeze_next_block( + state: &mut Shake128x4, + ) -> ( + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake128::BLOCK_SIZE]; + let mut out1 = [0u8; shake128::BLOCK_SIZE]; + let mut out2 = [0u8; shake128::BLOCK_SIZE]; + let mut out3 = [0u8; shake128::BLOCK_SIZE]; + x4::incremental::shake128_squeeze_next_block( + &mut state.state, + &mut out0, + &mut out1, + &mut out2, + &mut out3, + ); + + (out0, out1, out2, out3) } impl shake128::XofX4 for Shake128x4 { /// Init the state and absorb 4 blocks in parallel. + #[inline(always)] fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { - let mut state = x4::incremental::init(); - x4::incremental::shake128_absorb_final(&mut state, &input0, &input1, &input2, &input3); - Self { state } + init_absorb(input0, input1, input2, input3) } + #[inline(always)] fn squeeze_first_five_blocks( &mut self, out0: &mut [u8; shake128::FIVE_BLOCKS_SIZE], @@ -312,15 +453,10 @@ pub(crate) mod simd256 { out2: &mut [u8; shake128::FIVE_BLOCKS_SIZE], out3: &mut [u8; shake128::FIVE_BLOCKS_SIZE], ) { - x4::incremental::shake128_squeeze_first_five_blocks( - &mut self.state, - out0, - out1, - out2, - out3, - ); + squeeze_first_five_blocks(self, out0, out1, out2, out3); } + #[inline(always)] fn squeeze_next_block( &mut self, ) -> ( @@ -329,67 +465,150 @@ pub(crate) mod simd256 { [u8; shake128::BLOCK_SIZE], [u8; shake128::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake128::BLOCK_SIZE]; - let mut out1 = [0u8; shake128::BLOCK_SIZE]; - let mut out2 = [0u8; shake128::BLOCK_SIZE]; - let mut out3 = [0u8; shake128::BLOCK_SIZE]; - x4::incremental::shake128_squeeze_next_block( - &mut self.state, - &mut out0, - &mut out1, - &mut out2, - &mut out3, - ); - - (out0, out1, out2, out3) + squeeze_next_block(self) } } - // TODO: Shake256 is only portable for now. If we don't want to change that, - // we should use the portable Xof impelmentation above. - /// AVX2 SHAKE 256 state + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake256 { - state: portable::KeccakState, + state: libcrux_sha3::portable::KeccakState, } + + #[inline(always)] + fn shake256(input: &[u8], out: &mut [u8; OUTPUT_LENGTH]) { + libcrux_sha3::portable::shake256(out, input); + } + + #[inline(always)] + fn init_absorb_shake256(input: &[u8]) -> Shake256 { + let mut state = libcrux_sha3::portable::incremental::shake256_init(); + libcrux_sha3::portable::incremental::shake256_absorb_final(&mut state, input); + + Shake256 { state } + } + + #[inline(always)] + fn squeeze_first_block_shake256(state: &mut Shake256) -> [u8; shake256::BLOCK_SIZE] { + let mut out = [0u8; shake256::BLOCK_SIZE]; + libcrux_sha3::portable::incremental::shake256_squeeze_first_block( + &mut state.state, + &mut out, + ); + out + } + + #[inline(always)] + fn squeeze_next_block_shake256(state: &mut Shake256) -> [u8; shake256::BLOCK_SIZE] { + let mut out = [0u8; shake256::BLOCK_SIZE]; + libcrux_sha3::portable::incremental::shake256_squeeze_next_block( + &mut state.state, + &mut out, + ); + out + } + impl shake256::Xof for Shake256 { + #[inline(always)] fn shake256(input: &[u8], out: &mut [u8; OUTPUT_LENGTH]) { - portable::shake256(out, input); + shake256(input, out) } + #[inline(always)] fn init_absorb(input: &[u8]) -> Self { - let mut state = portable::incremental::shake256_init(); - portable::incremental::shake256_absorb_final(&mut state, input); - - Self { state } + init_absorb_shake256(input) } + #[inline(always)] fn squeeze_first_block(&mut self) -> [u8; shake256::BLOCK_SIZE] { - let mut out = [0u8; shake256::BLOCK_SIZE]; - portable::incremental::shake256_squeeze_first_block(&mut self.state, &mut out); - out + squeeze_first_block_shake256(self) } + #[inline(always)] fn squeeze_next_block(&mut self) -> [u8; shake256::BLOCK_SIZE] { - let mut out = [0u8; shake256::BLOCK_SIZE]; - portable::incremental::shake256_squeeze_next_block(&mut self.state, &mut out); - out + squeeze_next_block_shake256(self) } } /// AVX2 SHAKE 256 x4 state. + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake256x4 { - state: KeccakState, + state: libcrux_sha3::avx2::x4::incremental::KeccakState, + } + + fn init_absorb_x4(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Shake256x4 { + let mut state = x4::incremental::init(); + x4::incremental::shake256_absorb_final(&mut state, &input0, &input1, &input2, &input3); + Shake256x4 { state } + } + + fn squeeze_first_block_x4( + state: &mut Shake256x4, + ) -> ( + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake256::BLOCK_SIZE]; + let mut out1 = [0u8; shake256::BLOCK_SIZE]; + let mut out2 = [0u8; shake256::BLOCK_SIZE]; + let mut out3 = [0u8; shake256::BLOCK_SIZE]; + x4::incremental::shake256_squeeze_first_block( + &mut state.state, + &mut out0, + &mut out1, + &mut out2, + &mut out3, + ); + + (out0, out1, out2, out3) + } + + fn squeeze_next_block_x4( + state: &mut Shake256x4, + ) -> ( + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake256::BLOCK_SIZE]; + let mut out1 = [0u8; shake256::BLOCK_SIZE]; + let mut out2 = [0u8; shake256::BLOCK_SIZE]; + let mut out3 = [0u8; shake256::BLOCK_SIZE]; + x4::incremental::shake256_squeeze_next_block( + &mut state.state, + &mut out0, + &mut out1, + &mut out2, + &mut out3, + ); + + (out0, out1, out2, out3) + } + + fn shake256_x4( + input0: &[u8], + input1: &[u8], + input2: &[u8], + input3: &[u8], + out0: &mut [u8; OUT_LEN], + out1: &mut [u8; OUT_LEN], + out2: &mut [u8; OUT_LEN], + out3: &mut [u8; OUT_LEN], + ) { + x4::shake256(input0, input1, input2, input3, out0, out1, out2, out3); } impl shake256::XofX4 for Shake256x4 { - fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { - let mut state = x4::incremental::init(); - x4::incremental::shake256_absorb_final(&mut state, &input0, &input1, &input2, &input3); - Self { state } + #[inline(always)] + fn init_absorb_x4(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { + init_absorb_x4(input0, input1, input2, input3) } - fn squeeze_first_block( + #[inline(always)] + fn squeeze_first_block_x4( &mut self, ) -> ( [u8; shake256::BLOCK_SIZE], @@ -397,22 +616,11 @@ pub(crate) mod simd256 { [u8; shake256::BLOCK_SIZE], [u8; shake256::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake256::BLOCK_SIZE]; - let mut out1 = [0u8; shake256::BLOCK_SIZE]; - let mut out2 = [0u8; shake256::BLOCK_SIZE]; - let mut out3 = [0u8; shake256::BLOCK_SIZE]; - x4::incremental::shake256_squeeze_first_block( - &mut self.state, - &mut out0, - &mut out1, - &mut out2, - &mut out3, - ); - - (out0, out1, out2, out3) + squeeze_first_block_x4(self) } - fn squeeze_next_block( + #[inline(always)] + fn squeeze_next_block_x4( &mut self, ) -> ( [u8; shake256::BLOCK_SIZE], @@ -420,22 +628,11 @@ pub(crate) mod simd256 { [u8; shake256::BLOCK_SIZE], [u8; shake256::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake256::BLOCK_SIZE]; - let mut out1 = [0u8; shake256::BLOCK_SIZE]; - let mut out2 = [0u8; shake256::BLOCK_SIZE]; - let mut out3 = [0u8; shake256::BLOCK_SIZE]; - x4::incremental::shake256_squeeze_next_block( - &mut self.state, - &mut out0, - &mut out1, - &mut out2, - &mut out3, - ); - - (out0, out1, out2, out3) - } - - fn shake256( + squeeze_next_block_x4(self) + } + + #[inline(always)] + fn shake256_x4( input0: &[u8], input1: &[u8], input2: &[u8], @@ -445,7 +642,7 @@ pub(crate) mod simd256 { out2: &mut [u8; OUT_LEN], out3: &mut [u8; OUT_LEN], ) { - x4::shake256(input0, input1, input2, input3, out0, out1, out2, out3); + shake256_x4(input0, input1, input2, input3, out0, out1, out2, out3); } } } @@ -454,21 +651,57 @@ pub(crate) mod simd256 { #[cfg(feature = "simd128")] pub(crate) mod neon { - use libcrux_sha3::neon::x2::{self, incremental::KeccakState}; - use super::{shake128, shake256}; + use libcrux_sha3::neon::x2; + #[cfg_attr(hax, hax_lib::opaque_type)] + pub(crate) type KeccakState = x2::incremental::KeccakState; + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake128x4 { state: [KeccakState; 2], } + /// Init the state and absorb 4 blocks in parallel. + fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Shake128x4 { + let mut state = [x2::incremental::init(), x2::incremental::init()]; + x2::incremental::shake128_absorb_final(&mut state[0], &input0, &input1); + x2::incremental::shake128_absorb_final(&mut state[1], &input2, &input3); + Shake128x4 { state } + } + + fn squeeze_first_five_blocks( + state: &mut Shake128x4, + out0: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out1: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out2: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + out3: &mut [u8; shake128::FIVE_BLOCKS_SIZE], + ) { + x2::incremental::shake128_squeeze_first_five_blocks(&mut state.state[0], out0, out1); + x2::incremental::shake128_squeeze_first_five_blocks(&mut state.state[1], out2, out3); + } + + fn squeeze_next_block( + state: &mut Shake128x4, + ) -> ( + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + [u8; shake128::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake128::BLOCK_SIZE]; + let mut out1 = [0u8; shake128::BLOCK_SIZE]; + let mut out2 = [0u8; shake128::BLOCK_SIZE]; + let mut out3 = [0u8; shake128::BLOCK_SIZE]; + x2::incremental::shake128_squeeze_next_block(&mut state.state[0], &mut out0, &mut out1); + x2::incremental::shake128_squeeze_next_block(&mut state.state[1], &mut out2, &mut out3); + + (out0, out1, out2, out3) + } + impl shake128::XofX4 for Shake128x4 { /// Init the state and absorb 4 blocks in parallel. fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { - let mut state = [x2::incremental::init(), x2::incremental::init()]; - x2::incremental::shake128_absorb_final(&mut state[0], &input0, &input1); - x2::incremental::shake128_absorb_final(&mut state[1], &input2, &input3); - Self { state } + init_absorb(input0, input1, input2, input3) } fn squeeze_first_five_blocks( @@ -478,8 +711,7 @@ pub(crate) mod neon { out2: &mut [u8; shake128::FIVE_BLOCKS_SIZE], out3: &mut [u8; shake128::FIVE_BLOCKS_SIZE], ) { - x2::incremental::shake128_squeeze_first_five_blocks(&mut self.state[0], out0, out1); - x2::incremental::shake128_squeeze_first_five_blocks(&mut self.state[1], out2, out3); + squeeze_first_five_blocks(self, out0, out1, out2, out3); } fn squeeze_next_block( @@ -490,31 +722,79 @@ pub(crate) mod neon { [u8; shake128::BLOCK_SIZE], [u8; shake128::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake128::BLOCK_SIZE]; - let mut out1 = [0u8; shake128::BLOCK_SIZE]; - let mut out2 = [0u8; shake128::BLOCK_SIZE]; - let mut out3 = [0u8; shake128::BLOCK_SIZE]; - x2::incremental::shake128_squeeze_next_block(&mut self.state[0], &mut out0, &mut out1); - x2::incremental::shake128_squeeze_next_block(&mut self.state[1], &mut out2, &mut out3); - - (out0, out1, out2, out3) + squeeze_next_block(self) } } /// Neon SHAKE 256 x4 state + #[cfg_attr(hax, hax_lib::opaque_type)] pub(crate) struct Shake256x4 { state: [KeccakState; 2], } + fn init_absorb_x4(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Shake256x4 { + let mut state = [x2::incremental::init(), x2::incremental::init()]; + x2::incremental::shake256_absorb_final(&mut state[0], &input0, &input1); + x2::incremental::shake256_absorb_final(&mut state[1], &input2, &input3); + Shake256x4 { state } + } + + fn squeeze_first_block_x4( + state: &mut Shake256x4, + ) -> ( + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake256::BLOCK_SIZE]; + let mut out1 = [0u8; shake256::BLOCK_SIZE]; + let mut out2 = [0u8; shake256::BLOCK_SIZE]; + let mut out3 = [0u8; shake256::BLOCK_SIZE]; + x2::incremental::shake256_squeeze_first_block(&mut state.state[0], &mut out0, &mut out1); + x2::incremental::shake256_squeeze_first_block(&mut state.state[1], &mut out2, &mut out3); + + (out0, out1, out2, out3) + } + + fn squeeze_next_block_x4( + state: &mut Shake256x4, + ) -> ( + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + [u8; shake256::BLOCK_SIZE], + ) { + let mut out0 = [0u8; shake256::BLOCK_SIZE]; + let mut out1 = [0u8; shake256::BLOCK_SIZE]; + let mut out2 = [0u8; shake256::BLOCK_SIZE]; + let mut out3 = [0u8; shake256::BLOCK_SIZE]; + x2::incremental::shake256_squeeze_next_block(&mut state.state[0], &mut out0, &mut out1); + x2::incremental::shake256_squeeze_next_block(&mut state.state[1], &mut out2, &mut out3); + + (out0, out1, out2, out3) + } + + fn shake256_x4( + input0: &[u8], + input1: &[u8], + input2: &[u8], + input3: &[u8], + out0: &mut [u8; OUT_LEN], + out1: &mut [u8; OUT_LEN], + out2: &mut [u8; OUT_LEN], + out3: &mut [u8; OUT_LEN], + ) { + x2::shake256(input0, input1, out0, out1); + x2::shake256(input2, input3, out2, out3); + } + impl shake256::XofX4 for Shake256x4 { - fn init_absorb(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { - let mut state = [x2::incremental::init(), x2::incremental::init()]; - x2::incremental::shake256_absorb_final(&mut state[0], &input0, &input1); - x2::incremental::shake256_absorb_final(&mut state[1], &input2, &input3); - Self { state } + fn init_absorb_x4(input0: &[u8], input1: &[u8], input2: &[u8], input3: &[u8]) -> Self { + init_absorb_x4(input0, input1, input2, input3) } - fn squeeze_first_block( + fn squeeze_first_block_x4( &mut self, ) -> ( [u8; shake256::BLOCK_SIZE], @@ -522,17 +802,10 @@ pub(crate) mod neon { [u8; shake256::BLOCK_SIZE], [u8; shake256::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake256::BLOCK_SIZE]; - let mut out1 = [0u8; shake256::BLOCK_SIZE]; - let mut out2 = [0u8; shake256::BLOCK_SIZE]; - let mut out3 = [0u8; shake256::BLOCK_SIZE]; - x2::incremental::shake256_squeeze_first_block(&mut self.state[0], &mut out0, &mut out1); - x2::incremental::shake256_squeeze_first_block(&mut self.state[1], &mut out2, &mut out3); - - (out0, out1, out2, out3) + squeeze_first_block_x4(self) } - fn squeeze_next_block( + fn squeeze_next_block_x4( &mut self, ) -> ( [u8; shake256::BLOCK_SIZE], @@ -540,17 +813,10 @@ pub(crate) mod neon { [u8; shake256::BLOCK_SIZE], [u8; shake256::BLOCK_SIZE], ) { - let mut out0 = [0u8; shake256::BLOCK_SIZE]; - let mut out1 = [0u8; shake256::BLOCK_SIZE]; - let mut out2 = [0u8; shake256::BLOCK_SIZE]; - let mut out3 = [0u8; shake256::BLOCK_SIZE]; - x2::incremental::shake256_squeeze_next_block(&mut self.state[0], &mut out0, &mut out1); - x2::incremental::shake256_squeeze_next_block(&mut self.state[1], &mut out2, &mut out3); - - (out0, out1, out2, out3) + squeeze_next_block_x4(self) } - fn shake256( + fn shake256_x4( input0: &[u8], input1: &[u8], input2: &[u8], @@ -560,8 +826,7 @@ pub(crate) mod neon { out2: &mut [u8; OUT_LEN], out3: &mut [u8; OUT_LEN], ) { - x2::shake256(input0, input1, out0, out1); - x2::shake256(input2, input3, out2, out3); + shake256_x4(input0, input1, input2, input3, out0, out1, out2, out3); } } } diff --git a/libcrux-ml-dsa/src/lib.rs b/libcrux-ml-dsa/src/lib.rs index c83f0ce20..dda8312c1 100644 --- a/libcrux-ml-dsa/src/lib.rs +++ b/libcrux-ml-dsa/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![deny(unsafe_code)] mod arithmetic; mod constants; @@ -16,10 +17,7 @@ mod types; mod utils; // Public interface -pub use { - ml_dsa_generic::{SigningError, VerificationError}, - types::*, -}; +pub use types::*; pub use crate::constants::KEY_GENERATION_RANDOMNESS_SIZE; pub use crate::constants::SIGNING_RANDOMNESS_SIZE; diff --git a/libcrux-ml-dsa/src/ml_dsa_generic.rs b/libcrux-ml-dsa/src/ml_dsa_generic.rs index d13930b0b..9b0443525 100644 --- a/libcrux-ml-dsa/src/ml_dsa_generic.rs +++ b/libcrux-ml-dsa/src/ml_dsa_generic.rs @@ -1,22 +1,23 @@ -use libcrux_sha3::portable::incremental::{Shake256Absorb, XofAbsorb, XofSqueeze}; - use crate::{ arithmetic::{ decompose_vector, make_hint, power2round_vector, use_hint, vector_infinity_norm_exceeds, }, constants::*, encoding, - hash_functions::{shake128, shake256}, + hash_functions::{ + portable::{shake256_absorb, shake256_absorb_final, shake256_init, shake256_squeeze}, + shake128, shake256, + }, matrix::{ add_vectors, compute_A_times_mask, compute_As1_plus_s2, compute_w_approx, subtract_vectors, vector_times_ring_element, }, ntt::ntt, - polynomial::PolynomialRingElement, pre_hash::{DomainSeparationContext, PreHash}, sample::{sample_challenge_ring_element, sample_mask_vector}, samplex4, simd::traits::Operations, + types::{Signature, SigningError, VerificationError}, utils::into_padded_array, MLDSASignature, }; @@ -24,18 +25,8 @@ use crate::{ pub(crate) mod instantiations; pub(crate) mod multiplexing; -pub(crate) struct Signature< - SIMDUnit: Operations, - const COMMITMENT_HASH_SIZE: usize, - const COLUMNS_IN_A: usize, - const ROWS_IN_A: usize, -> { - pub commitment_hash: [u8; COMMITMENT_HASH_SIZE], - pub signer_response: [PolynomialRingElement; COLUMNS_IN_A], - pub hint: [[i32; COEFFICIENTS_IN_RING_ELEMENT]; ROWS_IN_A], -} - /// Generate a key pair. +#[inline(always)] pub(crate) fn generate_key_pair< SIMDUnit: Operations, Shake128X4: shake128::XofX4, @@ -52,10 +43,10 @@ pub(crate) fn generate_key_pair< ) -> ([u8; SIGNING_KEY_SIZE], [u8; VERIFICATION_KEY_SIZE]) { // 128 = SEED_FOR_A_SIZE + SEED_FOR_ERROR_VECTORS_SIZE + SEED_FOR_SIGNING_SIZE let mut seed_expanded = [0; 128]; - let mut shake = Shake256Absorb::new(); - shake.absorb(&randomness); - let mut shake = shake.absorb_final(&[ROWS_IN_A as u8, COLUMNS_IN_A as u8]); - shake.squeeze(&mut seed_expanded); + let mut shake = shake256_init(); + shake256_absorb(&mut shake, &randomness); + let mut shake = shake256_absorb_final(shake, &[ROWS_IN_A as u8, COLUMNS_IN_A as u8]); + shake256_squeeze(&mut shake, &mut seed_expanded); let (seed_for_a, seed_expanded) = seed_expanded.split_at(SEED_FOR_A_SIZE); let (seed_for_error_vectors, seed_for_signing) = @@ -99,21 +90,8 @@ pub(crate) fn generate_key_pair< (signing_key_serialized, verification_key_serialized) } -#[derive(Debug)] -pub enum VerificationError { - MalformedHintError, - SignerResponseExceedsBoundError, - CommitmentHashesDontMatchError, - ContextTooLongError, -} - -#[derive(Debug)] -pub enum SigningError { - RejectionSamplingError, - ContextTooLongError, -} - #[allow(non_snake_case)] +#[inline(always)] pub(crate) fn sign_pre_hashed< SIMDUnit: Operations, Shake128X4: shake128::XofX4, @@ -145,7 +123,6 @@ pub(crate) fn sign_pre_hashed< return Err(SigningError::ContextTooLongError); } let pre_hashed_message = PH::hash(message); - sign_internal::< SIMDUnit, Shake128X4, @@ -174,6 +151,7 @@ pub(crate) fn sign_pre_hashed< } #[allow(non_snake_case)] +#[inline(always)] pub(crate) fn sign< SIMDUnit: Operations, Shake128X4: shake128::XofX4, @@ -199,6 +177,7 @@ pub(crate) fn sign< context: &[u8], randomness: [u8; SIGNING_RANDOMNESS_SIZE], ) -> Result, SigningError> { + // TODO: Support implicit into() in ? so that this match becomes unnecessary sign_internal::< SIMDUnit, Shake128X4, @@ -231,6 +210,7 @@ pub(crate) fn sign< /// If no `domain_separation_context` is supplied, it is assumed that /// `message` already contains the domain separation. #[allow(non_snake_case)] +#[inline(always)] pub(crate) fn sign_internal< SIMDUnit: Operations, Shake128X4: shake128::XofX4, @@ -280,12 +260,12 @@ pub(crate) fn sign_internal< let mut mask_seed = [0; MASK_SEED_SIZE]; { - let mut shake = Shake256Absorb::new(); - shake.absorb(&seed_for_signing); - shake.absorb(&randomness); - let mut shake = shake.absorb_final(&message_representative); + let mut shake = shake256_init(); + shake256_absorb(&mut shake, &seed_for_signing); + shake256_absorb(&mut shake, &randomness); + let mut shake = shake256_absorb_final(shake, &message_representative); - shake.squeeze(&mut mask_seed); + shake256_squeeze(&mut shake, &mut mask_seed); } let mut domain_separator_for_mask: u16 = 0; @@ -326,11 +306,11 @@ pub(crate) fn sign_internal< COMMITMENT_VECTOR_SIZE, >(commitment); - let mut shake = Shake256Absorb::new(); - shake.absorb(&message_representative); - let mut shake = shake.absorb_final(&commitment_serialized); + let mut shake = shake256_init(); + shake256_absorb(&mut shake, &message_representative); + let mut shake = shake256_absorb_final(shake, &commitment_serialized); - shake.squeeze(&mut commitment_hash_candidate); + shake256_squeeze(&mut shake, &mut commitment_hash_candidate); } let verifier_challenge_as_ntt = ntt(sample_challenge_ring_element::< @@ -437,25 +417,32 @@ pub(crate) fn sign_internal< /// for details on the domain separation for regular ML-DSA. Line /// 23 of Algorithm 4 (and line 18 of Algorithm 5,resp.) describe domain separation for the HashMl-DSA /// variant. +#[inline(always)] fn derive_message_representative( verification_key_hash: [u8; 64], domain_separation_context: Option, message: &[u8], message_representative: &mut [u8; 64], ) { - let mut shake = Shake256Absorb::new(); - shake.absorb(&verification_key_hash); + let mut shake = shake256_init(); + shake256_absorb(&mut shake, &verification_key_hash); if let Some(domain_separation_context) = domain_separation_context { - shake.absorb(&[domain_separation_context.pre_hash_oid().is_some() as u8]); - shake.absorb(&[domain_separation_context.context().len() as u8]); - shake.absorb(domain_separation_context.context()); + shake256_absorb( + &mut shake, + &[domain_separation_context.pre_hash_oid().is_some() as u8], + ); + shake256_absorb( + &mut shake, + &[domain_separation_context.context().len() as u8], + ); + shake256_absorb(&mut shake, domain_separation_context.context()); if let Some(pre_hash_oid) = domain_separation_context.pre_hash_oid() { - shake.absorb(pre_hash_oid) + shake256_absorb(&mut shake, pre_hash_oid) } } - let mut shake = shake.absorb_final(message); - shake.squeeze(message_representative); + let mut shake = shake256_absorb_final(shake, message); + shake256_squeeze(&mut shake, message_representative); } /// The internal verification API. @@ -463,6 +450,7 @@ fn derive_message_representative( /// If no `domain_separation_context` is supplied, it is assumed that /// `message` already contains the domain separation. #[allow(non_snake_case)] +#[inline(always)] pub(crate) fn verify_internal< SIMDUnit: Operations, Shake128X4: shake128::XofX4, @@ -545,11 +533,11 @@ pub(crate) fn verify_internal< COMMITMENT_VECTOR_SIZE, >(commitment); - let mut shake = Shake256Absorb::new(); - shake.absorb(&message_representative); - let mut shake = shake.absorb_final(&commitment_serialized); + let mut shake = shake256_init(); + shake256_absorb(&mut shake, &message_representative); + let mut shake = shake256_absorb_final(shake, &commitment_serialized); - shake.squeeze(&mut commitment_hash); + shake256_squeeze(&mut shake, &mut commitment_hash); } if signature.commitment_hash != commitment_hash { @@ -563,6 +551,7 @@ pub(crate) fn verify_internal< } #[allow(non_snake_case)] +#[inline(always)] pub(crate) fn verify< SIMDUnit: Operations, Shake128X4: shake128::XofX4, @@ -586,6 +575,7 @@ pub(crate) fn verify< context: &[u8], signature_serialized: &[u8; SIGNATURE_SIZE], ) -> Result<(), VerificationError> { + // TODO: Support implicit into() in ? so that this match becomes unnecessary verify_internal::< SIMDUnit, Shake128X4, @@ -612,6 +602,7 @@ pub(crate) fn verify< } #[allow(non_snake_case)] +#[inline(always)] pub(crate) fn verify_pre_hashed< SIMDUnit: Operations, Shake128X4: shake128::XofX4, diff --git a/libcrux-ml-dsa/src/ml_dsa_generic/instantiations.rs b/libcrux-ml-dsa/src/ml_dsa_generic/instantiations.rs index 1718f6c01..15936617b 100644 --- a/libcrux-ml-dsa/src/ml_dsa_generic/instantiations.rs +++ b/libcrux-ml-dsa/src/ml_dsa_generic/instantiations.rs @@ -3,9 +3,9 @@ macro_rules! instantiate { pub mod $modp { use crate::{ constants::*, - ml_dsa_generic::{SigningError, VerificationError}, pre_hash::SHAKE128_PH, types::*, + types::{SigningError, VerificationError}, }; /// Generate key pair. @@ -305,12 +305,7 @@ instantiate! {portable, // AVX2 generic implementation. #[cfg(feature = "simd256")] -instantiate! {avx2, - crate::simd::avx2::AVX2SIMDUnit, - crate::hash_functions::simd256::Shake128x4, - crate::hash_functions::simd256::Shake256, - crate::hash_functions::simd256::Shake256x4 -} +pub mod avx2; // NEON generic implementation. #[cfg(feature = "simd128")] diff --git a/libcrux-ml-dsa/src/ml_dsa_generic/instantiations/avx2.rs b/libcrux-ml-dsa/src/ml_dsa_generic/instantiations/avx2.rs new file mode 100644 index 000000000..6f3a754a2 --- /dev/null +++ b/libcrux-ml-dsa/src/ml_dsa_generic/instantiations/avx2.rs @@ -0,0 +1,585 @@ +use crate::{ + constants::*, + ml_dsa_generic::{SigningError, VerificationError}, + pre_hash::SHAKE128_PH, + types::*, +}; + +mod avx2_feature { + use super::*; + + /// Generate key pair. + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[allow(unsafe_code)] + pub(super) unsafe fn generate_key_pair< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const ETA: usize, + const ERROR_RING_ELEMENT_SIZE: usize, + const SIGNING_KEY_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, + >( + randomness: [u8; KEY_GENERATION_RANDOMNESS_SIZE], + ) -> ([u8; SIGNING_KEY_SIZE], [u8; VERIFICATION_KEY_SIZE]) { + crate::ml_dsa_generic::generate_key_pair::< + crate::simd::avx2::AVX2SIMDUnit, + crate::hash_functions::simd256::Shake128x4, + crate::hash_functions::simd256::Shake256, + crate::hash_functions::simd256::Shake256x4, + ROWS_IN_A, + COLUMNS_IN_A, + ETA, + ERROR_RING_ELEMENT_SIZE, + SIGNING_KEY_SIZE, + VERIFICATION_KEY_SIZE, + >(randomness) + } + + /// Sign. + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[allow(unsafe_code)] + pub(super) unsafe fn sign< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const ETA: usize, + const ERROR_RING_ELEMENT_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA2: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const SIGNING_KEY_SIZE: usize, + const SIGNATURE_SIZE: usize, + >( + signing_key: &[u8; SIGNING_KEY_SIZE], + message: &[u8], + context: &[u8], + randomness: [u8; SIGNING_RANDOMNESS_SIZE], + ) -> Result, SigningError> { + crate::ml_dsa_generic::sign::< + crate::simd::avx2::AVX2SIMDUnit, + crate::hash_functions::simd256::Shake128x4, + crate::hash_functions::simd256::Shake256, + crate::hash_functions::simd256::Shake256x4, + ROWS_IN_A, + COLUMNS_IN_A, + ETA, + ERROR_RING_ELEMENT_SIZE, + GAMMA1_EXPONENT, + GAMMA2, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + GAMMA1_RING_ELEMENT_SIZE, + SIGNING_KEY_SIZE, + SIGNATURE_SIZE, + >(&signing_key, message, context, randomness) + } + + /// Sign (internal API) + #[cfg(feature = "acvp")] + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[allow(unsafe_code)] + pub(super) unsafe fn sign_internal< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const ETA: usize, + const ERROR_RING_ELEMENT_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA2: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const SIGNING_KEY_SIZE: usize, + const SIGNATURE_SIZE: usize, + >( + signing_key: &[u8; SIGNING_KEY_SIZE], + message: &[u8], + randomness: [u8; SIGNING_RANDOMNESS_SIZE], + ) -> Result, SigningError> { + crate::ml_dsa_generic::sign_internal::< + crate::simd::avx2::AVX2SIMDUnit, + crate::hash_functions::simd256::Shake128x4, + crate::hash_functions::simd256::Shake256, + crate::hash_functions::simd256::Shake256x4, + ROWS_IN_A, + COLUMNS_IN_A, + ETA, + ERROR_RING_ELEMENT_SIZE, + GAMMA1_EXPONENT, + GAMMA2, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + GAMMA1_RING_ELEMENT_SIZE, + SIGNING_KEY_SIZE, + SIGNATURE_SIZE, + >(&signing_key, message, None, randomness) + } + + /// Sign (pre-hashed). + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[allow(unsafe_code)] + pub(super) unsafe fn sign_pre_hashed_shake128< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const ETA: usize, + const ERROR_RING_ELEMENT_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA2: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const SIGNING_KEY_SIZE: usize, + const SIGNATURE_SIZE: usize, + >( + signing_key: &[u8; SIGNING_KEY_SIZE], + message: &[u8], + context: &[u8], + randomness: [u8; SIGNING_RANDOMNESS_SIZE], + ) -> Result, SigningError> { + crate::ml_dsa_generic::sign_pre_hashed::< + crate::simd::avx2::AVX2SIMDUnit, + crate::hash_functions::simd256::Shake128x4, + crate::hash_functions::simd256::Shake256, + crate::hash_functions::simd256::Shake256x4, + SHAKE128_PH, + 256, + ROWS_IN_A, + COLUMNS_IN_A, + ETA, + ERROR_RING_ELEMENT_SIZE, + GAMMA1_EXPONENT, + GAMMA2, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + GAMMA1_RING_ELEMENT_SIZE, + SIGNING_KEY_SIZE, + SIGNATURE_SIZE, + >(&signing_key, message, context, randomness) + } + + /// Verify. + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[allow(unsafe_code)] + pub(super) unsafe fn verify< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const SIGNATURE_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const GAMMA2: i32, + const BETA: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + >( + verification_key: &[u8; VERIFICATION_KEY_SIZE], + message: &[u8], + context: &[u8], + signature: &[u8; SIGNATURE_SIZE], + ) -> Result<(), VerificationError> { + crate::ml_dsa_generic::verify::< + crate::simd::avx2::AVX2SIMDUnit, + crate::hash_functions::simd256::Shake128x4, + crate::hash_functions::simd256::Shake256, + ROWS_IN_A, + COLUMNS_IN_A, + SIGNATURE_SIZE, + VERIFICATION_KEY_SIZE, + GAMMA1_EXPONENT, + GAMMA1_RING_ELEMENT_SIZE, + GAMMA2, + BETA, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + >(verification_key, message, context, signature) + } + + /// Verify (internal API). + #[cfg(feature = "acvp")] + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[allow(unsafe_code)] + pub(super) unsafe fn verify_internal< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const SIGNATURE_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const GAMMA2: i32, + const BETA: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + >( + verification_key: &[u8; VERIFICATION_KEY_SIZE], + message: &[u8], + signature: &[u8; SIGNATURE_SIZE], + ) -> Result<(), VerificationError> { + crate::ml_dsa_generic::verify_internal::< + crate::simd::avx2::AVX2SIMDUnit, + crate::hash_functions::simd256::Shake128x4, + crate::hash_functions::simd256::Shake256, + ROWS_IN_A, + COLUMNS_IN_A, + SIGNATURE_SIZE, + VERIFICATION_KEY_SIZE, + GAMMA1_EXPONENT, + GAMMA1_RING_ELEMENT_SIZE, + GAMMA2, + BETA, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + >(verification_key, message, None, signature) + } + + /// Verify (pre-hashed with SHAKE-128). + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[allow(unsafe_code)] + pub(super) unsafe fn verify_pre_hashed_shake128< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const SIGNATURE_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const GAMMA2: i32, + const BETA: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + >( + verification_key: &[u8; VERIFICATION_KEY_SIZE], + message: &[u8], + context: &[u8], + signature: &[u8; SIGNATURE_SIZE], + ) -> Result<(), VerificationError> { + crate::ml_dsa_generic::verify_pre_hashed::< + crate::simd::avx2::AVX2SIMDUnit, + crate::hash_functions::simd256::Shake128x4, + crate::hash_functions::simd256::Shake256, + SHAKE128_PH, + 256, + ROWS_IN_A, + COLUMNS_IN_A, + SIGNATURE_SIZE, + VERIFICATION_KEY_SIZE, + GAMMA1_EXPONENT, + GAMMA1_RING_ELEMENT_SIZE, + GAMMA2, + BETA, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + >(verification_key, message, context, signature) + } +} + +/// Generate key pair. +#[allow(unsafe_code)] +pub(crate) fn generate_key_pair< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const ETA: usize, + const ERROR_RING_ELEMENT_SIZE: usize, + const SIGNING_KEY_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, +>( + randomness: [u8; KEY_GENERATION_RANDOMNESS_SIZE], +) -> ([u8; SIGNING_KEY_SIZE], [u8; VERIFICATION_KEY_SIZE]) { + unsafe { + avx2_feature::generate_key_pair::< + ROWS_IN_A, + COLUMNS_IN_A, + ETA, + ERROR_RING_ELEMENT_SIZE, + SIGNING_KEY_SIZE, + VERIFICATION_KEY_SIZE, + >(randomness) + } +} + +/// Sign. +#[allow(unsafe_code)] +#[inline(always)] +pub(crate) fn sign< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const ETA: usize, + const ERROR_RING_ELEMENT_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA2: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const SIGNING_KEY_SIZE: usize, + const SIGNATURE_SIZE: usize, +>( + signing_key: &[u8; SIGNING_KEY_SIZE], + message: &[u8], + context: &[u8], + randomness: [u8; SIGNING_RANDOMNESS_SIZE], +) -> Result, SigningError> { + unsafe { + avx2_feature::sign::< + ROWS_IN_A, + COLUMNS_IN_A, + ETA, + ERROR_RING_ELEMENT_SIZE, + GAMMA1_EXPONENT, + GAMMA2, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + GAMMA1_RING_ELEMENT_SIZE, + SIGNING_KEY_SIZE, + SIGNATURE_SIZE, + >(signing_key, message, context, randomness) + } +} + +/// Sign (internal API) +#[cfg(feature = "acvp")] +#[allow(unsafe_code)] +pub(crate) fn sign_internal< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const ETA: usize, + const ERROR_RING_ELEMENT_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA2: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const SIGNING_KEY_SIZE: usize, + const SIGNATURE_SIZE: usize, +>( + signing_key: &[u8; SIGNING_KEY_SIZE], + message: &[u8], + randomness: [u8; SIGNING_RANDOMNESS_SIZE], +) -> Result, SigningError> { + unsafe { + avx2_feature::sign_internal::< + ROWS_IN_A, + COLUMNS_IN_A, + ETA, + ERROR_RING_ELEMENT_SIZE, + GAMMA1_EXPONENT, + GAMMA2, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + GAMMA1_RING_ELEMENT_SIZE, + SIGNING_KEY_SIZE, + SIGNATURE_SIZE, + >(signing_key, message, randomness) + } +} + +/// Sign (pre-hashed). +#[allow(unsafe_code)] +pub(crate) fn sign_pre_hashed_shake128< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const ETA: usize, + const ERROR_RING_ELEMENT_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA2: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const SIGNING_KEY_SIZE: usize, + const SIGNATURE_SIZE: usize, +>( + signing_key: &[u8; SIGNING_KEY_SIZE], + message: &[u8], + context: &[u8], + randomness: [u8; SIGNING_RANDOMNESS_SIZE], +) -> Result, SigningError> { + unsafe { + avx2_feature::sign_pre_hashed_shake128::< + ROWS_IN_A, + COLUMNS_IN_A, + ETA, + ERROR_RING_ELEMENT_SIZE, + GAMMA1_EXPONENT, + GAMMA2, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + GAMMA1_RING_ELEMENT_SIZE, + SIGNING_KEY_SIZE, + SIGNATURE_SIZE, + >(signing_key, message, context, randomness) + } +} + +/// Verify. +#[allow(unsafe_code)] +pub(crate) fn verify< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const SIGNATURE_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const GAMMA2: i32, + const BETA: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, +>( + verification_key: &[u8; VERIFICATION_KEY_SIZE], + message: &[u8], + context: &[u8], + signature: &[u8; SIGNATURE_SIZE], +) -> Result<(), VerificationError> { + unsafe { + avx2_feature::verify::< + ROWS_IN_A, + COLUMNS_IN_A, + SIGNATURE_SIZE, + VERIFICATION_KEY_SIZE, + GAMMA1_EXPONENT, + GAMMA1_RING_ELEMENT_SIZE, + GAMMA2, + BETA, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + >(verification_key, message, context, signature) + } +} + +/// Verify (internal API). +#[cfg(feature = "acvp")] +#[allow(unsafe_code)] +pub(crate) fn verify_internal< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const SIGNATURE_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const GAMMA2: i32, + const BETA: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, +>( + verification_key: &[u8; VERIFICATION_KEY_SIZE], + message: &[u8], + signature: &[u8; SIGNATURE_SIZE], +) -> Result<(), VerificationError> { + unsafe { + avx2_feature::verify_internal::< + ROWS_IN_A, + COLUMNS_IN_A, + SIGNATURE_SIZE, + VERIFICATION_KEY_SIZE, + GAMMA1_EXPONENT, + GAMMA1_RING_ELEMENT_SIZE, + GAMMA2, + BETA, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + >(verification_key, message, signature) + } +} + +/// Verify (pre-hashed with SHAKE-128). +#[allow(unsafe_code)] +pub(crate) fn verify_pre_hashed_shake128< + const ROWS_IN_A: usize, + const COLUMNS_IN_A: usize, + const SIGNATURE_SIZE: usize, + const VERIFICATION_KEY_SIZE: usize, + const GAMMA1_EXPONENT: usize, + const GAMMA1_RING_ELEMENT_SIZE: usize, + const GAMMA2: i32, + const BETA: i32, + const COMMITMENT_RING_ELEMENT_SIZE: usize, + const COMMITMENT_VECTOR_SIZE: usize, + const COMMITMENT_HASH_SIZE: usize, + const ONES_IN_VERIFIER_CHALLENGE: usize, + const MAX_ONES_IN_HINT: usize, +>( + verification_key: &[u8; VERIFICATION_KEY_SIZE], + message: &[u8], + context: &[u8], + signature: &[u8; SIGNATURE_SIZE], +) -> Result<(), VerificationError> { + unsafe { + avx2_feature::verify_pre_hashed_shake128::< + ROWS_IN_A, + COLUMNS_IN_A, + SIGNATURE_SIZE, + VERIFICATION_KEY_SIZE, + GAMMA1_EXPONENT, + GAMMA1_RING_ELEMENT_SIZE, + GAMMA2, + BETA, + COMMITMENT_RING_ELEMENT_SIZE, + COMMITMENT_VECTOR_SIZE, + COMMITMENT_HASH_SIZE, + ONES_IN_VERIFIER_CHALLENGE, + MAX_ONES_IN_HINT, + >(verification_key, message, context, signature) + } +} diff --git a/libcrux-ml-dsa/src/ntt.rs b/libcrux-ml-dsa/src/ntt.rs index a1246393c..1ea58c883 100644 --- a/libcrux-ml-dsa/src/ntt.rs +++ b/libcrux-ml-dsa/src/ntt.rs @@ -1,38 +1,4 @@ -use crate::{ - arithmetic::FieldElementTimesMontgomeryR, - constants::COEFFICIENTS_IN_RING_ELEMENT, - polynomial::PolynomialRingElement, - simd::traits::{montgomery_multiply_by_fer, Operations, COEFFICIENTS_IN_SIMD_UNIT}, -}; - -const ZETAS_TIMES_MONTGOMERY_R: [FieldElementTimesMontgomeryR; 256] = [ - 0, 25847, -2608894, -518909, 237124, -777960, -876248, 466468, 1826347, 2353451, -359251, - -2091905, 3119733, -2884855, 3111497, 2680103, 2725464, 1024112, -1079900, 3585928, -549488, - -1119584, 2619752, -2108549, -2118186, -3859737, -1399561, -3277672, 1757237, -19422, 4010497, - 280005, 2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439, -3861115, - -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299, -1699267, -1643818, 3505694, - -3821735, 3507263, -2140649, -1600420, 3699596, 811944, 531354, 954230, 3881043, 3900724, - -2556880, 2071892, -2797779, -3930395, -1528703, -3677745, -3041255, -1452451, 3475950, - 2176455, -1585221, -1257611, 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922, - 3412210, -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047, -671102, -1228525, - -22981, -1308169, -381987, 1349076, 1852771, -1430430, -3343383, 264944, 508951, 3097992, - 44288, -1100098, 904516, 3958618, -3724342, -8578, 1653064, -3249728, 2389356, -210977, 759969, - -1316856, 189548, -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330, 1285669, - -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961, 2091667, 3407706, 2316500, - 3817976, -3342478, 2244091, -2446433, -3562462, 266997, 2434439, -1235728, 3513181, -3520352, - -3759364, -1197226, -3193378, 900702, 1859098, 909542, 819034, 495491, -1613174, -43260, - -522500, -655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838, 342297, - 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044, 2842341, 2691481, -2590150, - 1265009, 4055324, 1247620, 2486353, 1595974, -3767016, 1250494, 2635921, -3548272, -2994039, - 1869119, 1903435, -1050970, -1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, - -1962642, -1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031, -542412, - -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993, -2013608, 2432395, 2454455, - -164721, 1957272, 3369112, 185531, -1207385, -3183426, 162844, 1616392, 3014001, 810149, - 1652634, -3694233, -1799107, -3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, - 472078, -426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893, -2939036, - -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687, -554416, 3919660, -48306, - -1362209, 3937738, 1400424, -846154, 1976782, -]; +use crate::{polynomial::PolynomialRingElement, simd::traits::Operations}; #[inline(always)] pub(crate) fn ntt( @@ -43,105 +9,13 @@ pub(crate) fn ntt( } } -#[inline(always)] -fn invert_ntt_at_layer_0( - zeta_i: &mut usize, - re: &mut PolynomialRingElement, -) { - *zeta_i -= 1; - - for round in 0..re.simd_units.len() { - re.simd_units[round] = SIMDUnit::invert_ntt_at_layer_0( - re.simd_units[round], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i - 1], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i - 2], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i - 3], - ); - - *zeta_i -= 4; - } - - *zeta_i += 1; -} -#[inline(always)] -fn invert_ntt_at_layer_1( - zeta_i: &mut usize, - re: &mut PolynomialRingElement, -) { - *zeta_i -= 1; - - for round in 0..(256 / COEFFICIENTS_IN_SIMD_UNIT) { - re.simd_units[round] = SIMDUnit::invert_ntt_at_layer_1( - re.simd_units[round], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i - 1], - ); - *zeta_i -= 2; - } - - *zeta_i += 1; -} -#[inline(always)] -fn invert_ntt_at_layer_2( - zeta_i: &mut usize, - re: &mut PolynomialRingElement, -) { - for round in 0..(256 / COEFFICIENTS_IN_SIMD_UNIT) { - *zeta_i -= 1; - re.simd_units[round] = SIMDUnit::invert_ntt_at_layer_2( - re.simd_units[round], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ); - } -} -#[inline(always)] -fn invert_ntt_at_layer_3_plus( - zeta_i: &mut usize, - re: &mut PolynomialRingElement, -) { - let step = 1 << LAYER; - - for round in 0..(128 >> LAYER) { - *zeta_i -= 1; - - let offset = (round * step * 2) / COEFFICIENTS_IN_SIMD_UNIT; - let step_by = step / COEFFICIENTS_IN_SIMD_UNIT; - - for j in offset..offset + step_by { - let a_minus_b = SIMDUnit::subtract(&re.simd_units[j + step_by], &re.simd_units[j]); - re.simd_units[j] = SIMDUnit::add(&re.simd_units[j], &re.simd_units[j + step_by]); - re.simd_units[j + step_by] = - montgomery_multiply_by_fer(a_minus_b, ZETAS_TIMES_MONTGOMERY_R[*zeta_i]); - } - } -} - #[inline(always)] pub(crate) fn invert_ntt_montgomery( - mut re: PolynomialRingElement, + re: PolynomialRingElement, ) -> PolynomialRingElement { - let mut zeta_i = COEFFICIENTS_IN_RING_ELEMENT; - - invert_ntt_at_layer_0(&mut zeta_i, &mut re); - invert_ntt_at_layer_1(&mut zeta_i, &mut re); - invert_ntt_at_layer_2(&mut zeta_i, &mut re); - invert_ntt_at_layer_3_plus::(&mut zeta_i, &mut re); - invert_ntt_at_layer_3_plus::(&mut zeta_i, &mut re); - invert_ntt_at_layer_3_plus::(&mut zeta_i, &mut re); - invert_ntt_at_layer_3_plus::(&mut zeta_i, &mut re); - invert_ntt_at_layer_3_plus::(&mut zeta_i, &mut re); - - for i in 0..re.simd_units.len() { - // After invert_ntt_at_layer, elements are of the form a * MONTGOMERY_R^{-1} - // we multiply by (MONTGOMERY_R^2) * (1/2^8) mod Q = 41,978 to both: - // - // - Divide the elements by 256 and - // - Convert the elements form montgomery domain to the standard domain. - re.simd_units[i] = SIMDUnit::montgomery_multiply_by_constant(re.simd_units[i], 41_978); + PolynomialRingElement { + simd_units: SIMDUnit::invert_ntt_montgomery(re.simd_units), } - - re } #[inline(always)] diff --git a/libcrux-ml-dsa/src/polynomial.rs b/libcrux-ml-dsa/src/polynomial.rs index acc135481..0cab00b27 100644 --- a/libcrux-ml-dsa/src/polynomial.rs +++ b/libcrux-ml-dsa/src/polynomial.rs @@ -44,7 +44,7 @@ impl PolynomialRingElement { let mut exceeds = false; for simd_unit in self.simd_units { - exceeds |= SIMDUnit::infinity_norm_exceeds(simd_unit, bound); + exceeds = exceeds || SIMDUnit::infinity_norm_exceeds(simd_unit, bound); } exceeds diff --git a/libcrux-ml-dsa/src/pre_hash.rs b/libcrux-ml-dsa/src/pre_hash.rs index e21e412c2..06855c0f9 100644 --- a/libcrux-ml-dsa/src/pre_hash.rs +++ b/libcrux-ml-dsa/src/pre_hash.rs @@ -5,7 +5,9 @@ //!/perform the pre-hash of the message. This module implements the //! pre-hash trait for SHAKE-128, with a digest length of 256 bytes. use crate::{ - constants::CONTEXT_MAX_LEN, hash_functions::shake128::Xof, SigningError, VerificationError, + constants::CONTEXT_MAX_LEN, + hash_functions::shake128::Xof, + types::{SigningError, VerificationError}, }; pub(crate) const PRE_HASH_OID_LEN: usize = 11; diff --git a/libcrux-ml-dsa/src/sample.rs b/libcrux-ml-dsa/src/sample.rs index dfbb5b554..99e7d33f2 100644 --- a/libcrux-ml-dsa/src/sample.rs +++ b/libcrux-ml-dsa/src/sample.rs @@ -251,8 +251,8 @@ pub(crate) fn sample_four_error_ring_elements< seed3[64] = domain_separator3 as u8; seed3[65] = (domain_separator3 >> 8) as u8; - let mut state = Shake256::init_absorb(&seed0, &seed1, &seed2, &seed3); - let randomnesses = state.squeeze_first_block(); + let mut state = Shake256::init_absorb_x4(&seed0, &seed1, &seed2, &seed3); + let randomnesses = state.squeeze_first_block_x4(); // Every call to |rejection_sample_less_than_field_modulus| // will result in a call to |SIMDUnit::rejection_sample_less_than_field_modulus|; @@ -283,7 +283,7 @@ pub(crate) fn sample_four_error_ring_elements< while !done0 || !done1 || !done2 || !done3 { // Always sample another 4, but we only use it if we actually need it. - let randomnesses = state.squeeze_next_block(); + let randomnesses = state.squeeze_next_block_x4(); if !done0 { done0 = rejection_sample_less_than_eta::( &randomnesses.0, @@ -322,6 +322,7 @@ pub(crate) fn sample_four_error_ring_elements< ) } +#[inline(always)] fn update_seed(mut seed: [u8; 66], domain_separator: &mut u16) -> [u8; 66] { seed[64] = *domain_separator as u8; seed[65] = (*domain_separator >> 8) as u8; @@ -380,7 +381,7 @@ pub(crate) fn sample_mask_vector< let mut out1 = [0; 576]; let mut out2 = [0; 576]; let mut out3 = [0; 576]; - Shake256X4::shake256( + Shake256X4::shake256_x4( &seed0, &seed1, &seed2, &seed3, &mut out0, &mut out1, &mut out2, &mut out3, ); mask[0] = encoding::gamma1::deserialize::(&out0); @@ -393,7 +394,7 @@ pub(crate) fn sample_mask_vector< let mut out1 = [0; 640]; let mut out2 = [0; 640]; let mut out3 = [0; 640]; - Shake256X4::shake256( + Shake256X4::shake256_x4( &seed0, &seed1, &seed2, &seed3, &mut out0, &mut out1, &mut out2, &mut out3, ); mask[0] = encoding::gamma1::deserialize::(&out0); diff --git a/libcrux-ml-dsa/src/samplex4.rs b/libcrux-ml-dsa/src/samplex4.rs index 1173c0abf..918deb8ce 100644 --- a/libcrux-ml-dsa/src/samplex4.rs +++ b/libcrux-ml-dsa/src/samplex4.rs @@ -10,6 +10,22 @@ fn generate_domain_separator(row: u8, column: u8) -> u16 { (column as u16) | ((row as u16) << 8) } +// Doing deep updates like `a[1][1] = 3` causes a memory blowup in F* +// https://github.com/hacspec/hax/issues/1098 +// So we are instead using a matrix abstraction with a custom update function here. + +type Matrix = + [[PolynomialRingElement; COLUMNS_IN_A]; ROWS_IN_A]; + +fn update_matrix( + m: &mut Matrix, + i: usize, + j: usize, + v: PolynomialRingElement, +) { + m[i][j] = v; +} + #[allow(non_snake_case)] #[inline(always)] pub(crate) fn matrix_A_4_by_4< @@ -19,8 +35,9 @@ pub(crate) fn matrix_A_4_by_4< const COLUMNS_IN_A: usize, >( seed: [u8; 34], -) -> [[PolynomialRingElement; COLUMNS_IN_A]; ROWS_IN_A] { - let mut A = [[PolynomialRingElement::::ZERO(); COLUMNS_IN_A]; ROWS_IN_A]; +) -> Matrix { + let mut A: Matrix = + [[PolynomialRingElement::::ZERO(); COLUMNS_IN_A]; ROWS_IN_A]; let four_ring_elements = sample_four_ring_elements::( seed, @@ -29,10 +46,10 @@ pub(crate) fn matrix_A_4_by_4< generate_domain_separator(0, 2), generate_domain_separator(0, 3), ); - A[0][0] = four_ring_elements.0; - A[0][1] = four_ring_elements.1; - A[0][2] = four_ring_elements.2; - A[0][3] = four_ring_elements.3; + update_matrix(&mut A, 0, 0, four_ring_elements.0); + update_matrix(&mut A, 0, 1, four_ring_elements.1); + update_matrix(&mut A, 0, 2, four_ring_elements.2); + update_matrix(&mut A, 0, 3, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -41,10 +58,10 @@ pub(crate) fn matrix_A_4_by_4< generate_domain_separator(1, 2), generate_domain_separator(1, 3), ); - A[1][0] = four_ring_elements.0; - A[1][1] = four_ring_elements.1; - A[1][2] = four_ring_elements.2; - A[1][3] = four_ring_elements.3; + update_matrix(&mut A, 1, 0, four_ring_elements.0); + update_matrix(&mut A, 1, 1, four_ring_elements.1); + update_matrix(&mut A, 1, 2, four_ring_elements.2); + update_matrix(&mut A, 1, 3, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -53,10 +70,10 @@ pub(crate) fn matrix_A_4_by_4< generate_domain_separator(2, 2), generate_domain_separator(2, 3), ); - A[2][0] = four_ring_elements.0; - A[2][1] = four_ring_elements.1; - A[2][2] = four_ring_elements.2; - A[2][3] = four_ring_elements.3; + update_matrix(&mut A, 2, 0, four_ring_elements.0); + update_matrix(&mut A, 2, 1, four_ring_elements.1); + update_matrix(&mut A, 2, 2, four_ring_elements.2); + update_matrix(&mut A, 2, 3, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -65,10 +82,10 @@ pub(crate) fn matrix_A_4_by_4< generate_domain_separator(3, 2), generate_domain_separator(3, 3), ); - A[3][0] = four_ring_elements.0; - A[3][1] = four_ring_elements.1; - A[3][2] = four_ring_elements.2; - A[3][3] = four_ring_elements.3; + update_matrix(&mut A, 3, 0, four_ring_elements.0); + update_matrix(&mut A, 3, 1, four_ring_elements.1); + update_matrix(&mut A, 3, 2, four_ring_elements.2); + update_matrix(&mut A, 3, 3, four_ring_elements.3); A } @@ -92,10 +109,10 @@ pub(crate) fn matrix_A_6_by_5< generate_domain_separator(0, 2), generate_domain_separator(0, 3), ); - A[0][0] = four_ring_elements.0; - A[0][1] = four_ring_elements.1; - A[0][2] = four_ring_elements.2; - A[0][3] = four_ring_elements.3; + update_matrix(&mut A, 0, 0, four_ring_elements.0); + update_matrix(&mut A, 0, 1, four_ring_elements.1); + update_matrix(&mut A, 0, 2, four_ring_elements.2); + update_matrix(&mut A, 0, 3, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -104,10 +121,10 @@ pub(crate) fn matrix_A_6_by_5< generate_domain_separator(1, 1), generate_domain_separator(1, 2), ); - A[0][4] = four_ring_elements.0; - A[1][0] = four_ring_elements.1; - A[1][1] = four_ring_elements.2; - A[1][2] = four_ring_elements.3; + update_matrix(&mut A, 0, 4, four_ring_elements.0); + update_matrix(&mut A, 1, 0, four_ring_elements.1); + update_matrix(&mut A, 1, 1, four_ring_elements.2); + update_matrix(&mut A, 1, 2, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -116,10 +133,10 @@ pub(crate) fn matrix_A_6_by_5< generate_domain_separator(2, 0), generate_domain_separator(2, 1), ); - A[1][3] = four_ring_elements.0; - A[1][4] = four_ring_elements.1; - A[2][0] = four_ring_elements.2; - A[2][1] = four_ring_elements.3; + update_matrix(&mut A, 1, 3, four_ring_elements.0); + update_matrix(&mut A, 1, 4, four_ring_elements.1); + update_matrix(&mut A, 2, 0, four_ring_elements.2); + update_matrix(&mut A, 2, 1, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -128,10 +145,10 @@ pub(crate) fn matrix_A_6_by_5< generate_domain_separator(2, 4), generate_domain_separator(3, 0), ); - A[2][2] = four_ring_elements.0; - A[2][3] = four_ring_elements.1; - A[2][4] = four_ring_elements.2; - A[3][0] = four_ring_elements.3; + update_matrix(&mut A, 2, 2, four_ring_elements.0); + update_matrix(&mut A, 2, 3, four_ring_elements.1); + update_matrix(&mut A, 2, 4, four_ring_elements.2); + update_matrix(&mut A, 3, 0, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -140,10 +157,10 @@ pub(crate) fn matrix_A_6_by_5< generate_domain_separator(3, 3), generate_domain_separator(3, 4), ); - A[3][1] = four_ring_elements.0; - A[3][2] = four_ring_elements.1; - A[3][3] = four_ring_elements.2; - A[3][4] = four_ring_elements.3; + update_matrix(&mut A, 3, 1, four_ring_elements.0); + update_matrix(&mut A, 3, 2, four_ring_elements.1); + update_matrix(&mut A, 3, 3, four_ring_elements.2); + update_matrix(&mut A, 3, 4, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -152,10 +169,10 @@ pub(crate) fn matrix_A_6_by_5< generate_domain_separator(4, 2), generate_domain_separator(4, 3), ); - A[4][0] = four_ring_elements.0; - A[4][1] = four_ring_elements.1; - A[4][2] = four_ring_elements.2; - A[4][3] = four_ring_elements.3; + update_matrix(&mut A, 4, 0, four_ring_elements.0); + update_matrix(&mut A, 4, 1, four_ring_elements.1); + update_matrix(&mut A, 4, 2, four_ring_elements.2); + update_matrix(&mut A, 4, 3, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -164,10 +181,10 @@ pub(crate) fn matrix_A_6_by_5< generate_domain_separator(5, 1), generate_domain_separator(5, 2), ); - A[4][4] = four_ring_elements.0; - A[5][0] = four_ring_elements.1; - A[5][1] = four_ring_elements.2; - A[5][2] = four_ring_elements.3; + update_matrix(&mut A, 4, 4, four_ring_elements.0); + update_matrix(&mut A, 5, 0, four_ring_elements.1); + update_matrix(&mut A, 5, 1, four_ring_elements.2); + update_matrix(&mut A, 5, 2, four_ring_elements.3); // The the last 2 sampled ring elements are discarded here. let four_ring_elements = sample_four_ring_elements::( @@ -177,8 +194,8 @@ pub(crate) fn matrix_A_6_by_5< generate_domain_separator(5, 5), generate_domain_separator(5, 6), ); - A[5][3] = four_ring_elements.0; - A[5][4] = four_ring_elements.1; + update_matrix(&mut A, 5, 3, four_ring_elements.0); + update_matrix(&mut A, 5, 4, four_ring_elements.1); A } @@ -201,10 +218,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(0, 2), generate_domain_separator(0, 3), ); - A[0][0] = four_ring_elements.0; - A[0][1] = four_ring_elements.1; - A[0][2] = four_ring_elements.2; - A[0][3] = four_ring_elements.3; + update_matrix(&mut A, 0, 0, four_ring_elements.0); + update_matrix(&mut A, 0, 1, four_ring_elements.1); + update_matrix(&mut A, 0, 2, four_ring_elements.2); + update_matrix(&mut A, 0, 3, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -213,10 +230,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(0, 6), generate_domain_separator(1, 0), ); - A[0][4] = four_ring_elements.0; - A[0][5] = four_ring_elements.1; - A[0][6] = four_ring_elements.2; - A[1][0] = four_ring_elements.3; + update_matrix(&mut A, 0, 4, four_ring_elements.0); + update_matrix(&mut A, 0, 5, four_ring_elements.1); + update_matrix(&mut A, 0, 6, four_ring_elements.2); + update_matrix(&mut A, 1, 0, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -225,10 +242,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(1, 3), generate_domain_separator(1, 4), ); - A[1][1] = four_ring_elements.0; - A[1][2] = four_ring_elements.1; - A[1][3] = four_ring_elements.2; - A[1][4] = four_ring_elements.3; + update_matrix(&mut A, 1, 1, four_ring_elements.0); + update_matrix(&mut A, 1, 2, four_ring_elements.1); + update_matrix(&mut A, 1, 3, four_ring_elements.2); + update_matrix(&mut A, 1, 4, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -237,10 +254,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(2, 0), generate_domain_separator(2, 1), ); - A[1][5] = four_ring_elements.0; - A[1][6] = four_ring_elements.1; - A[2][0] = four_ring_elements.2; - A[2][1] = four_ring_elements.3; + update_matrix(&mut A, 1, 5, four_ring_elements.0); + update_matrix(&mut A, 1, 6, four_ring_elements.1); + update_matrix(&mut A, 2, 0, four_ring_elements.2); + update_matrix(&mut A, 2, 1, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -249,10 +266,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(2, 4), generate_domain_separator(2, 5), ); - A[2][2] = four_ring_elements.0; - A[2][3] = four_ring_elements.1; - A[2][4] = four_ring_elements.2; - A[2][5] = four_ring_elements.3; + update_matrix(&mut A, 2, 2, four_ring_elements.0); + update_matrix(&mut A, 2, 3, four_ring_elements.1); + update_matrix(&mut A, 2, 4, four_ring_elements.2); + update_matrix(&mut A, 2, 5, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -261,10 +278,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(3, 1), generate_domain_separator(3, 2), ); - A[2][6] = four_ring_elements.0; - A[3][0] = four_ring_elements.1; - A[3][1] = four_ring_elements.2; - A[3][2] = four_ring_elements.3; + update_matrix(&mut A, 2, 6, four_ring_elements.0); + update_matrix(&mut A, 3, 0, four_ring_elements.1); + update_matrix(&mut A, 3, 1, four_ring_elements.2); + update_matrix(&mut A, 3, 2, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -273,10 +290,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(3, 5), generate_domain_separator(3, 6), ); - A[3][3] = four_ring_elements.0; - A[3][4] = four_ring_elements.1; - A[3][5] = four_ring_elements.2; - A[3][6] = four_ring_elements.3; + update_matrix(&mut A, 3, 3, four_ring_elements.0); + update_matrix(&mut A, 3, 4, four_ring_elements.1); + update_matrix(&mut A, 3, 5, four_ring_elements.2); + update_matrix(&mut A, 3, 6, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -285,10 +302,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(4, 2), generate_domain_separator(4, 3), ); - A[4][0] = four_ring_elements.0; - A[4][1] = four_ring_elements.1; - A[4][2] = four_ring_elements.2; - A[4][3] = four_ring_elements.3; + update_matrix(&mut A, 4, 0, four_ring_elements.0); + update_matrix(&mut A, 4, 1, four_ring_elements.1); + update_matrix(&mut A, 4, 2, four_ring_elements.2); + update_matrix(&mut A, 4, 3, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -297,10 +314,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(4, 6), generate_domain_separator(5, 0), ); - A[4][4] = four_ring_elements.0; - A[4][5] = four_ring_elements.1; - A[4][6] = four_ring_elements.2; - A[5][0] = four_ring_elements.3; + update_matrix(&mut A, 4, 4, four_ring_elements.0); + update_matrix(&mut A, 4, 5, four_ring_elements.1); + update_matrix(&mut A, 4, 6, four_ring_elements.2); + update_matrix(&mut A, 5, 0, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -309,10 +326,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(5, 3), generate_domain_separator(5, 4), ); - A[5][1] = four_ring_elements.0; - A[5][2] = four_ring_elements.1; - A[5][3] = four_ring_elements.2; - A[5][4] = four_ring_elements.3; + update_matrix(&mut A, 5, 1, four_ring_elements.0); + update_matrix(&mut A, 5, 2, four_ring_elements.1); + update_matrix(&mut A, 5, 3, four_ring_elements.2); + update_matrix(&mut A, 5, 4, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -321,10 +338,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(6, 0), generate_domain_separator(6, 1), ); - A[5][5] = four_ring_elements.0; - A[5][6] = four_ring_elements.1; - A[6][0] = four_ring_elements.2; - A[6][1] = four_ring_elements.3; + update_matrix(&mut A, 5, 5, four_ring_elements.0); + update_matrix(&mut A, 5, 6, four_ring_elements.1); + update_matrix(&mut A, 6, 0, four_ring_elements.2); + update_matrix(&mut A, 6, 1, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -333,10 +350,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(6, 4), generate_domain_separator(6, 5), ); - A[6][2] = four_ring_elements.0; - A[6][3] = four_ring_elements.1; - A[6][4] = four_ring_elements.2; - A[6][5] = four_ring_elements.3; + update_matrix(&mut A, 6, 2, four_ring_elements.0); + update_matrix(&mut A, 6, 3, four_ring_elements.1); + update_matrix(&mut A, 6, 4, four_ring_elements.2); + update_matrix(&mut A, 6, 5, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -345,10 +362,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(7, 1), generate_domain_separator(7, 2), ); - A[6][6] = four_ring_elements.0; - A[7][0] = four_ring_elements.1; - A[7][1] = four_ring_elements.2; - A[7][2] = four_ring_elements.3; + update_matrix(&mut A, 6, 6, four_ring_elements.0); + update_matrix(&mut A, 7, 0, four_ring_elements.1); + update_matrix(&mut A, 7, 1, four_ring_elements.2); + update_matrix(&mut A, 7, 2, four_ring_elements.3); let four_ring_elements = sample_four_ring_elements::( seed, @@ -357,10 +374,10 @@ pub(crate) fn matrix_A_8_by_7< generate_domain_separator(7, 5), generate_domain_separator(7, 6), ); - A[7][3] = four_ring_elements.0; - A[7][4] = four_ring_elements.1; - A[7][5] = four_ring_elements.2; - A[7][6] = four_ring_elements.3; + update_matrix(&mut A, 7, 3, four_ring_elements.0); + update_matrix(&mut A, 7, 4, four_ring_elements.1); + update_matrix(&mut A, 7, 5, four_ring_elements.2); + update_matrix(&mut A, 7, 6, four_ring_elements.3); A } diff --git a/libcrux-ml-dsa/src/simd.rs b/libcrux-ml-dsa/src/simd.rs index 7228eefe2..376602844 100644 --- a/libcrux-ml-dsa/src/simd.rs +++ b/libcrux-ml-dsa/src/simd.rs @@ -3,3 +3,6 @@ pub(crate) mod avx2; pub(crate) mod portable; pub(crate) mod traits; + +#[cfg(test)] +pub(crate) mod tests; diff --git a/libcrux-ml-dsa/src/simd/avx2.rs b/libcrux-ml-dsa/src/simd/avx2.rs index 82192638a..d5cda168c 100644 --- a/libcrux-ml-dsa/src/simd/avx2.rs +++ b/libcrux-ml-dsa/src/simd/avx2.rs @@ -1,142 +1,144 @@ use crate::simd::traits::{Operations, SIMD_UNITS_IN_RING_ELEMENT}; -use libcrux_intrinsics; mod arithmetic; mod encoding; +mod invntt; mod ntt; mod rejection_sample; +mod vector_type; -#[derive(Clone, Copy)] -pub struct AVX2SIMDUnit { - pub(crate) coefficients: libcrux_intrinsics::avx2::Vec256, -} - -impl From for AVX2SIMDUnit { - fn from(coefficients: libcrux_intrinsics::avx2::Vec256) -> Self { - Self { coefficients } - } -} +pub(crate) use vector_type::AVX2SIMDUnit; impl Operations for AVX2SIMDUnit { + #[inline(always)] fn ZERO() -> Self { - libcrux_intrinsics::avx2::mm256_setzero_si256().into() + vector_type::ZERO() } + #[inline(always)] fn from_coefficient_array(coefficient_array: &[i32]) -> Self { - libcrux_intrinsics::avx2::mm256_loadu_si256_i32(coefficient_array).into() + vector_type::from_coefficient_array(coefficient_array) } + #[inline(always)] fn to_coefficient_array(&self) -> [i32; 8] { - let mut coefficient_array = [0i32; 8]; - libcrux_intrinsics::avx2::mm256_storeu_si256_i32(&mut coefficient_array, self.coefficients); - - coefficient_array + vector_type::to_coefficient_array(&self) } - + #[inline(always)] fn add(lhs: &Self, rhs: &Self) -> Self { arithmetic::add(lhs.coefficients, rhs.coefficients).into() } - + #[inline(always)] fn subtract(lhs: &Self, rhs: &Self) -> Self { arithmetic::subtract(lhs.coefficients, rhs.coefficients).into() } - fn montgomery_multiply_by_constant(simd_unit: Self, constant: i32) -> Self { - arithmetic::montgomery_multiply_by_constant(simd_unit.coefficients, constant).into() - } + #[inline(always)] fn montgomery_multiply(lhs: Self, rhs: Self) -> Self { arithmetic::montgomery_multiply(lhs.coefficients, rhs.coefficients).into() } + #[inline(always)] fn shift_left_then_reduce(simd_unit: Self) -> Self { arithmetic::shift_left_then_reduce::(simd_unit.coefficients).into() } + #[inline(always)] fn power2round(simd_unit: Self) -> (Self, Self) { let (lower, upper) = arithmetic::power2round(simd_unit.coefficients); (lower.into(), upper.into()) } + #[inline(always)] fn infinity_norm_exceeds(simd_unit: Self, bound: i32) -> bool { arithmetic::infinity_norm_exceeds(simd_unit.coefficients, bound) } + #[inline(always)] fn decompose(simd_unit: Self) -> (Self, Self) { let (lower, upper) = arithmetic::decompose::(simd_unit.coefficients); (lower.into(), upper.into()) } + #[inline(always)] fn compute_hint(low: Self, high: Self) -> (usize, Self) { let (count, hint) = arithmetic::compute_hint::(low.coefficients, high.coefficients); (count, hint.into()) } + #[inline(always)] fn use_hint(simd_unit: Self, hint: Self) -> Self { arithmetic::use_hint::(simd_unit.coefficients, hint.coefficients).into() } + #[inline(always)] fn rejection_sample_less_than_field_modulus(randomness: &[u8], out: &mut [i32]) -> usize { rejection_sample::less_than_field_modulus::sample(randomness, out) } + #[inline(always)] fn rejection_sample_less_than_eta_equals_2(randomness: &[u8], out: &mut [i32]) -> usize { rejection_sample::less_than_eta::sample::<2>(randomness, out) } + #[inline(always)] fn rejection_sample_less_than_eta_equals_4(randomness: &[u8], out: &mut [i32]) -> usize { rejection_sample::less_than_eta::sample::<4>(randomness, out) } + #[inline(always)] fn gamma1_serialize(simd_unit: Self) -> [u8; OUTPUT_SIZE] { encoding::gamma1::serialize::(simd_unit.coefficients) } + #[inline(always)] fn gamma1_deserialize(serialized: &[u8]) -> Self { encoding::gamma1::deserialize::(serialized).into() } + #[inline(always)] fn commitment_serialize(simd_unit: Self) -> [u8; OUTPUT_SIZE] { encoding::commitment::serialize::(simd_unit.coefficients) } + #[inline(always)] fn error_serialize(simd_unit: Self) -> [u8; OUTPUT_SIZE] { encoding::error::serialize::(simd_unit.coefficients) } + #[inline(always)] fn error_deserialize(serialized: &[u8]) -> Self { encoding::error::deserialize::(serialized).into() } + #[inline(always)] fn t0_serialize(simd_unit: Self) -> [u8; 13] { encoding::t0::serialize(simd_unit.coefficients) } + #[inline(always)] fn t0_deserialize(serialized: &[u8]) -> Self { encoding::t0::deserialize(serialized).into() } + #[inline(always)] fn t1_serialize(simd_unit: Self) -> [u8; 10] { encoding::t1::serialize(simd_unit.coefficients) } + #[inline(always)] fn t1_deserialize(serialized: &[u8]) -> Self { encoding::t1::deserialize(serialized).into() } + #[inline(always)] fn ntt(simd_units: [Self; SIMD_UNITS_IN_RING_ELEMENT]) -> [Self; SIMD_UNITS_IN_RING_ELEMENT] { let result = ntt::ntt(simd_units.map(|x| x.coefficients)); result.map(|x| x.into()) } - fn invert_ntt_at_layer_0( - simd_unit: Self, - zeta0: i32, - zeta1: i32, - zeta2: i32, - zeta3: i32, - ) -> Self { - ntt::invert_ntt_at_layer_0(simd_unit.coefficients, zeta0, zeta1, zeta2, zeta3).into() - } - fn invert_ntt_at_layer_1(simd_unit: Self, zeta0: i32, zeta1: i32) -> Self { - ntt::invert_ntt_at_layer_1(simd_unit.coefficients, zeta0, zeta1).into() - } - fn invert_ntt_at_layer_2(simd_unit: Self, zeta: i32) -> Self { - ntt::invert_ntt_at_layer_2(simd_unit.coefficients, zeta).into() + #[inline(always)] + fn invert_ntt_montgomery( + simd_units: [Self; SIMD_UNITS_IN_RING_ELEMENT], + ) -> [Self; SIMD_UNITS_IN_RING_ELEMENT] { + let result = invntt::invert_ntt_montgomery(simd_units.map(|x| x.coefficients)); + + result.map(|x| x.into()) } } diff --git a/libcrux-ml-dsa/src/simd/avx2/invntt.rs b/libcrux-ml-dsa/src/simd/avx2/invntt.rs new file mode 100644 index 000000000..4d01c7fe1 --- /dev/null +++ b/libcrux-ml-dsa/src/simd/avx2/invntt.rs @@ -0,0 +1,346 @@ +use super::arithmetic; +use crate::simd::traits::{COEFFICIENTS_IN_SIMD_UNIT, SIMD_UNITS_IN_RING_ELEMENT}; + +use libcrux_intrinsics::avx2::*; + +#[inline(always)] +#[allow(unsafe_code)] +pub(crate) fn invert_ntt_montgomery( + mut re: [Vec256; SIMD_UNITS_IN_RING_ELEMENT], +) -> [Vec256; SIMD_UNITS_IN_RING_ELEMENT] { + unsafe { + invert_ntt_at_layer_0(&mut re); + invert_ntt_at_layer_1(&mut re); + invert_ntt_at_layer_2(&mut re); + invert_ntt_at_layer_3(&mut re); + invert_ntt_at_layer_4(&mut re); + invert_ntt_at_layer_5(&mut re); + invert_ntt_at_layer_6(&mut re); + invert_ntt_at_layer_7(&mut re); + } + for i in 0..re.len() { + // After invert_ntt_at_layer, elements are of the form a * MONTGOMERY_R^{-1} + // we multiply by (MONTGOMERY_R^2) * (1/2^8) mod Q = 41,978 to both: + // + // - Divide the elements by 256 and + // - Convert the elements form montgomery domain to the standard domain. + re[i] = arithmetic::montgomery_multiply_by_constant(re[i], 41_978); + } + + re +} + +#[inline(always)] +fn simd_unit_invert_ntt_at_layer_0( + simd_unit0: Vec256, + simd_unit1: Vec256, + zeta00: i32, + zeta01: i32, + zeta02: i32, + zeta03: i32, + zeta10: i32, + zeta11: i32, + zeta12: i32, + zeta13: i32, +) -> (Vec256, Vec256) { + const SHUFFLE: i32 = 0b11_01_10_00; + let a_shuffled = mm256_shuffle_epi32::(simd_unit0); + let b_shuffled = mm256_shuffle_epi32::(simd_unit1); + + let lo_values = mm256_unpacklo_epi64(a_shuffled, b_shuffled); + let hi_values = mm256_unpackhi_epi64(a_shuffled, b_shuffled); + + let sums = arithmetic::add(lo_values, hi_values); + let differences = arithmetic::subtract(hi_values, lo_values); + + let zetas = mm256_set_epi32( + zeta13, zeta12, zeta03, zeta02, zeta11, zeta10, zeta01, zeta00, + ); + let products = arithmetic::montgomery_multiply(differences, zetas); + + let a_shuffled = mm256_unpacklo_epi64(sums, products); + let b_shuffled = mm256_unpackhi_epi64(sums, products); + + let a = mm256_shuffle_epi32::(a_shuffled); + let b = mm256_shuffle_epi32::(b_shuffled); + + (a, b) +} + +#[inline(always)] +fn simd_unit_invert_ntt_at_layer_1( + simd_unit0: Vec256, + simd_unit1: Vec256, + zeta00: i32, + zeta01: i32, + zeta10: i32, + zeta11: i32, +) -> (Vec256, Vec256) { + let lo_values = mm256_unpacklo_epi64(simd_unit0, simd_unit1); + let hi_values = mm256_unpackhi_epi64(simd_unit0, simd_unit1); + + let sums = arithmetic::add(lo_values, hi_values); + let differences = arithmetic::subtract(hi_values, lo_values); + + let zetas = mm256_set_epi32( + zeta11, zeta11, zeta01, zeta01, zeta10, zeta10, zeta00, zeta00, + ); + let products = arithmetic::montgomery_multiply(differences, zetas); + + let a = mm256_unpacklo_epi64(sums, products); + let b = mm256_unpackhi_epi64(sums, products); + + (a, b) +} + +#[inline(always)] +fn simd_unit_invert_ntt_at_layer_2( + simd_unit0: Vec256, + simd_unit1: Vec256, + zeta0: i32, + zeta1: i32, +) -> (Vec256, Vec256) { + let lo_values = mm256_permute2x128_si256::<0x20>(simd_unit0, simd_unit1); + let hi_values = mm256_permute2x128_si256::<0x31>(simd_unit0, simd_unit1); + + let sums = arithmetic::add(lo_values, hi_values); + let differences = arithmetic::subtract(hi_values, lo_values); + + let zetas = mm256_set_epi32(zeta1, zeta1, zeta1, zeta1, zeta0, zeta0, zeta0, zeta0); + let products = arithmetic::montgomery_multiply(differences, zetas); + + let a = mm256_permute2x128_si256::<0x20>(sums, products); + let b = mm256_permute2x128_si256::<0x31>(sums, products); + + (a, b) +} + +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn invert_ntt_at_layer_0(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta00: i32, + zeta01: i32, + zeta02: i32, + zeta03: i32, + zeta10: i32, + zeta11: i32, + zeta12: i32, + zeta13: i32, + ) { + (re[index], re[index + 1]) = simd_unit_invert_ntt_at_layer_0( + re[index], + re[index + 1], + zeta00, + zeta01, + zeta02, + zeta03, + zeta10, + zeta11, + zeta12, + zeta13, + ); + } + + round( + re, 0, 1976782, -846154, 1400424, 3937738, -1362209, -48306, 3919660, -554416, + ); + round( + re, 2, -3545687, 1612842, -976891, 183443, -2286327, -420899, -2235985, -2939036, + ); + round( + re, 4, -3833893, -260646, -1104333, -1667432, 1910376, -1803090, 1723600, -426683, + ); + round( + re, 6, 472078, 1717735, -975884, 2213111, 269760, 3866901, 3523897, -3038916, + ); + round( + re, 8, -1799107, -3694233, 1652634, 810149, 3014001, 1616392, 162844, -3183426, + ); + round( + re, 10, -1207385, 185531, 3369112, 1957272, -164721, 2454455, 2432395, -2013608, + ); + round( + re, 12, -3776993, 594136, -3724270, -2584293, -1846953, -1671176, -2831860, -542412, + ); + round( + re, 14, 3406031, 2235880, 777191, 1500165, -1374803, -2546312, 1917081, -1279661, + ); + round( + re, 16, -1962642, 3306115, 1312455, -451100, -1430225, -3318210, 1237275, -1333058, + ); + round( + re, 18, -1050970, 1903435, 1869119, -2994039, -3548272, 2635921, 1250494, -3767016, + ); + round( + re, 20, 1595974, 2486353, 1247620, 4055324, 1265009, -2590150, 2691481, 2842341, + ); + round( + re, 22, 203044, 1735879, -3342277, 3437287, 4108315, -2437823, 286988, 342297, + ); + round( + re, 24, -3595838, -768622, -525098, -3556995, 3207046, 2031748, -3122442, -655327, + ); + round( + re, 26, -522500, -43260, -1613174, 495491, 819034, 909542, 1859098, 900702, + ); + round( + re, 28, -3193378, -1197226, -3759364, -3520352, 3513181, -1235728, 2434439, 266997, + ); + round( + re, 30, -3562462, -2446433, 2244091, -3342478, 3817976, 2316500, 3407706, 2091667, + ); +} + +#[allow(unsafe_code)] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +unsafe fn invert_ntt_at_layer_1(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta_00: i32, + zeta_01: i32, + zeta_10: i32, + zeta_11: i32, + ) { + (re[index], re[index + 1]) = simd_unit_invert_ntt_at_layer_1( + re[index], + re[index + 1], + zeta_00, + zeta_01, + zeta_10, + zeta_11, + ); + } + + round(re, 0, 3839961, -3628969, -3881060, -3019102); + round(re, 2, -1439742, -812732, -1584928, 1285669); + round(re, 4, 1341330, 1315589, -177440, -2409325); + round(re, 6, -1851402, 3159746, -3553272, 189548); + round(re, 8, -1316856, 759969, -210977, 2389356); + round(re, 10, -3249728, 1653064, -8578, -3724342); + round(re, 12, 3958618, 904516, -1100098, 44288); + round(re, 14, 3097992, 508951, 264944, -3343383); + round(re, 16, -1430430, 1852771, 1349076, -381987); + round(re, 18, -1308169, -22981, -1228525, -671102); + round(re, 20, -2477047, -411027, -3693493, -2967645); + round(re, 22, 2715295, 2147896, -983419, 3412210); + round(re, 24, 126922, -3632928, -3157330, -3190144); + round(re, 26, -1000202, -4083598, 1939314, -1257611); + round(re, 28, -1585221, 2176455, 3475950, -1452451); + round(re, 30, -3041255, -3677745, -1528703, -3930395); +} + +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn invert_ntt_at_layer_2(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], index: usize, zeta1: i32, zeta2: i32) { + (re[index], re[index + 1]) = + simd_unit_invert_ntt_at_layer_2(re[index], re[index + 1], zeta1, zeta2); + } + + round(re, 0, -2797779, 2071892); + round(re, 2, -2556880, 3900724); + round(re, 4, 3881043, 954230); + round(re, 6, 531354, 811944); + round(re, 8, 3699596, -1600420); + round(re, 10, -2140649, 3507263); + round(re, 12, -3821735, 3505694); + round(re, 14, -1643818, -1699267); + round(re, 16, -539299, 2348700); + round(re, 18, -300467, 3539968); + round(re, 20, -2867647, 3574422); + round(re, 22, -3043716, -3861115); + round(re, 24, 3915439, -2537516); + round(re, 26, -3592148, -1661693); + round(re, 28, 3530437, 3077325); + round(re, 30, 95776, 2706023); +} + +#[inline(always)] +fn outer_3_plus( + re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], +) { + for j in OFFSET..OFFSET + STEP_BY { + let a_minus_b = arithmetic::subtract(re[j + STEP_BY], re[j]); + re[j] = arithmetic::add(re[j], re[j + STEP_BY]); + re[j + STEP_BY] = arithmetic::montgomery_multiply_by_constant(a_minus_b, ZETA); + } + () +} + +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn invert_ntt_at_layer_3(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 8; // 1 << LAYER; + const STEP_BY: usize = 1; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 280005>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 4010497>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -19422>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1757237>(re); + outer_3_plus::<{ (4 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -3277672>(re); + outer_3_plus::<{ (5 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1399561>(re); + outer_3_plus::<{ (6 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -3859737>(re); + outer_3_plus::<{ (7 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2118186>(re); + outer_3_plus::<{ (8 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2108549>(re); + outer_3_plus::<{ (9 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2619752>(re); + outer_3_plus::<{ (10 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1119584>(re); + outer_3_plus::<{ (11 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -549488>(re); + outer_3_plus::<{ (12 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3585928>(re); + outer_3_plus::<{ (13 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1079900>(re); + outer_3_plus::<{ (14 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1024112>(re); + outer_3_plus::<{ (15 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2725464>(re); +} + +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn invert_ntt_at_layer_4(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 16; // 1 << LAYER; + const STEP_BY: usize = 2; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2680103>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3111497>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2884855>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3119733>(re); + outer_3_plus::<{ (4 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2091905>(re); + outer_3_plus::<{ (5 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -359251>(re); + outer_3_plus::<{ (6 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2353451>(re); + outer_3_plus::<{ (7 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1826347>(re); +} + +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn invert_ntt_at_layer_5(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 32; // 1 << LAYER; + const STEP_BY: usize = 4; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 466468>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -876248>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -777960>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 237124>(re); +} + +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn invert_ntt_at_layer_6(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 64; // 1 << LAYER; + const STEP_BY: usize = 8; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -518909>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2608894>(re); +} + +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn invert_ntt_at_layer_7(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 128; // 1 << LAYER; + const STEP_BY: usize = 16; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 25847>(re); +} diff --git a/libcrux-ml-dsa/src/simd/avx2/ntt.rs b/libcrux-ml-dsa/src/simd/avx2/ntt.rs index c6f302155..799eb0247 100644 --- a/libcrux-ml-dsa/src/simd/avx2/ntt.rs +++ b/libcrux-ml-dsa/src/simd/avx2/ntt.rs @@ -1,7 +1,5 @@ use super::arithmetic; -use crate::simd::traits::{ - COEFFICIENTS_IN_SIMD_UNIT, SIMD_UNITS_IN_RING_ELEMENT, ZETAS_TIMES_MONTGOMERY_R, -}; +use crate::simd::traits::{COEFFICIENTS_IN_SIMD_UNIT, SIMD_UNITS_IN_RING_ELEMENT}; use libcrux_intrinsics::avx2::*; @@ -102,158 +100,352 @@ fn butterfly_8(a: Vec256, b: Vec256, zeta0: i32, zeta1: i32) -> (Vec256, Vec256) (a_out, b_out) } -#[inline(always)] -pub fn invert_ntt_at_layer_0( - simd_unit: Vec256, - zeta0: i32, - zeta1: i32, - zeta2: i32, - zeta3: i32, -) -> Vec256 { - let zetas = mm256_set_epi32(zeta3, 0, zeta2, 0, zeta1, 0, zeta0, 0); - - let add_by_signs = mm256_set_epi32(-1, 1, -1, 1, -1, 1, -1, 1); - let add_by = mm256_shuffle_epi32::<0b10_11_00_01>(simd_unit); - let add_by = mm256_mullo_epi32(add_by, add_by_signs); - - let sums = mm256_add_epi32(simd_unit, add_by); - - let products = arithmetic::montgomery_multiply(sums, zetas); - - mm256_blend_epi32::<0b1_0_1_0_1_0_1_0>(sums, products) -} - -#[inline(always)] -fn ntt_at_layer_0(zeta_i: &mut usize, re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { - *zeta_i += 1; - for round in (0..re.len()).step_by(2) { +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn ntt_at_layer_0(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta_0: i32, + zeta_1: i32, + zeta_2: i32, + zeta_3: i32, + zeta_4: i32, + zeta_5: i32, + zeta_6: i32, + zeta_7: i32, + ) { let (a, b) = butterfly_2( - re[round], - re[round + 1], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 1], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 2], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 3], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 4], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 5], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 6], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 7], + re[index], + re[index + 1], + zeta_0, + zeta_1, + zeta_2, + zeta_3, + zeta_4, + zeta_5, + zeta_6, + zeta_7, ); - re[round] = a; - re[round + 1] = b; - - *zeta_i += 8; + re[index] = a; + re[index + 1] = b; } - *zeta_i -= 1; + round( + re, 0, 2091667, 3407706, 2316500, 3817976, -3342478, 2244091, -2446433, -3562462, + ); + round( + re, 2, 266997, 2434439, -1235728, 3513181, -3520352, -3759364, -1197226, -3193378, + ); + round( + re, 4, 900702, 1859098, 909542, 819034, 495491, -1613174, -43260, -522500, + ); + round( + re, 6, -655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838, + ); + round( + re, 8, 342297, 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044, + ); + round( + re, 10, 2842341, 2691481, -2590150, 1265009, 4055324, 1247620, 2486353, 1595974, + ); + round( + re, 12, -3767016, 1250494, 2635921, -3548272, -2994039, 1869119, 1903435, -1050970, + ); + round( + re, 14, -1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, -1962642, + ); + round( + re, 16, -1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031, + ); + round( + re, 18, -542412, -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993, + ); + round( + re, 20, -2013608, 2432395, 2454455, -164721, 1957272, 3369112, 185531, -1207385, + ); + round( + re, 22, -3183426, 162844, 1616392, 3014001, 810149, 1652634, -3694233, -1799107, + ); + round( + re, 24, -3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, 472078, + ); + round( + re, 26, -426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893, + ); + round( + re, 28, -2939036, -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687, + ); + round( + re, 30, -554416, 3919660, -48306, -1362209, 3937738, 1400424, -846154, 1976782, + ); } -#[inline(always)] -pub fn invert_ntt_at_layer_1(simd_unit: Vec256, zeta0: i32, zeta1: i32) -> Vec256 { - let zetas = mm256_set_epi32(zeta1, zeta1, 0, 0, zeta0, zeta0, 0, 0); - - let add_by_signs = mm256_set_epi32(-1, -1, 1, 1, -1, -1, 1, 1); - let add_by = mm256_shuffle_epi32::<0b01_00_11_10>(simd_unit); - let add_by = mm256_mullo_epi32(add_by, add_by_signs); +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn ntt_at_layer_1(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta_0: i32, + zeta_1: i32, + zeta_2: i32, + zeta_3: i32, + ) { + let (a, b) = butterfly_4(re[index], re[index + 1], zeta_0, zeta_1, zeta_2, zeta_3); + re[index] = a; + re[index + 1] = b; + } - let sums = mm256_add_epi32(simd_unit, add_by); + round(re, 0, -3930395, -1528703, -3677745, -3041255); + round(re, 2, -1452451, 3475950, 2176455, -1585221); + round(re, 4, -1257611, 1939314, -4083598, -1000202); + round(re, 6, -3190144, -3157330, -3632928, 126922); + round(re, 8, 3412210, -983419, 2147896, 2715295); + round(re, 10, -2967645, -3693493, -411027, -2477047); + round(re, 12, -671102, -1228525, -22981, -1308169); + round(re, 14, -381987, 1349076, 1852771, -1430430); + round(re, 16, -3343383, 264944, 508951, 3097992); + round(re, 18, 44288, -1100098, 904516, 3958618); + round(re, 20, -3724342, -8578, 1653064, -3249728); + round(re, 22, 2389356, -210977, 759969, -1316856); + round(re, 24, 189548, -3553272, 3159746, -1851402); + round(re, 26, -2409325, -177440, 1315589, 1341330); + round(re, 28, 1285669, -1584928, -812732, -1439742); + round(re, 30, -3019102, -3881060, -3628969, 3839961); +} - let products = arithmetic::montgomery_multiply(sums, zetas); +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn ntt_at_layer_2(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta_0: i32, + zeta_1: i32, + ) { + let (a, b) = butterfly_8(re[index], re[index + 1], zeta_0, zeta_1); + re[index] = a; + re[index + 1] = b; + } - mm256_blend_epi32::<0b1_1_0_0_1_1_0_0>(sums, products) + round(re, 0, 2706023, 95776); + round(re, 2, 3077325, 3530437); + round(re, 4, -1661693, -3592148); + round(re, 6, -2537516, 3915439); + round(re, 8, -3861115, -3043716); + round(re, 10, 3574422, -2867647); + round(re, 12, 3539968, -300467); + round(re, 14, 2348700, -539299); + round(re, 16, -1699267, -1643818); + round(re, 18, 3505694, -3821735); + round(re, 20, 3507263, -2140649); + round(re, 22, -1600420, 3699596); + round(re, 24, 811944, 531354); + round(re, 26, 954230, 3881043); + round(re, 28, 3900724, -2556880); + round(re, 30, 2071892, -2797779); } -#[inline(always)] -fn ntt_at_layer_1(zeta_i: &mut usize, re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { - *zeta_i += 1; - for round in (0..re.len()).step_by(2) { - let (a, b) = butterfly_4( - re[round], - re[round + 1], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 1], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 2], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 3], +/// This is equivalent to the pqclean 0 and 1 +/// +/// This does 32 Montgomery multiplications (192 multiplications). +/// This is the same as in pqclean. The only difference is locality of registers. +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn ntt_at_layer_7_and_6(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + let field_modulus = mm256_set1_epi32(crate::simd::traits::FIELD_MODULUS); + let inverse_of_modulus_mod_montgomery_r = + mm256_set1_epi32(crate::simd::traits::INVERSE_OF_MODULUS_MOD_MONTGOMERY_R as i32); + + #[inline(always)] + fn mul( + re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta: Vec256, + step_by: usize, + field_modulus: Vec256, + inverse_of_modulus_mod_montgomery_r: Vec256, + ) { + let prod02 = mm256_mul_epi32(re[index + step_by], zeta); + let prod13 = mm256_mul_epi32( + mm256_shuffle_epi32::<0b11_11_01_01>(re[index + step_by]), // 0xF5 + mm256_shuffle_epi32::<0b11_11_01_01>(zeta), // 0xF5 ); - re[round] = a; - re[round + 1] = b; + let k02 = mm256_mul_epi32(prod02, inverse_of_modulus_mod_montgomery_r); + let k13 = mm256_mul_epi32(prod13, inverse_of_modulus_mod_montgomery_r); - *zeta_i += 4; - } + let c02 = mm256_mul_epi32(k02, field_modulus); + let c13 = mm256_mul_epi32(k13, field_modulus); - *zeta_i -= 1; -} + let res02 = mm256_sub_epi32(prod02, c02); + let res13 = mm256_sub_epi32(prod13, c13); + let res02_shifted = mm256_shuffle_epi32::<0b11_11_01_01>(res02); // 0xF5 + let t = mm256_blend_epi32::<0b10101010>(res02_shifted, res13); // 0xAA -#[inline(always)] -pub fn invert_ntt_at_layer_2(simd_unit: Vec256, zeta: i32) -> Vec256 { - let zetas = mm256_set_epi32(zeta, zeta, zeta, zeta, 0, 0, 0, 0); + re[index + step_by] = arithmetic::subtract(re[index], t); + re[index] = arithmetic::add(re[index], t); + } + + macro_rules! layer { + ($start:literal, $zeta:expr, $step_by:expr) => {{ + mul( + re, + $start, + $zeta, + $step_by, + field_modulus, + inverse_of_modulus_mod_montgomery_r, + ); + mul( + re, + $start + 1, + $zeta, + $step_by, + field_modulus, + inverse_of_modulus_mod_montgomery_r, + ); + mul( + re, + $start + 2, + $zeta, + $step_by, + field_modulus, + inverse_of_modulus_mod_montgomery_r, + ); + mul( + re, + $start + 3, + $zeta, + $step_by, + field_modulus, + inverse_of_modulus_mod_montgomery_r, + ); + }}; + } - let add_by_signs = mm256_set_epi32(-1, -1, -1, -1, 1, 1, 1, 1); - let add_by = mm256_permute4x64_epi64::<0b01_00_11_10>(simd_unit); - let add_by = mm256_mullo_epi32(add_by, add_by_signs); + const STEP_BY_7: usize = 2 * COEFFICIENTS_IN_SIMD_UNIT; + const STEP_BY_6: usize = (1 << 6) / COEFFICIENTS_IN_SIMD_UNIT; - let sums = mm256_add_epi32(simd_unit, add_by); + let zeta7 = mm256_set1_epi32(25847); + let zeta60 = mm256_set1_epi32(-2608894); + let zeta61 = mm256_set1_epi32(-518909); - let products = arithmetic::montgomery_multiply(sums, zetas); + layer!(0, zeta7, STEP_BY_7); + layer!(8, zeta7, STEP_BY_7); + layer!(0, zeta60, STEP_BY_6); + layer!(16, zeta61, STEP_BY_6); - mm256_blend_epi32::<0b1_1_1_1_0_0_0_0>(sums, products) + layer!(4, zeta7, STEP_BY_7); + layer!(12, zeta7, STEP_BY_7); + layer!(4, zeta60, STEP_BY_6); + layer!(20, zeta61, STEP_BY_6); } -#[inline(always)] -fn ntt_at_layer_2(zeta_i: &mut usize, re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { - for round in (0..re.len()).step_by(2) { - *zeta_i += 1; - let (a, b) = butterfly_8( - re[round], - re[round + 1], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 1], - ); - re[round] = a; - re[round + 1] = b; +/// Layer 5, 4, 3 +/// +/// Each layer does 16 Montgomery multiplications -> 3*16 = 48 total +/// pqclean does 4 * 4 on each layer -> 48 total | plus 4 * 4 shuffles every time (48) +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[allow(unsafe_code)] +unsafe fn ntt_at_layer_5_to_3(re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta: i32, + ) { + let rhs = mm256_set1_epi32(zeta); + let offset = (index * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT; + + for j in offset..offset + STEP_BY { + let t = arithmetic::montgomery_multiply(re[j + STEP_BY], rhs); + + re[j + STEP_BY] = arithmetic::subtract(re[j], t); + re[j] = arithmetic::add(re[j], t); + } + () // Needed because of https://github.com/hacspec/hax/issues/720 + } - *zeta_i += 1; + // Layer 5 + { + // 0: 0, 1, 2, 3 + // 1: 8, 9, 10, 11 + // 2: 16, 17, 18, 19 + // 3: 24, 25, 26, 27 + const STEP: usize = 1 << 5; + const STEP_BY: usize = STEP / COEFFICIENTS_IN_SIMD_UNIT; + + round::(re, 0, 237124); + round::(re, 1, -777960); + round::(re, 2, -876248); + round::(re, 3, 466468); } -} -#[inline(always)] -fn ntt_at_layer_3_plus( - zeta_i: &mut usize, - re: &mut [Vec256; SIMD_UNITS_IN_RING_ELEMENT], -) { - let step = 1 << LAYER; - - for round in 0..(128 >> LAYER) { - *zeta_i += 1; - - let offset = (round * step * 2) / COEFFICIENTS_IN_SIMD_UNIT; - let step_by = step / COEFFICIENTS_IN_SIMD_UNIT; - - for j in offset..offset + step_by { - let t = arithmetic::montgomery_multiply_by_constant( - re[j + step_by], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ); + // Layer 4 + { + // 0: 0, 1 + // 1: 4, 5 + // 2: 8, 9 + // 3: 12, 13 + // 4: 16, 17 + // 5: 20, 21 + // 6: 24, 25 + // 7: 28, 29 + const STEP: usize = 1 << 4; + const STEP_BY: usize = STEP / COEFFICIENTS_IN_SIMD_UNIT; + + round::(re, 0, 1826347); + round::(re, 1, 2353451); + round::(re, 2, -359251); + round::(re, 3, -2091905); + round::(re, 4, 3119733); + round::(re, 5, -2884855); + round::(re, 6, 3111497); + round::(re, 7, 2680103); + } - re[j + step_by] = arithmetic::subtract(re[j], t); - re[j] = arithmetic::add(re[j], t); - } + // Layer 3 + { + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + const STEP: usize = 1 << 3; + const STEP_BY: usize = STEP / COEFFICIENTS_IN_SIMD_UNIT; + + round::(re, 0, 2725464); + round::(re, 1, 1024112); + round::(re, 2, -1079900); + round::(re, 3, 3585928); + round::(re, 4, -549488); + round::(re, 5, -1119584); + round::(re, 6, 2619752); + round::(re, 7, -2108549); + round::(re, 8, -2118186); + round::(re, 9, -3859737); + round::(re, 10, -1399561); + round::(re, 11, -3277672); + round::(re, 12, 1757237); + round::(re, 13, -19422); + round::(re, 14, 4010497); + round::(re, 15, 280005); } + () } +#[allow(unsafe_code)] #[inline(always)] pub(crate) fn ntt( mut re: [Vec256; SIMD_UNITS_IN_RING_ELEMENT], ) -> [Vec256; SIMD_UNITS_IN_RING_ELEMENT] { - let mut zeta_i = 0; - ntt_at_layer_3_plus::<7>(&mut zeta_i, &mut re); - ntt_at_layer_3_plus::<6>(&mut zeta_i, &mut re); - ntt_at_layer_3_plus::<5>(&mut zeta_i, &mut re); - ntt_at_layer_3_plus::<4>(&mut zeta_i, &mut re); - ntt_at_layer_3_plus::<3>(&mut zeta_i, &mut re); - ntt_at_layer_2(&mut zeta_i, &mut re); - ntt_at_layer_1(&mut zeta_i, &mut re); - ntt_at_layer_0(&mut zeta_i, &mut re); + unsafe { + ntt_at_layer_7_and_6(&mut re); + ntt_at_layer_5_to_3(&mut re); + ntt_at_layer_2(&mut re); + ntt_at_layer_1(&mut re); + ntt_at_layer_0(&mut re); + } re } diff --git a/libcrux-ml-dsa/src/simd/avx2/vector_type.rs b/libcrux-ml-dsa/src/simd/avx2/vector_type.rs new file mode 100644 index 000000000..13fa15372 --- /dev/null +++ b/libcrux-ml-dsa/src/simd/avx2/vector_type.rs @@ -0,0 +1,25 @@ +#[derive(Clone, Copy)] +pub struct AVX2SIMDUnit { + pub(crate) coefficients: libcrux_intrinsics::avx2::Vec256, +} + +impl From for AVX2SIMDUnit { + fn from(coefficients: libcrux_intrinsics::avx2::Vec256) -> Self { + Self { coefficients } + } +} + +#[allow(non_snake_case)] +pub(crate) fn ZERO() -> AVX2SIMDUnit { + libcrux_intrinsics::avx2::mm256_setzero_si256().into() +} + +pub(crate) fn from_coefficient_array(coefficient_array: &[i32]) -> AVX2SIMDUnit { + libcrux_intrinsics::avx2::mm256_loadu_si256_i32(coefficient_array).into() +} + +pub(crate) fn to_coefficient_array(x: &AVX2SIMDUnit) -> [i32; 8] { + let mut coefficient_array = [0i32; 8]; + libcrux_intrinsics::avx2::mm256_storeu_si256_i32(&mut coefficient_array, x.coefficients); + coefficient_array +} diff --git a/libcrux-ml-dsa/src/simd/portable.rs b/libcrux-ml-dsa/src/simd/portable.rs index 05098b5c7..f0c02d10e 100644 --- a/libcrux-ml-dsa/src/simd/portable.rs +++ b/libcrux-ml-dsa/src/simd/portable.rs @@ -1,34 +1,27 @@ -use crate::simd::traits::{Operations, COEFFICIENTS_IN_SIMD_UNIT, SIMD_UNITS_IN_RING_ELEMENT}; +use crate::simd::traits::{Operations, SIMD_UNITS_IN_RING_ELEMENT}; mod arithmetic; - +mod vector_type; // Some of the portable implementations are used in lieu of vectorized ones in // the AVX2 module. pub(crate) mod encoding; - +mod invntt; mod ntt; mod sample; -#[derive(Clone, Copy)] -pub struct PortableSIMDUnit { - pub(crate) coefficients: [arithmetic::FieldElement; COEFFICIENTS_IN_SIMD_UNIT], -} +pub(crate) use vector_type::PortableSIMDUnit; impl Operations for PortableSIMDUnit { fn ZERO() -> Self { - PortableSIMDUnit { - coefficients: [0i32; COEFFICIENTS_IN_SIMD_UNIT], - } + vector_type::ZERO() } fn from_coefficient_array(array: &[i32]) -> Self { - PortableSIMDUnit { - coefficients: array[0..8].try_into().unwrap(), - } + vector_type::from_coefficient_array(array) } fn to_coefficient_array(&self) -> [i32; 8] { - self.coefficients.try_into().unwrap() + vector_type::to_coefficient_array(&self) } fn add(lhs: &Self, rhs: &Self) -> Self { @@ -39,12 +32,10 @@ impl Operations for PortableSIMDUnit { arithmetic::subtract(lhs, rhs) } - fn montgomery_multiply_by_constant(simd_unit: Self, c: i32) -> Self { - arithmetic::montgomery_multiply_by_constant(simd_unit, c) - } fn montgomery_multiply(lhs: Self, rhs: Self) -> Self { arithmetic::montgomery_multiply(&lhs, &rhs) } + fn shift_left_then_reduce(simd_unit: Self) -> Self { arithmetic::shift_left_then_reduce::(simd_unit) } @@ -114,19 +105,9 @@ impl Operations for PortableSIMDUnit { ntt::ntt(simd_units) } - fn invert_ntt_at_layer_0( - simd_unit: Self, - zeta0: i32, - zeta1: i32, - zeta2: i32, - zeta3: i32, - ) -> Self { - ntt::invert_ntt_at_layer_0(simd_unit, zeta0, zeta1, zeta2, zeta3) - } - fn invert_ntt_at_layer_1(simd_unit: Self, zeta0: i32, zeta1: i32) -> Self { - ntt::invert_ntt_at_layer_1(simd_unit, zeta0, zeta1) - } - fn invert_ntt_at_layer_2(simd_unit: Self, zeta: i32) -> Self { - ntt::invert_ntt_at_layer_2(simd_unit, zeta) + fn invert_ntt_montgomery( + simd_units: [Self; SIMD_UNITS_IN_RING_ELEMENT], + ) -> [Self; SIMD_UNITS_IN_RING_ELEMENT] { + invntt::invert_ntt_montgomery(simd_units) } } diff --git a/libcrux-ml-dsa/src/simd/portable/arithmetic.rs b/libcrux-ml-dsa/src/simd/portable/arithmetic.rs index 1785d108e..f4c269470 100644 --- a/libcrux-ml-dsa/src/simd/portable/arithmetic.rs +++ b/libcrux-ml-dsa/src/simd/portable/arithmetic.rs @@ -1,28 +1,16 @@ +use super::vector_type::{FieldElement, PortableSIMDUnit, ZERO}; use crate::{ constants::BITS_IN_LOWER_PART_OF_T, - simd::{ - portable::PortableSIMDUnit, - traits::{ - FieldElementTimesMontgomeryR, Operations, FIELD_MODULUS, - INVERSE_OF_MODULUS_MOD_MONTGOMERY_R, - }, + simd::traits::{ + FieldElementTimesMontgomeryR, FIELD_MODULUS, INVERSE_OF_MODULUS_MOD_MONTGOMERY_R, }, }; -/// Values having this type hold a representative 'x' of the Kyber field. -/// We use 'fe' as a shorthand for this type. -pub(crate) type FieldElement = i32; - -/// If 'x' denotes a value of type `fe`, values having this type hold a -/// representative y ≡ x·MONTGOMERY_R^(-1) (mod FIELD_MODULUS). -/// We use 'mfe' as a shorthand for this type -pub type MontgomeryFieldElement = i32; - pub(crate) const MONTGOMERY_SHIFT: u8 = 32; #[inline(always)] pub fn add(lhs: &PortableSIMDUnit, rhs: &PortableSIMDUnit) -> PortableSIMDUnit { - let mut sum = PortableSIMDUnit::ZERO(); + let mut sum = ZERO(); for i in 0..sum.coefficients.len() { sum.coefficients[i] = lhs.coefficients[i] + rhs.coefficients[i]; @@ -33,7 +21,7 @@ pub fn add(lhs: &PortableSIMDUnit, rhs: &PortableSIMDUnit) -> PortableSIMDUnit { #[inline(always)] pub fn subtract(lhs: &PortableSIMDUnit, rhs: &PortableSIMDUnit) -> PortableSIMDUnit { - let mut difference = PortableSIMDUnit::ZERO(); + let mut difference = ZERO(); for i in 0..difference.coefficients.len() { difference.coefficients[i] = lhs.coefficients[i] - rhs.coefficients[i]; @@ -47,7 +35,7 @@ pub(crate) fn get_n_least_significant_bits(n: u8, value: u64) -> u64 { value & ((1 << n) - 1) } #[inline(always)] -pub(crate) fn montgomery_reduce_element(value: i64) -> MontgomeryFieldElement { +pub(crate) fn montgomery_reduce_element(value: i64) -> FieldElementTimesMontgomeryR { let t = get_n_least_significant_bits(MONTGOMERY_SHIFT, value as u64) * INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; let k = get_n_least_significant_bits(MONTGOMERY_SHIFT, t) as i32; @@ -86,7 +74,7 @@ pub(crate) fn montgomery_multiply( lhs: &PortableSIMDUnit, rhs: &PortableSIMDUnit, ) -> PortableSIMDUnit { - let mut product = PortableSIMDUnit::ZERO(); + let mut product = ZERO(); for i in 0..product.coefficients.len() { product.coefficients[i] = @@ -106,7 +94,8 @@ pub(crate) fn montgomery_multiply( // to the standard unsigned range. #[inline(always)] fn power2round_element(t: i32) -> (i32, i32) { - debug_assert!(t > -FIELD_MODULUS && t < FIELD_MODULUS, "t is {}", t); + // Hax issue: https://github.com/hacspec/hax/issues/1082 + debug_assert!(t > -FIELD_MODULUS && t < FIELD_MODULUS); // Convert the signed representative to the standard unsigned one. let t = t + ((t >> 31) & FIELD_MODULUS); @@ -123,8 +112,8 @@ fn power2round_element(t: i32) -> (i32, i32) { } pub fn power2round(simd_unit: PortableSIMDUnit) -> (PortableSIMDUnit, PortableSIMDUnit) { - let mut t0_simd_unit = PortableSIMDUnit::ZERO(); - let mut t1_simd_unit = PortableSIMDUnit::ZERO(); + let mut t0_simd_unit = ZERO(); + let mut t1_simd_unit = ZERO(); for (i, t) in simd_unit.coefficients.into_iter().enumerate() { let (t0, t1) = power2round_element(t); @@ -150,11 +139,7 @@ pub fn infinity_norm_exceeds(simd_unit: PortableSIMDUnit, bound: i32) -> bool { // straightforward way to do so (returning false) will not go through hax; // revisit if performance is impacted. for coefficient in simd_unit.coefficients.into_iter() { - debug_assert!( - coefficient > -FIELD_MODULUS && coefficient < FIELD_MODULUS, - "coefficient is {}", - coefficient - ); + debug_assert!(coefficient > -FIELD_MODULUS && coefficient < FIELD_MODULUS); // This norm is calculated using the absolute value of the // signed representative in the range: // @@ -165,7 +150,7 @@ pub fn infinity_norm_exceeds(simd_unit: PortableSIMDUnit, bound: i32) -> bool { let sign = coefficient >> 31; let normalized = coefficient - (sign & (2 * coefficient)); - exceeds |= normalized >= bound; + exceeds = exceeds || normalized >= bound; } exceeds @@ -182,7 +167,7 @@ fn reduce_element(fe: FieldElement) -> FieldElement { pub fn shift_left_then_reduce( simd_unit: PortableSIMDUnit, ) -> PortableSIMDUnit { - let mut out = PortableSIMDUnit::ZERO(); + let mut out = ZERO(); for i in 0..simd_unit.coefficients.len() { out.coefficients[i] = reduce_element(simd_unit.coefficients[i] << SHIFT_BY); @@ -205,7 +190,7 @@ pub fn compute_hint( low: PortableSIMDUnit, high: PortableSIMDUnit, ) -> (usize, PortableSIMDUnit) { - let mut hint = PortableSIMDUnit::ZERO(); + let mut hint = ZERO(); let mut one_hints_count = 0; for i in 0..hint.coefficients.len() { @@ -234,11 +219,7 @@ pub fn compute_hint( #[allow(non_snake_case)] #[inline(always)] fn decompose_element(r: i32) -> (i32, i32) { - debug_assert!( - r > -FIELD_MODULUS && r < FIELD_MODULUS, - "the representative is {}", - r - ); + debug_assert!(r > -FIELD_MODULUS && r < FIELD_MODULUS); // Convert the signed representative to the standard unsigned one. let r = r + ((r >> 31) & FIELD_MODULUS); @@ -319,8 +300,8 @@ pub(crate) fn use_one_hint(r: i32, hint: i32) -> i32 { pub fn decompose( simd_unit: PortableSIMDUnit, ) -> (PortableSIMDUnit, PortableSIMDUnit) { - let mut low = PortableSIMDUnit::ZERO(); - let mut high = PortableSIMDUnit::ZERO(); + let mut low = ZERO(); + let mut high = ZERO(); for i in 0..low.coefficients.len() { let (low_part, high_part) = decompose_element::(simd_unit.coefficients[i]); @@ -336,7 +317,7 @@ pub fn use_hint( simd_unit: PortableSIMDUnit, hint: PortableSIMDUnit, ) -> PortableSIMDUnit { - let mut result = PortableSIMDUnit::ZERO(); + let mut result = ZERO(); for i in 0..result.coefficients.len() { result.coefficients[i] = diff --git a/libcrux-ml-dsa/src/simd/portable/encoding/commitment.rs b/libcrux-ml-dsa/src/simd/portable/encoding/commitment.rs index c6886ba50..6ffafe423 100644 --- a/libcrux-ml-dsa/src/simd/portable/encoding/commitment.rs +++ b/libcrux-ml-dsa/src/simd/portable/encoding/commitment.rs @@ -1,4 +1,4 @@ -use crate::simd::portable::PortableSIMDUnit; +use super::super::vector_type::PortableSIMDUnit; #[inline(always)] pub fn serialize(simd_unit: PortableSIMDUnit) -> [u8; OUTPUT_SIZE] { diff --git a/libcrux-ml-dsa/src/simd/portable/encoding/error.rs b/libcrux-ml-dsa/src/simd/portable/encoding/error.rs index d7878fbc8..5581cc2a4 100644 --- a/libcrux-ml-dsa/src/simd/portable/encoding/error.rs +++ b/libcrux-ml-dsa/src/simd/portable/encoding/error.rs @@ -1,4 +1,4 @@ -use crate::simd::{portable::PortableSIMDUnit, traits::Operations}; +use super::super::vector_type::{PortableSIMDUnit, ZERO}; #[inline(always)] fn serialize_when_eta_is_2( @@ -54,7 +54,7 @@ pub(crate) fn serialize( fn deserialize_when_eta_is_2(serialized: &[u8]) -> PortableSIMDUnit { debug_assert!(serialized.len() == 3); - let mut simd_unit = PortableSIMDUnit::ZERO(); + let mut simd_unit = ZERO(); const ETA: i32 = 2; let byte0 = serialized[0] as i32; @@ -76,7 +76,7 @@ fn deserialize_when_eta_is_2(serialized: &[u8]) -> PortableSIMDUnit { fn deserialize_when_eta_is_4(serialized: &[u8]) -> PortableSIMDUnit { debug_assert!(serialized.len() == 4); - let mut simd_unit = PortableSIMDUnit::ZERO(); + let mut simd_unit = ZERO(); const ETA: i32 = 4; for (i, byte) in serialized.iter().enumerate() { diff --git a/libcrux-ml-dsa/src/simd/portable/encoding/gamma1.rs b/libcrux-ml-dsa/src/simd/portable/encoding/gamma1.rs index eabb2fd81..3dbb5f20a 100644 --- a/libcrux-ml-dsa/src/simd/portable/encoding/gamma1.rs +++ b/libcrux-ml-dsa/src/simd/portable/encoding/gamma1.rs @@ -1,5 +1,4 @@ -use crate::simd::{portable::PortableSIMDUnit, traits::Operations}; - +use super::super::vector_type::{PortableSIMDUnit, ZERO}; // This function is marked public since it is called in the corresponding AVX2 code. #[inline(always)] pub fn serialize_when_gamma1_is_2_pow_17( @@ -37,6 +36,7 @@ pub fn serialize_when_gamma1_is_2_pow_17( serialized } + #[inline(always)] fn serialize_when_gamma1_is_2_pow_19( simd_unit: PortableSIMDUnit, @@ -81,33 +81,33 @@ fn deserialize_when_gamma1_is_2_pow_17(serialized: &[u8]) -> PortableSIMDUnit { const GAMMA1: i32 = 1 << 17; const GAMMA1_TIMES_2_BITMASK: i32 = (GAMMA1 << 1) - 1; - let mut simd_unit = PortableSIMDUnit::ZERO(); + let mut simd_unit = ZERO(); for (i, bytes) in serialized.chunks_exact(9).enumerate() { - simd_unit.coefficients[4 * i] = bytes[0] as i32; - simd_unit.coefficients[4 * i] |= (bytes[1] as i32) << 8; - simd_unit.coefficients[4 * i] |= (bytes[2] as i32) << 16; - simd_unit.coefficients[4 * i] &= GAMMA1_TIMES_2_BITMASK; - - simd_unit.coefficients[4 * i + 1] = (bytes[2] as i32) >> 2; - simd_unit.coefficients[4 * i + 1] |= (bytes[3] as i32) << 6; - simd_unit.coefficients[4 * i + 1] |= (bytes[4] as i32) << 14; - simd_unit.coefficients[4 * i + 1] &= GAMMA1_TIMES_2_BITMASK; - - simd_unit.coefficients[4 * i + 2] = (bytes[4] as i32) >> 4; - simd_unit.coefficients[4 * i + 2] |= (bytes[5] as i32) << 4; - simd_unit.coefficients[4 * i + 2] |= (bytes[6] as i32) << 12; - simd_unit.coefficients[4 * i + 2] &= GAMMA1_TIMES_2_BITMASK; - - simd_unit.coefficients[4 * i + 3] = (bytes[6] as i32) >> 6; - simd_unit.coefficients[4 * i + 3] |= (bytes[7] as i32) << 2; - simd_unit.coefficients[4 * i + 3] |= (bytes[8] as i32) << 10; - simd_unit.coefficients[4 * i + 3] &= GAMMA1_TIMES_2_BITMASK; - - simd_unit.coefficients[4 * i] = GAMMA1 - simd_unit.coefficients[4 * i]; - simd_unit.coefficients[4 * i + 1] = GAMMA1 - simd_unit.coefficients[4 * i + 1]; - simd_unit.coefficients[4 * i + 2] = GAMMA1 - simd_unit.coefficients[4 * i + 2]; - simd_unit.coefficients[4 * i + 3] = GAMMA1 - simd_unit.coefficients[4 * i + 3]; + let mut coefficient0 = bytes[0] as i32; + coefficient0 |= (bytes[1] as i32) << 8; + coefficient0 |= (bytes[2] as i32) << 16; + coefficient0 &= GAMMA1_TIMES_2_BITMASK; + + let mut coefficient1 = (bytes[2] as i32) >> 2; + coefficient1 |= (bytes[3] as i32) << 6; + coefficient1 |= (bytes[4] as i32) << 14; + coefficient1 &= GAMMA1_TIMES_2_BITMASK; + + let mut coefficient2 = (bytes[4] as i32) >> 4; + coefficient2 |= (bytes[5] as i32) << 4; + coefficient2 |= (bytes[6] as i32) << 12; + coefficient2 &= GAMMA1_TIMES_2_BITMASK; + + let mut coefficient3 = (bytes[6] as i32) >> 6; + coefficient3 |= (bytes[7] as i32) << 2; + coefficient3 |= (bytes[8] as i32) << 10; + coefficient3 &= GAMMA1_TIMES_2_BITMASK; + + simd_unit.coefficients[4 * i] = GAMMA1 - coefficient0; + simd_unit.coefficients[4 * i + 1] = GAMMA1 - coefficient1; + simd_unit.coefficients[4 * i + 2] = GAMMA1 - coefficient2; + simd_unit.coefficients[4 * i + 3] = GAMMA1 - coefficient3; } simd_unit @@ -121,20 +121,20 @@ fn deserialize_when_gamma1_is_2_pow_19(serialized: &[u8]) -> PortableSIMDUnit { const GAMMA1: i32 = 1 << 19; const GAMMA1_TIMES_2_BITMASK: i32 = (GAMMA1 << 1) - 1; - let mut simd_unit = PortableSIMDUnit::ZERO(); + let mut simd_unit = ZERO(); for (i, bytes) in serialized.chunks_exact(5).enumerate() { - simd_unit.coefficients[2 * i] = bytes[0] as i32; - simd_unit.coefficients[2 * i] |= (bytes[1] as i32) << 8; - simd_unit.coefficients[2 * i] |= (bytes[2] as i32) << 16; - simd_unit.coefficients[2 * i] &= GAMMA1_TIMES_2_BITMASK; + let mut coefficient0 = bytes[0] as i32; + coefficient0 |= (bytes[1] as i32) << 8; + coefficient0 |= (bytes[2] as i32) << 16; + coefficient0 &= GAMMA1_TIMES_2_BITMASK; - simd_unit.coefficients[2 * i + 1] = (bytes[2] as i32) >> 4; - simd_unit.coefficients[2 * i + 1] |= (bytes[3] as i32) << 4; - simd_unit.coefficients[2 * i + 1] |= (bytes[4] as i32) << 12; + let mut coefficient1 = (bytes[2] as i32) >> 4; + coefficient1 |= (bytes[3] as i32) << 4; + coefficient1 |= (bytes[4] as i32) << 12; - simd_unit.coefficients[2 * i] = GAMMA1 - simd_unit.coefficients[2 * i]; - simd_unit.coefficients[2 * i + 1] = GAMMA1 - simd_unit.coefficients[2 * i + 1]; + simd_unit.coefficients[2 * i] = GAMMA1 - coefficient0; + simd_unit.coefficients[2 * i + 1] = GAMMA1 - coefficient1; } simd_unit diff --git a/libcrux-ml-dsa/src/simd/portable/encoding/t0.rs b/libcrux-ml-dsa/src/simd/portable/encoding/t0.rs index da66b7729..626f14c43 100644 --- a/libcrux-ml-dsa/src/simd/portable/encoding/t0.rs +++ b/libcrux-ml-dsa/src/simd/portable/encoding/t0.rs @@ -1,7 +1,6 @@ -use crate::{ - constants::BITS_IN_LOWER_PART_OF_T, - simd::{portable::PortableSIMDUnit, traits::Operations}, -}; +use crate::constants::BITS_IN_LOWER_PART_OF_T; + +use super::super::vector_type::{PortableSIMDUnit, ZERO}; // If t0 is a signed representative, change it to an unsigned one and // vice versa. @@ -63,8 +62,6 @@ pub fn serialize(simd_unit: PortableSIMDUnit) -> [u8; 13] { pub fn deserialize(serialized: &[u8]) -> PortableSIMDUnit { debug_assert!(serialized.len() == 13); - let mut simd_unit = PortableSIMDUnit::ZERO(); - const BITS_IN_LOWER_PART_OF_T_MASK: i32 = (1 << (BITS_IN_LOWER_PART_OF_T as i32)) - 1; let byte0 = serialized[0] as i32; @@ -81,50 +78,52 @@ pub fn deserialize(serialized: &[u8]) -> PortableSIMDUnit { let byte11 = serialized[11] as i32; let byte12 = serialized[12] as i32; - simd_unit.coefficients[0] = byte0; - simd_unit.coefficients[0] |= byte1 << 8; - simd_unit.coefficients[0] &= BITS_IN_LOWER_PART_OF_T_MASK; - - simd_unit.coefficients[1] = byte1 >> 5; - simd_unit.coefficients[1] |= byte2 << 3; - simd_unit.coefficients[1] |= byte3 << 11; - simd_unit.coefficients[1] &= BITS_IN_LOWER_PART_OF_T_MASK; - - simd_unit.coefficients[2] = byte3 >> 2; - simd_unit.coefficients[2] |= byte4 << 6; - simd_unit.coefficients[2] &= BITS_IN_LOWER_PART_OF_T_MASK; - - simd_unit.coefficients[3] = byte4 >> 7; - simd_unit.coefficients[3] |= byte5 << 1; - simd_unit.coefficients[3] |= byte6 << 9; - simd_unit.coefficients[3] &= BITS_IN_LOWER_PART_OF_T_MASK; - - simd_unit.coefficients[4] = byte6 >> 4; - simd_unit.coefficients[4] |= byte7 << 4; - simd_unit.coefficients[4] |= byte8 << 12; - simd_unit.coefficients[4] &= BITS_IN_LOWER_PART_OF_T_MASK; - - simd_unit.coefficients[5] = byte8 >> 1; - simd_unit.coefficients[5] |= byte9 << 7; - simd_unit.coefficients[5] &= BITS_IN_LOWER_PART_OF_T_MASK; - - simd_unit.coefficients[6] = byte9 >> 6; - simd_unit.coefficients[6] |= byte10 << 2; - simd_unit.coefficients[6] |= byte11 << 10; - simd_unit.coefficients[6] &= BITS_IN_LOWER_PART_OF_T_MASK; - - simd_unit.coefficients[7] = byte11 >> 3; - simd_unit.coefficients[7] |= byte12 << 5; - simd_unit.coefficients[7] &= BITS_IN_LOWER_PART_OF_T_MASK; - - simd_unit.coefficients[0] = change_t0_interval(simd_unit.coefficients[0]); - simd_unit.coefficients[1] = change_t0_interval(simd_unit.coefficients[1]); - simd_unit.coefficients[2] = change_t0_interval(simd_unit.coefficients[2]); - simd_unit.coefficients[3] = change_t0_interval(simd_unit.coefficients[3]); - simd_unit.coefficients[4] = change_t0_interval(simd_unit.coefficients[4]); - simd_unit.coefficients[5] = change_t0_interval(simd_unit.coefficients[5]); - simd_unit.coefficients[6] = change_t0_interval(simd_unit.coefficients[6]); - simd_unit.coefficients[7] = change_t0_interval(simd_unit.coefficients[7]); + let mut coefficient0 = byte0; + coefficient0 |= byte1 << 8; + coefficient0 &= BITS_IN_LOWER_PART_OF_T_MASK; + + let mut coefficient1 = byte1 >> 5; + coefficient1 |= byte2 << 3; + coefficient1 |= byte3 << 11; + coefficient1 &= BITS_IN_LOWER_PART_OF_T_MASK; + + let mut coefficient2 = byte3 >> 2; + coefficient2 |= byte4 << 6; + coefficient2 &= BITS_IN_LOWER_PART_OF_T_MASK; + + let mut coefficient3 = byte4 >> 7; + coefficient3 |= byte5 << 1; + coefficient3 |= byte6 << 9; + coefficient3 &= BITS_IN_LOWER_PART_OF_T_MASK; + + let mut coefficient4 = byte6 >> 4; + coefficient4 |= byte7 << 4; + coefficient4 |= byte8 << 12; + coefficient4 &= BITS_IN_LOWER_PART_OF_T_MASK; + + let mut coefficient5 = byte8 >> 1; + coefficient5 |= byte9 << 7; + coefficient5 &= BITS_IN_LOWER_PART_OF_T_MASK; + + let mut coefficient6 = byte9 >> 6; + coefficient6 |= byte10 << 2; + coefficient6 |= byte11 << 10; + coefficient6 &= BITS_IN_LOWER_PART_OF_T_MASK; + + let mut coefficient7 = byte11 >> 3; + coefficient7 |= byte12 << 5; + coefficient7 &= BITS_IN_LOWER_PART_OF_T_MASK; + + let mut simd_unit = ZERO(); + + simd_unit.coefficients[0] = change_t0_interval(coefficient0); + simd_unit.coefficients[1] = change_t0_interval(coefficient1); + simd_unit.coefficients[2] = change_t0_interval(coefficient2); + simd_unit.coefficients[3] = change_t0_interval(coefficient3); + simd_unit.coefficients[4] = change_t0_interval(coefficient4); + simd_unit.coefficients[5] = change_t0_interval(coefficient5); + simd_unit.coefficients[6] = change_t0_interval(coefficient6); + simd_unit.coefficients[7] = change_t0_interval(coefficient7); simd_unit } diff --git a/libcrux-ml-dsa/src/simd/portable/encoding/t1.rs b/libcrux-ml-dsa/src/simd/portable/encoding/t1.rs index 3b8c56515..c0fc9de40 100644 --- a/libcrux-ml-dsa/src/simd/portable/encoding/t1.rs +++ b/libcrux-ml-dsa/src/simd/portable/encoding/t1.rs @@ -1,7 +1,6 @@ -use crate::{ - constants::BITS_IN_UPPER_PART_OF_T, - simd::{portable::PortableSIMDUnit, traits::Operations}, -}; +use crate::constants::BITS_IN_UPPER_PART_OF_T; + +use super::super::vector_type::{PortableSIMDUnit, ZERO}; #[inline(always)] pub fn serialize(simd_unit: PortableSIMDUnit) -> [u8; 10] { @@ -25,7 +24,7 @@ pub fn serialize(simd_unit: PortableSIMDUnit) -> [u8; 10] { pub fn deserialize(serialized: &[u8]) -> PortableSIMDUnit { debug_assert!(serialized.len() == 10); - let mut simd_unit = PortableSIMDUnit::ZERO(); + let mut simd_unit = ZERO(); let mask = (1 << BITS_IN_UPPER_PART_OF_T) - 1; for (i, bytes) in serialized.chunks_exact(5).enumerate() { diff --git a/libcrux-ml-dsa/src/simd/portable/invntt.rs b/libcrux-ml-dsa/src/simd/portable/invntt.rs new file mode 100644 index 000000000..2cef94c7f --- /dev/null +++ b/libcrux-ml-dsa/src/simd/portable/invntt.rs @@ -0,0 +1,315 @@ +use super::arithmetic::{self, montgomery_multiply_fe_by_fer}; +use super::vector_type::PortableSIMDUnit; +use crate::simd::traits::{COEFFICIENTS_IN_SIMD_UNIT, SIMD_UNITS_IN_RING_ELEMENT}; + +#[inline(always)] +pub fn simd_unit_invert_ntt_at_layer_0( + mut simd_unit: PortableSIMDUnit, + zeta0: i32, + zeta1: i32, + zeta2: i32, + zeta3: i32, +) -> PortableSIMDUnit { + let a_minus_b = simd_unit.coefficients[1] - simd_unit.coefficients[0]; + simd_unit.coefficients[0] = simd_unit.coefficients[0] + simd_unit.coefficients[1]; + simd_unit.coefficients[1] = montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + + let a_minus_b = simd_unit.coefficients[3] - simd_unit.coefficients[2]; + simd_unit.coefficients[2] = simd_unit.coefficients[2] + simd_unit.coefficients[3]; + simd_unit.coefficients[3] = montgomery_multiply_fe_by_fer(a_minus_b, zeta1); + + let a_minus_b = simd_unit.coefficients[5] - simd_unit.coefficients[4]; + simd_unit.coefficients[4] = simd_unit.coefficients[4] + simd_unit.coefficients[5]; + simd_unit.coefficients[5] = montgomery_multiply_fe_by_fer(a_minus_b, zeta2); + + let a_minus_b = simd_unit.coefficients[7] - simd_unit.coefficients[6]; + simd_unit.coefficients[6] = simd_unit.coefficients[6] + simd_unit.coefficients[7]; + simd_unit.coefficients[7] = montgomery_multiply_fe_by_fer(a_minus_b, zeta3); + + simd_unit +} + +#[inline(always)] +pub fn simd_unit_invert_ntt_at_layer_1( + mut simd_unit: PortableSIMDUnit, + zeta0: i32, + zeta1: i32, +) -> PortableSIMDUnit { + let a_minus_b = simd_unit.coefficients[2] - simd_unit.coefficients[0]; + simd_unit.coefficients[0] = simd_unit.coefficients[0] + simd_unit.coefficients[2]; + simd_unit.coefficients[2] = montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + + let a_minus_b = simd_unit.coefficients[3] - simd_unit.coefficients[1]; + simd_unit.coefficients[1] = simd_unit.coefficients[1] + simd_unit.coefficients[3]; + simd_unit.coefficients[3] = montgomery_multiply_fe_by_fer(a_minus_b, zeta0); + + let a_minus_b = simd_unit.coefficients[6] - simd_unit.coefficients[4]; + simd_unit.coefficients[4] = simd_unit.coefficients[4] + simd_unit.coefficients[6]; + simd_unit.coefficients[6] = montgomery_multiply_fe_by_fer(a_minus_b, zeta1); + + let a_minus_b = simd_unit.coefficients[7] - simd_unit.coefficients[5]; + simd_unit.coefficients[5] = simd_unit.coefficients[5] + simd_unit.coefficients[7]; + simd_unit.coefficients[7] = montgomery_multiply_fe_by_fer(a_minus_b, zeta1); + + simd_unit +} + +#[inline(always)] +pub fn simd_unit_invert_ntt_at_layer_2( + mut simd_unit: PortableSIMDUnit, + zeta: i32, +) -> PortableSIMDUnit { + let a_minus_b = simd_unit.coefficients[4] - simd_unit.coefficients[0]; + simd_unit.coefficients[0] = simd_unit.coefficients[0] + simd_unit.coefficients[4]; + simd_unit.coefficients[4] = montgomery_multiply_fe_by_fer(a_minus_b, zeta); + + let a_minus_b = simd_unit.coefficients[5] - simd_unit.coefficients[1]; + simd_unit.coefficients[1] = simd_unit.coefficients[1] + simd_unit.coefficients[5]; + simd_unit.coefficients[5] = montgomery_multiply_fe_by_fer(a_minus_b, zeta); + + let a_minus_b = simd_unit.coefficients[6] - simd_unit.coefficients[2]; + simd_unit.coefficients[2] = simd_unit.coefficients[2] + simd_unit.coefficients[6]; + simd_unit.coefficients[6] = montgomery_multiply_fe_by_fer(a_minus_b, zeta); + + let a_minus_b = simd_unit.coefficients[7] - simd_unit.coefficients[3]; + simd_unit.coefficients[3] = simd_unit.coefficients[3] + simd_unit.coefficients[7]; + simd_unit.coefficients[7] = montgomery_multiply_fe_by_fer(a_minus_b, zeta); + + simd_unit +} + +#[inline(always)] +fn invert_ntt_at_layer_0(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta0: i32, + zeta1: i32, + zeta2: i32, + zeta3: i32, + ) { + re[index] = simd_unit_invert_ntt_at_layer_0(re[index], zeta0, zeta1, zeta2, zeta3); + } + + round(re, 0, 1976782, -846154, 1400424, 3937738); + round(re, 1, -1362209, -48306, 3919660, -554416); + round(re, 2, -3545687, 1612842, -976891, 183443); + round(re, 3, -2286327, -420899, -2235985, -2939036); + round(re, 4, -3833893, -260646, -1104333, -1667432); + round(re, 5, 1910376, -1803090, 1723600, -426683); + round(re, 6, 472078, 1717735, -975884, 2213111); + round(re, 7, 269760, 3866901, 3523897, -3038916); + round(re, 8, -1799107, -3694233, 1652634, 810149); + round(re, 9, 3014001, 1616392, 162844, -3183426); + round(re, 10, -1207385, 185531, 3369112, 1957272); + round(re, 11, -164721, 2454455, 2432395, -2013608); + round(re, 12, -3776993, 594136, -3724270, -2584293); + round(re, 13, -1846953, -1671176, -2831860, -542412); + round(re, 14, 3406031, 2235880, 777191, 1500165); + round(re, 15, -1374803, -2546312, 1917081, -1279661); + round(re, 16, -1962642, 3306115, 1312455, -451100); + round(re, 17, -1430225, -3318210, 1237275, -1333058); + round(re, 18, -1050970, 1903435, 1869119, -2994039); + round(re, 19, -3548272, 2635921, 1250494, -3767016); + round(re, 20, 1595974, 2486353, 1247620, 4055324); + round(re, 21, 1265009, -2590150, 2691481, 2842341); + round(re, 22, 203044, 1735879, -3342277, 3437287); + round(re, 23, 4108315, -2437823, 286988, 342297); + round(re, 24, -3595838, -768622, -525098, -3556995); + round(re, 25, 3207046, 2031748, -3122442, -655327); + round(re, 26, -522500, -43260, -1613174, 495491); + round(re, 27, 819034, 909542, 1859098, 900702); + round(re, 28, -3193378, -1197226, -3759364, -3520352); + round(re, 29, 3513181, -1235728, 2434439, 266997); + round(re, 30, -3562462, -2446433, 2244091, -3342478); + round(re, 31, 3817976, 2316500, 3407706, 2091667); +} + +#[inline(always)] +fn invert_ntt_at_layer_1(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta_00: i32, + zeta_01: i32, + ) { + re[index] = simd_unit_invert_ntt_at_layer_1(re[index], zeta_00, zeta_01); + } + + round(re, 0, 3839961, -3628969); + round(re, 1, -3881060, -3019102); + round(re, 2, -1439742, -812732); + round(re, 3, -1584928, 1285669); + round(re, 4, 1341330, 1315589); + round(re, 5, -177440, -2409325); + round(re, 6, -1851402, 3159746); + round(re, 7, -3553272, 189548); + round(re, 8, -1316856, 759969); + round(re, 9, -210977, 2389356); + round(re, 10, -3249728, 1653064); + round(re, 11, -8578, -3724342); + round(re, 12, 3958618, 904516); + round(re, 13, -1100098, 44288); + round(re, 14, 3097992, 508951); + round(re, 15, 264944, -3343383); + round(re, 16, -1430430, 1852771); + round(re, 17, 1349076, -381987); + round(re, 18, -1308169, -22981); + round(re, 19, -1228525, -671102); + round(re, 20, -2477047, -411027); + round(re, 21, -3693493, -2967645); + round(re, 22, 2715295, 2147896); + round(re, 23, -983419, 3412210); + round(re, 24, 126922, -3632928); + round(re, 25, -3157330, -3190144); + round(re, 26, -1000202, -4083598); + round(re, 27, 1939314, -1257611); + round(re, 28, -1585221, 2176455); + round(re, 29, 3475950, -1452451); + round(re, 30, -3041255, -3677745); + round(re, 31, -1528703, -3930395); +} + +#[inline(always)] +fn invert_ntt_at_layer_2(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + fn round(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], index: usize, zeta1: i32) { + re[index] = simd_unit_invert_ntt_at_layer_2(re[index], zeta1); + } + + round(re, 0, -2797779); + round(re, 1, 2071892); + round(re, 2, -2556880); + round(re, 3, 3900724); + round(re, 4, 3881043); + round(re, 5, 954230); + round(re, 6, 531354); + round(re, 7, 811944); + round(re, 8, 3699596); + round(re, 9, -1600420); + round(re, 10, -2140649); + round(re, 11, 3507263); + round(re, 12, -3821735); + round(re, 13, 3505694); + round(re, 14, -1643818); + round(re, 15, -1699267); + round(re, 16, -539299); + round(re, 17, 2348700); + round(re, 18, -300467); + round(re, 19, 3539968); + round(re, 20, -2867647); + round(re, 21, 3574422); + round(re, 22, -3043716); + round(re, 23, -3861115); + round(re, 24, 3915439); + round(re, 25, -2537516); + round(re, 26, -3592148); + round(re, 27, -1661693); + round(re, 28, 3530437); + round(re, 29, 3077325); + round(re, 30, 95776); + round(re, 31, 2706023); +} + +#[inline(always)] +fn outer_3_plus( + re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], +) { + for j in OFFSET..OFFSET + STEP_BY { + let a_minus_b = arithmetic::subtract(&re[j + STEP_BY], &re[j]); + re[j] = arithmetic::add(&re[j], &re[j + STEP_BY]); + re[j + STEP_BY] = arithmetic::montgomery_multiply_by_constant(a_minus_b, ZETA); + } + () +} + +#[inline(always)] +fn invert_ntt_at_layer_3(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 8; // 1 << LAYER; + const STEP_BY: usize = 1; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 280005>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 4010497>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -19422>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1757237>(re); + outer_3_plus::<{ (4 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -3277672>(re); + outer_3_plus::<{ (5 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1399561>(re); + outer_3_plus::<{ (6 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -3859737>(re); + outer_3_plus::<{ (7 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2118186>(re); + outer_3_plus::<{ (8 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2108549>(re); + outer_3_plus::<{ (9 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2619752>(re); + outer_3_plus::<{ (10 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1119584>(re); + outer_3_plus::<{ (11 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -549488>(re); + outer_3_plus::<{ (12 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3585928>(re); + outer_3_plus::<{ (13 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1079900>(re); + outer_3_plus::<{ (14 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1024112>(re); + outer_3_plus::<{ (15 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2725464>(re); +} + +#[inline(always)] +fn invert_ntt_at_layer_4(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 16; // 1 << LAYER; + const STEP_BY: usize = 2; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2680103>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3111497>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2884855>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3119733>(re); + outer_3_plus::<{ (4 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2091905>(re); + outer_3_plus::<{ (5 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -359251>(re); + outer_3_plus::<{ (6 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2353451>(re); + outer_3_plus::<{ (7 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1826347>(re); +} + +#[inline(always)] +fn invert_ntt_at_layer_5(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 32; // 1 << LAYER; + const STEP_BY: usize = 4; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 466468>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -876248>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -777960>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 237124>(re); +} + +#[inline(always)] +fn invert_ntt_at_layer_6(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 64; // 1 << LAYER; + const STEP_BY: usize = 8; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -518909>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2608894>(re); +} + +#[inline(always)] +fn invert_ntt_at_layer_7(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 128; // 1 << LAYER; + const STEP_BY: usize = 16; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 25847>(re); +} + +pub(crate) fn invert_ntt_montgomery( + mut re: [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], +) -> [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT] { + invert_ntt_at_layer_0(&mut re); + invert_ntt_at_layer_1(&mut re); + invert_ntt_at_layer_2(&mut re); + invert_ntt_at_layer_3(&mut re); + invert_ntt_at_layer_4(&mut re); + invert_ntt_at_layer_5(&mut re); + invert_ntt_at_layer_6(&mut re); + invert_ntt_at_layer_7(&mut re); + + for i in 0..re.len() { + // After invert_ntt_at_layer, elements are of the form a * MONTGOMERY_R^{-1} + // we multiply by (MONTGOMERY_R^2) * (1/2^8) mod Q = 41,978 to both: + // + // - Divide the elements by 256 and + // - Convert the elements form montgomery domain to the standard domain. + re[i] = arithmetic::montgomery_multiply_by_constant(re[i], 41_978); + } + + re +} diff --git a/libcrux-ml-dsa/src/simd/portable/ntt.rs b/libcrux-ml-dsa/src/simd/portable/ntt.rs index ac40a9c1c..c632f3cf8 100644 --- a/libcrux-ml-dsa/src/simd/portable/ntt.rs +++ b/libcrux-ml-dsa/src/simd/portable/ntt.rs @@ -1,11 +1,6 @@ -use super::arithmetic::{self, montgomery_multiply_fe_by_fer}; -use crate::simd::{ - portable::PortableSIMDUnit, - traits::{ - montgomery_multiply_by_fer, COEFFICIENTS_IN_SIMD_UNIT, SIMD_UNITS_IN_RING_ELEMENT, - ZETAS_TIMES_MONTGOMERY_R, - }, -}; +use super::arithmetic::{self, montgomery_multiply_by_constant, montgomery_multiply_fe_by_fer}; +use super::vector_type::PortableSIMDUnit; +use crate::simd::traits::{COEFFICIENTS_IN_SIMD_UNIT, SIMD_UNITS_IN_RING_ELEMENT}; #[inline(always)] pub fn simd_unit_ntt_at_layer_0( @@ -33,6 +28,7 @@ pub fn simd_unit_ntt_at_layer_0( simd_unit } + #[inline(always)] pub fn simd_unit_ntt_at_layer_1( mut simd_unit: PortableSIMDUnit, @@ -57,6 +53,7 @@ pub fn simd_unit_ntt_at_layer_1( simd_unit } + #[inline(always)] pub fn simd_unit_ntt_at_layer_2(mut simd_unit: PortableSIMDUnit, zeta: i32) -> PortableSIMDUnit { let t = montgomery_multiply_fe_by_fer(simd_unit.coefficients[4], zeta); @@ -79,153 +76,231 @@ pub fn simd_unit_ntt_at_layer_2(mut simd_unit: PortableSIMDUnit, zeta: i32) -> P } #[inline(always)] -pub fn invert_ntt_at_layer_0( - mut simd_unit: PortableSIMDUnit, - zeta0: i32, - zeta1: i32, - zeta2: i32, - zeta3: i32, -) -> PortableSIMDUnit { - let a_minus_b = simd_unit.coefficients[1] - simd_unit.coefficients[0]; - simd_unit.coefficients[0] = simd_unit.coefficients[0] + simd_unit.coefficients[1]; - simd_unit.coefficients[1] = montgomery_multiply_fe_by_fer(a_minus_b, zeta0); - - let a_minus_b = simd_unit.coefficients[3] - simd_unit.coefficients[2]; - simd_unit.coefficients[2] = simd_unit.coefficients[2] + simd_unit.coefficients[3]; - simd_unit.coefficients[3] = montgomery_multiply_fe_by_fer(a_minus_b, zeta1); - - let a_minus_b = simd_unit.coefficients[5] - simd_unit.coefficients[4]; - simd_unit.coefficients[4] = simd_unit.coefficients[4] + simd_unit.coefficients[5]; - simd_unit.coefficients[5] = montgomery_multiply_fe_by_fer(a_minus_b, zeta2); - - let a_minus_b = simd_unit.coefficients[7] - simd_unit.coefficients[6]; - simd_unit.coefficients[6] = simd_unit.coefficients[6] + simd_unit.coefficients[7]; - simd_unit.coefficients[7] = montgomery_multiply_fe_by_fer(a_minus_b, zeta3); +fn ntt_at_layer_0(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta_0: i32, + zeta_1: i32, + zeta_2: i32, + zeta_3: i32, + ) { + re[index] = simd_unit_ntt_at_layer_0(re[index], zeta_0, zeta_1, zeta_2, zeta_3); + } - simd_unit + round(re, 0, 2091667, 3407706, 2316500, 3817976); + round(re, 1, -3342478, 2244091, -2446433, -3562462); + round(re, 2, 266997, 2434439, -1235728, 3513181); + round(re, 3, -3520352, -3759364, -1197226, -3193378); + round(re, 4, 900702, 1859098, 909542, 819034); + round(re, 5, 495491, -1613174, -43260, -522500); + round(re, 6, -655327, -3122442, 2031748, 3207046); + round(re, 7, -3556995, -525098, -768622, -3595838); + round(re, 8, 342297, 286988, -2437823, 4108315); + round(re, 9, 3437287, -3342277, 1735879, 203044); + round(re, 10, 2842341, 2691481, -2590150, 1265009); + round(re, 11, 4055324, 1247620, 2486353, 1595974); + round(re, 12, -3767016, 1250494, 2635921, -3548272); + round(re, 13, -2994039, 1869119, 1903435, -1050970); + round(re, 14, -1333058, 1237275, -3318210, -1430225); + round(re, 15, -451100, 1312455, 3306115, -1962642); + round(re, 16, -1279661, 1917081, -2546312, -1374803); + round(re, 17, 1500165, 777191, 2235880, 3406031); + round(re, 18, -542412, -2831860, -1671176, -1846953); + round(re, 19, -2584293, -3724270, 594136, -3776993); + round(re, 20, -2013608, 2432395, 2454455, -164721); + round(re, 21, 1957272, 3369112, 185531, -1207385); + round(re, 22, -3183426, 162844, 1616392, 3014001); + round(re, 23, 810149, 1652634, -3694233, -1799107); + round(re, 24, -3038916, 3523897, 3866901, 269760); + round(re, 25, 2213111, -975884, 1717735, 472078); + round(re, 26, -426683, 1723600, -1803090, 1910376); + round(re, 27, -1667432, -1104333, -260646, -3833893); + round(re, 28, -2939036, -2235985, -420899, -2286327); + round(re, 29, 183443, -976891, 1612842, -3545687); + round(re, 30, -554416, 3919660, -48306, -1362209); + round(re, 31, 3937738, 1400424, -846154, 1976782); } -#[inline(always)] -pub fn invert_ntt_at_layer_1( - mut simd_unit: PortableSIMDUnit, - zeta0: i32, - zeta1: i32, -) -> PortableSIMDUnit { - let a_minus_b = simd_unit.coefficients[2] - simd_unit.coefficients[0]; - simd_unit.coefficients[0] = simd_unit.coefficients[0] + simd_unit.coefficients[2]; - simd_unit.coefficients[2] = montgomery_multiply_fe_by_fer(a_minus_b, zeta0); - - let a_minus_b = simd_unit.coefficients[3] - simd_unit.coefficients[1]; - simd_unit.coefficients[1] = simd_unit.coefficients[1] + simd_unit.coefficients[3]; - simd_unit.coefficients[3] = montgomery_multiply_fe_by_fer(a_minus_b, zeta0); - - let a_minus_b = simd_unit.coefficients[6] - simd_unit.coefficients[4]; - simd_unit.coefficients[4] = simd_unit.coefficients[4] + simd_unit.coefficients[6]; - simd_unit.coefficients[6] = montgomery_multiply_fe_by_fer(a_minus_b, zeta1); - let a_minus_b = simd_unit.coefficients[7] - simd_unit.coefficients[5]; - simd_unit.coefficients[5] = simd_unit.coefficients[5] + simd_unit.coefficients[7]; - simd_unit.coefficients[7] = montgomery_multiply_fe_by_fer(a_minus_b, zeta1); - - simd_unit -} #[inline(always)] -pub fn invert_ntt_at_layer_2(mut simd_unit: PortableSIMDUnit, zeta: i32) -> PortableSIMDUnit { - let a_minus_b = simd_unit.coefficients[4] - simd_unit.coefficients[0]; - simd_unit.coefficients[0] = simd_unit.coefficients[0] + simd_unit.coefficients[4]; - simd_unit.coefficients[4] = montgomery_multiply_fe_by_fer(a_minus_b, zeta); - - let a_minus_b = simd_unit.coefficients[5] - simd_unit.coefficients[1]; - simd_unit.coefficients[1] = simd_unit.coefficients[1] + simd_unit.coefficients[5]; - simd_unit.coefficients[5] = montgomery_multiply_fe_by_fer(a_minus_b, zeta); - - let a_minus_b = simd_unit.coefficients[6] - simd_unit.coefficients[2]; - simd_unit.coefficients[2] = simd_unit.coefficients[2] + simd_unit.coefficients[6]; - simd_unit.coefficients[6] = montgomery_multiply_fe_by_fer(a_minus_b, zeta); - - let a_minus_b = simd_unit.coefficients[7] - simd_unit.coefficients[3]; - simd_unit.coefficients[3] = simd_unit.coefficients[3] + simd_unit.coefficients[7]; - simd_unit.coefficients[7] = montgomery_multiply_fe_by_fer(a_minus_b, zeta); +fn ntt_at_layer_1(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round( + re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], + index: usize, + zeta_0: i32, + zeta_1: i32, + ) { + re[index] = simd_unit_ntt_at_layer_1(re[index], zeta_0, zeta_1); + } - simd_unit + round(re, 0, -3930395, -1528703); + round(re, 1, -3677745, -3041255); + round(re, 2, -1452451, 3475950); + round(re, 3, 2176455, -1585221); + round(re, 4, -1257611, 1939314); + round(re, 5, -4083598, -1000202); + round(re, 6, -3190144, -3157330); + round(re, 7, -3632928, 126922); + round(re, 8, 3412210, -983419); + round(re, 9, 2147896, 2715295); + round(re, 10, -2967645, -3693493); + round(re, 11, -411027, -2477047); + round(re, 12, -671102, -1228525); + round(re, 13, -22981, -1308169); + round(re, 14, -381987, 1349076); + round(re, 15, 1852771, -1430430); + round(re, 16, -3343383, 264944); + round(re, 17, 508951, 3097992); + round(re, 18, 44288, -1100098); + round(re, 19, 904516, 3958618); + round(re, 20, -3724342, -8578); + round(re, 21, 1653064, -3249728); + round(re, 22, 2389356, -210977); + round(re, 23, 759969, -1316856); + round(re, 24, 189548, -3553272); + round(re, 25, 3159746, -1851402); + round(re, 26, -2409325, -177440); + round(re, 27, 1315589, 1341330); + round(re, 28, 1285669, -1584928); + round(re, 29, -812732, -1439742); + round(re, 30, -3019102, -3881060); + round(re, 31, -3628969, 3839961); } #[inline(always)] -fn ntt_at_layer_0(zeta_i: &mut usize, re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { - *zeta_i += 1; - - for round in 0..re.len() { - re[round] = simd_unit_ntt_at_layer_0( - re[round], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 1], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 2], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 3], - ); - - *zeta_i += 4; +fn ntt_at_layer_2(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + #[inline(always)] + fn round(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], index: usize, zeta: i32) { + re[index] = simd_unit_ntt_at_layer_2(re[index], zeta); } - *zeta_i -= 1; + round(re, 0, 2706023); + round(re, 1, 95776); + round(re, 2, 3077325); + round(re, 3, 3530437); + round(re, 4, -1661693); + round(re, 5, -3592148); + round(re, 6, -2537516); + round(re, 7, 3915439); + round(re, 8, -3861115); + round(re, 9, -3043716); + round(re, 10, 3574422); + round(re, 11, -2867647); + round(re, 12, 3539968); + round(re, 13, -300467); + round(re, 14, 2348700); + round(re, 15, -539299); + round(re, 16, -1699267); + round(re, 17, -1643818); + round(re, 18, 3505694); + round(re, 19, -3821735); + round(re, 20, 3507263); + round(re, 21, -2140649); + round(re, 22, -1600420); + round(re, 23, 3699596); + round(re, 24, 811944); + round(re, 25, 531354); + round(re, 26, 954230); + round(re, 27, 3881043); + round(re, 28, 3900724); + round(re, 29, -2556880); + round(re, 30, 2071892); + round(re, 31, -2797779); } -#[inline(always)] -fn ntt_at_layer_1(zeta_i: &mut usize, re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { - *zeta_i += 1; - for round in 0..re.len() { - re[round] = simd_unit_ntt_at_layer_1( - re[round], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i], - ZETAS_TIMES_MONTGOMERY_R[*zeta_i + 1], - ); +#[inline(always)] +fn outer_3_plus( + re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], +) { + for j in OFFSET..OFFSET + STEP_BY { + let t = montgomery_multiply_by_constant(re[j + STEP_BY], ZETA); - *zeta_i += 2; + re[j + STEP_BY] = arithmetic::subtract(&re[j], &t); + re[j] = arithmetic::add(&re[j], &t); } + () // Needed because of https://github.com/hacspec/hax/issues/720 +} - *zeta_i -= 1; +#[inline(always)] +fn ntt_at_layer_3(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 8; // 1 << LAYER; + const STEP_BY: usize = 1; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2725464>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1024112>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1079900>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3585928>(re); + outer_3_plus::<{ (4 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -549488>(re); + outer_3_plus::<{ (5 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1119584>(re); + outer_3_plus::<{ (6 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2619752>(re); + outer_3_plus::<{ (7 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2108549>(re); + outer_3_plus::<{ (8 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2118186>(re); + outer_3_plus::<{ (9 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -3859737>(re); + outer_3_plus::<{ (10 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -1399561>(re); + outer_3_plus::<{ (11 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -3277672>(re); + outer_3_plus::<{ (12 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1757237>(re); + outer_3_plus::<{ (13 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -19422>(re); + outer_3_plus::<{ (14 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 4010497>(re); + outer_3_plus::<{ (15 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 280005>(re); } + #[inline(always)] -fn ntt_at_layer_2(zeta_i: &mut usize, re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { - for round in 0..re.len() { - *zeta_i += 1; - re[round] = simd_unit_ntt_at_layer_2(re[round], ZETAS_TIMES_MONTGOMERY_R[*zeta_i]); - } +fn ntt_at_layer_4(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 16; // 1 << LAYER; + const STEP_BY: usize = 2; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 1826347>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2353451>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -359251>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2091905>(re); + outer_3_plus::<{ (4 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3119733>(re); + outer_3_plus::<{ (5 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2884855>(re); + outer_3_plus::<{ (6 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 3111497>(re); + outer_3_plus::<{ (7 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 2680103>(re); } + #[inline(always)] -fn ntt_at_layer_3_plus( - zeta_i: &mut usize, - re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], -) { - let step = 1 << LAYER; +fn ntt_at_layer_5(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 32; // 1 << LAYER; + const STEP_BY: usize = 4; // step / COEFFICIENTS_IN_SIMD_UNIT; + + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 237124>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -777960>(re); + outer_3_plus::<{ (2 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -876248>(re); + outer_3_plus::<{ (3 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 466468>(re); +} - for round in 0..(128 >> LAYER) { - *zeta_i += 1; +#[inline(always)] +fn ntt_at_layer_6(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 64; // 1 << LAYER; + const STEP_BY: usize = 8; // step / COEFFICIENTS_IN_SIMD_UNIT; - let offset = (round * step * 2) / COEFFICIENTS_IN_SIMD_UNIT; - let step_by = step / COEFFICIENTS_IN_SIMD_UNIT; + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -2608894>(re); + outer_3_plus::<{ (1 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, -518909>(re); +} - for j in offset..offset + step_by { - let t = montgomery_multiply_by_fer(re[j + step_by], ZETAS_TIMES_MONTGOMERY_R[*zeta_i]); +#[inline(always)] +fn ntt_at_layer_7(re: &mut [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT]) { + const STEP: usize = 128; // 1 << LAYER; + const STEP_BY: usize = 16; // step / COEFFICIENTS_IN_SIMD_UNIT; - re[j + step_by] = arithmetic::subtract(&re[j], &t); - re[j] = arithmetic::add(&re[j], &t); - } - } + outer_3_plus::<{ (0 * STEP * 2) / COEFFICIENTS_IN_SIMD_UNIT }, STEP_BY, 25847>(re); } #[inline(always)] pub(crate) fn ntt( mut re: [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT], ) -> [PortableSIMDUnit; SIMD_UNITS_IN_RING_ELEMENT] { - let mut zeta_i = 0; - - ntt_at_layer_3_plus::<7>(&mut zeta_i, &mut re); - ntt_at_layer_3_plus::<6>(&mut zeta_i, &mut re); - ntt_at_layer_3_plus::<5>(&mut zeta_i, &mut re); - ntt_at_layer_3_plus::<4>(&mut zeta_i, &mut re); - ntt_at_layer_3_plus::<3>(&mut zeta_i, &mut re); - ntt_at_layer_2(&mut zeta_i, &mut re); - ntt_at_layer_1(&mut zeta_i, &mut re); - ntt_at_layer_0(&mut zeta_i, &mut re); + ntt_at_layer_7(&mut re); + ntt_at_layer_6(&mut re); + ntt_at_layer_5(&mut re); + ntt_at_layer_4(&mut re); + ntt_at_layer_3(&mut re); + ntt_at_layer_2(&mut re); + ntt_at_layer_1(&mut re); + ntt_at_layer_0(&mut re); re } diff --git a/libcrux-ml-dsa/src/simd/portable/vector_type.rs b/libcrux-ml-dsa/src/simd/portable/vector_type.rs new file mode 100644 index 000000000..3a71624d9 --- /dev/null +++ b/libcrux-ml-dsa/src/simd/portable/vector_type.rs @@ -0,0 +1,26 @@ +use crate::simd::traits::COEFFICIENTS_IN_SIMD_UNIT; +/// Values having this type hold a representative 'x' of the ML-DSA field. +/// We use 'fe' as a shorthand for this type. +pub(crate) type FieldElement = i32; + +#[derive(Clone, Copy)] +pub struct PortableSIMDUnit { + pub(crate) coefficients: [FieldElement; COEFFICIENTS_IN_SIMD_UNIT], +} + +#[allow(non_snake_case)] +pub(crate) fn ZERO() -> PortableSIMDUnit { + PortableSIMDUnit { + coefficients: [0i32; COEFFICIENTS_IN_SIMD_UNIT], + } +} + +pub(crate) fn from_coefficient_array(array: &[i32]) -> PortableSIMDUnit { + PortableSIMDUnit { + coefficients: array[0..8].try_into().unwrap(), + } +} + +pub(crate) fn to_coefficient_array(x: &PortableSIMDUnit) -> [i32; 8] { + x.coefficients +} diff --git a/libcrux-ml-dsa/src/simd/tests.rs b/libcrux-ml-dsa/src/simd/tests.rs new file mode 100644 index 000000000..acd67ac45 --- /dev/null +++ b/libcrux-ml-dsa/src/simd/tests.rs @@ -0,0 +1,94 @@ +use crate::simd::traits::*; + +fn test_decompose_generic() { + // When GAMMA2 = 95,232 + let input = SIMDUnit::from_coefficient_array(&[ + 5520769, 5416853, 180455, 8127421, 5159850, 5553986, 3391280, 3968290, + ]); + + let expected_low = SIMDUnit::from_coefficient_array(&[ + -2687, 83861, -10009, -62531, 17322, 30530, -37072, -31454, + ]); + let expected_high = SIMDUnit::from_coefficient_array(&[29, 28, 1, 43, 27, 29, 18, 21]); + + let (low, high) = SIMDUnit::decompose::<95_232>(input); + + assert_eq!( + low.to_coefficient_array(), + expected_low.to_coefficient_array() + ); + assert_eq!( + high.to_coefficient_array(), + expected_high.to_coefficient_array() + ); + + // When GAMMA2 = 261,888 + let input = SIMDUnit::from_coefficient_array(&[ + 2108939, 7162128, 6506792, 7957464, 2350341, 8333084, 496214, 2168929, + ]); + + let expected_low = SIMDUnit::from_coefficient_array(&[ + 13835, -170736, 221480, 100824, 255237, -47333, -27562, 73825, + ]); + let expected_high = SIMDUnit::from_coefficient_array(&[4, 14, 12, 15, 4, 0, 1, 4]); + + let (low, high) = SIMDUnit::decompose::<261_888>(input); + + assert_eq!( + low.to_coefficient_array(), + expected_low.to_coefficient_array() + ); + assert_eq!( + high.to_coefficient_array(), + expected_high.to_coefficient_array() + ); +} + +fn test_power2round_generic() { + let input = SIMDUnit::from_coefficient_array(&[ + 6950677, 3362411, 5783989, 5909314, 6459529, 5751812, 864332, 3667708, + ]); + + let expected_low = + SIMDUnit::from_coefficient_array(&[3861, 3691, 437, 2882, -3959, 1028, -4020, -2308]); + let expected_high = SIMDUnit::from_coefficient_array(&[848, 410, 706, 721, 789, 702, 106, 448]); + + let (low, high) = SIMDUnit::power2round(input); + + assert_eq!( + low.to_coefficient_array(), + expected_low.to_coefficient_array() + ); + assert_eq!( + high.to_coefficient_array(), + expected_high.to_coefficient_array() + ); +} + +#[cfg(not(feature = "simd256"))] +mod portable { + use super::{test_decompose_generic, test_power2round_generic}; + + #[test] + fn test_decompose() { + test_decompose_generic::(); + } + #[test] + fn test_power2round() { + test_power2round_generic::(); + } +} + +#[cfg(feature = "simd256")] +mod avx2 { + use super::{test_decompose_generic, test_power2round_generic}; + + #[test] + fn test_decompose() { + test_decompose_generic::(); + } + #[test] + fn test_power2round() { + test_power2round_generic::(); + } +} diff --git a/libcrux-ml-dsa/src/simd/traits.rs b/libcrux-ml-dsa/src/simd/traits.rs index 71d7455f1..d851dab1a 100644 --- a/libcrux-ml-dsa/src/simd/traits.rs +++ b/libcrux-ml-dsa/src/simd/traits.rs @@ -14,35 +14,6 @@ pub const INVERSE_OF_MODULUS_MOD_MONTGOMERY_R: u64 = 58_728_449; /// We use 'fer' as a shorthand for this type. pub(crate) type FieldElementTimesMontgomeryR = i32; -pub(crate) const ZETAS_TIMES_MONTGOMERY_R: [FieldElementTimesMontgomeryR; 256] = [ - 0, 25847, -2608894, -518909, 237124, -777960, -876248, 466468, 1826347, 2353451, -359251, - -2091905, 3119733, -2884855, 3111497, 2680103, 2725464, 1024112, -1079900, 3585928, -549488, - -1119584, 2619752, -2108549, -2118186, -3859737, -1399561, -3277672, 1757237, -19422, 4010497, - 280005, 2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439, -3861115, - -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299, -1699267, -1643818, 3505694, - -3821735, 3507263, -2140649, -1600420, 3699596, 811944, 531354, 954230, 3881043, 3900724, - -2556880, 2071892, -2797779, -3930395, -1528703, -3677745, -3041255, -1452451, 3475950, - 2176455, -1585221, -1257611, 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922, - 3412210, -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047, -671102, -1228525, - -22981, -1308169, -381987, 1349076, 1852771, -1430430, -3343383, 264944, 508951, 3097992, - 44288, -1100098, 904516, 3958618, -3724342, -8578, 1653064, -3249728, 2389356, -210977, 759969, - -1316856, 189548, -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330, 1285669, - -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961, 2091667, 3407706, 2316500, - 3817976, -3342478, 2244091, -2446433, -3562462, 266997, 2434439, -1235728, 3513181, -3520352, - -3759364, -1197226, -3193378, 900702, 1859098, 909542, 819034, 495491, -1613174, -43260, - -522500, -655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838, 342297, - 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044, 2842341, 2691481, -2590150, - 1265009, 4055324, 1247620, 2486353, 1595974, -3767016, 1250494, 2635921, -3548272, -2994039, - 1869119, 1903435, -1050970, -1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, - -1962642, -1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031, -542412, - -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993, -2013608, 2432395, 2454455, - -164721, 1957272, 3369112, 185531, -1207385, -3183426, 162844, 1616392, 3014001, 810149, - 1652634, -3694233, -1799107, -3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, - 472078, -426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893, -2939036, - -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687, -554416, 3919660, -48306, - -1362209, 3937738, 1400424, -846154, 1976782, -]; - pub(crate) trait Operations: Copy + Clone { #[allow(non_snake_case)] fn ZERO() -> Self; @@ -60,7 +31,6 @@ pub(crate) trait Operations: Copy + Clone { // Modular operations fn montgomery_multiply(lhs: Self, rhs: Self) -> Self; - fn montgomery_multiply_by_constant(simd_unit: Self, c: i32) -> Self; fn shift_left_then_reduce(simd_unit: Self) -> Self; // Decomposition operations @@ -104,119 +74,8 @@ pub(crate) trait Operations: Copy + Clone { // NTT fn ntt(simd_units: [Self; SIMD_UNITS_IN_RING_ELEMENT]) -> [Self; SIMD_UNITS_IN_RING_ELEMENT]; - // Inverse NTT - fn invert_ntt_at_layer_0( - simd_unit: Self, - zeta0: i32, - zeta1: i32, - zeta2: i32, - zeta3: i32, - ) -> Self; - fn invert_ntt_at_layer_1(simd_unit: Self, zeta0: i32, zeta1: i32) -> Self; - fn invert_ntt_at_layer_2(simd_unit: Self, zeta: i32) -> Self; -} - -// hax does not support trait with default implementations, so we use the -// following pattern. -pub fn montgomery_multiply_by_fer(simd_unit: S, fer: i32) -> S { - S::montgomery_multiply_by_constant(simd_unit, fer) -} - -#[cfg(test)] -mod tests { - use super::*; - - fn test_decompose_generic() { - // When GAMMA2 = 95,232 - let input = SIMDUnit::from_coefficient_array(&[ - 5520769, 5416853, 180455, 8127421, 5159850, 5553986, 3391280, 3968290, - ]); - - let expected_low = SIMDUnit::from_coefficient_array(&[ - -2687, 83861, -10009, -62531, 17322, 30530, -37072, -31454, - ]); - let expected_high = SIMDUnit::from_coefficient_array(&[29, 28, 1, 43, 27, 29, 18, 21]); - - let (low, high) = SIMDUnit::decompose::<95_232>(input); - - assert_eq!( - low.to_coefficient_array(), - expected_low.to_coefficient_array() - ); - assert_eq!( - high.to_coefficient_array(), - expected_high.to_coefficient_array() - ); - - // When GAMMA2 = 261,888 - let input = SIMDUnit::from_coefficient_array(&[ - 2108939, 7162128, 6506792, 7957464, 2350341, 8333084, 496214, 2168929, - ]); - - let expected_low = SIMDUnit::from_coefficient_array(&[ - 13835, -170736, 221480, 100824, 255237, -47333, -27562, 73825, - ]); - let expected_high = SIMDUnit::from_coefficient_array(&[4, 14, 12, 15, 4, 0, 1, 4]); - - let (low, high) = SIMDUnit::decompose::<261_888>(input); - - assert_eq!( - low.to_coefficient_array(), - expected_low.to_coefficient_array() - ); - assert_eq!( - high.to_coefficient_array(), - expected_high.to_coefficient_array() - ); - } - - fn test_power2round_generic() { - let input = SIMDUnit::from_coefficient_array(&[ - 6950677, 3362411, 5783989, 5909314, 6459529, 5751812, 864332, 3667708, - ]); - - let expected_low = - SIMDUnit::from_coefficient_array(&[3861, 3691, 437, 2882, -3959, 1028, -4020, -2308]); - let expected_high = - SIMDUnit::from_coefficient_array(&[848, 410, 706, 721, 789, 702, 106, 448]); - - let (low, high) = SIMDUnit::power2round(input); - - assert_eq!( - low.to_coefficient_array(), - expected_low.to_coefficient_array() - ); - assert_eq!( - high.to_coefficient_array(), - expected_high.to_coefficient_array() - ); - } - - #[cfg(not(feature = "simd256"))] - mod portable { - use super::{test_decompose_generic, test_power2round_generic}; - - #[test] - fn test_decompose() { - test_decompose_generic::(); - } - #[test] - fn test_power2round() { - test_power2round_generic::(); - } - } - - #[cfg(feature = "simd256")] - mod avx2 { - use super::{test_decompose_generic, test_power2round_generic}; - - #[test] - fn test_decompose() { - test_decompose_generic::(); - } - #[test] - fn test_power2round() { - test_power2round_generic::(); - } - } + // invert NTT and convert to standard domain + fn invert_ntt_montgomery( + simd_units: [Self; SIMD_UNITS_IN_RING_ELEMENT], + ) -> [Self; SIMD_UNITS_IN_RING_ELEMENT]; } diff --git a/libcrux-ml-dsa/src/types.rs b/libcrux-ml-dsa/src/types.rs index 72c5e1479..d432b1e99 100644 --- a/libcrux-ml-dsa/src/types.rs +++ b/libcrux-ml-dsa/src/types.rs @@ -33,3 +33,30 @@ pub struct MLDSAKeyPair, pub verification_key: MLDSAVerificationKey, } + +use crate::{constants::*, polynomial::PolynomialRingElement, simd::traits::Operations}; + +pub(crate) struct Signature< + SIMDUnit: Operations, + const COMMITMENT_HASH_SIZE: usize, + const COLUMNS_IN_A: usize, + const ROWS_IN_A: usize, +> { + pub commitment_hash: [u8; COMMITMENT_HASH_SIZE], + pub signer_response: [PolynomialRingElement; COLUMNS_IN_A], + pub hint: [[i32; COEFFICIENTS_IN_RING_ELEMENT]; ROWS_IN_A], +} + +#[derive(Debug)] +pub enum VerificationError { + MalformedHintError, + SignerResponseExceedsBoundError, + CommitmentHashesDontMatchError, + ContextTooLongError, +} + +#[derive(Debug)] +pub enum SigningError { + RejectionSamplingError, + ContextTooLongError, +} diff --git a/libcrux-ml-dsa/tests/acvp.rs b/libcrux-ml-dsa/tests/acvp.rs index ebdc2ce9f..75f0c1ddf 100644 --- a/libcrux-ml-dsa/tests/acvp.rs +++ b/libcrux-ml-dsa/tests/acvp.rs @@ -63,8 +63,6 @@ struct ResultPromptTestGroup { #[test] fn keygen() { - use libcrux_ml_dsa::*; - let prompts: Prompts = read("keygen", "prompt.json"); assert!(prompts.algorithm == "ML-DSA"); assert!(prompts.revision == "FIPS204"); @@ -83,37 +81,50 @@ fn keygen() { eprintln!("{parameter_set}"); for test in kat.tests { - eprintln!(" {}", test.tcId); - fn check( - keys: MLDSAKeyPair, - result: &KeyGenResult, - ) { - assert_eq!(result.pk, keys.verification_key.as_slice()); - assert_eq!(result.sk, keys.signing_key.as_slice()); - } - - let expected_result = results - .testGroups - .iter() - .find(|tg| tg.tgId == kat.tgId) - .unwrap() - .tests - .iter() - .find(|t| t.tcId == test.tcId) - .unwrap(); - - match parameter_set.as_str() { - "ML-DSA-44" => check(ml_dsa_44::generate_key_pair(test.seed), expected_result), - - "ML-DSA-65" => check(ml_dsa_65::generate_key_pair(test.seed), expected_result), - - "ML-DSA-87" => check(ml_dsa_87::generate_key_pair(test.seed), expected_result), - _ => unimplemented!(), - } + keygen_inner(test, &results, kat.tgId, ¶meter_set); } } } +#[inline(never)] +#[allow(non_snake_case)] +fn keygen_inner( + test: KeyGenPrompt, + results: &Results, + tgId: usize, + parameter_set: &String, +) { + use libcrux_ml_dsa::*; + eprintln!(" {}", test.tcId); + #[inline(never)] + fn check( + keys: MLDSAKeyPair, + result: &KeyGenResult, + ) { + assert_eq!(result.pk, keys.verification_key.as_slice()); + assert_eq!(result.sk, keys.signing_key.as_slice()); + } + + let expected_result = results + .testGroups + .iter() + .find(|tg| tg.tgId == tgId) + .unwrap() + .tests + .iter() + .find(|t| t.tcId == test.tcId) + .unwrap(); + + match parameter_set.as_str() { + "ML-DSA-44" => check(ml_dsa_44::generate_key_pair(test.seed), expected_result), + + "ML-DSA-65" => check(ml_dsa_65::generate_key_pair(test.seed), expected_result), + + "ML-DSA-87" => check(ml_dsa_87::generate_key_pair(test.seed), expected_result), + _ => unimplemented!(), + } +} + fn read(variant: &str, file: &str) -> T { let katfile_path = Path::new("tests") .join("kats") @@ -128,8 +139,6 @@ fn read(variant: &str, file: &str) -> T { #[test] fn siggen() { - use libcrux_ml_dsa::*; - let prompts: Prompts = read("siggen", "prompt.json"); assert!(prompts.algorithm == "ML-DSA"); assert!(prompts.revision == "FIPS204"); @@ -148,59 +157,69 @@ fn siggen() { eprintln!("{parameter_set}"); for test in kat.tests { - eprintln!(" {}", test.tcId); - let expected_result = results - .testGroups - .iter() - .find(|tg| tg.tgId == kat.tgId) - .unwrap() - .tests - .iter() - .find(|t| t.tcId == test.tcId) - .unwrap(); - - let Randomness(rnd) = test.rnd.unwrap_or(Randomness([0u8; 32])); - - match parameter_set.as_str() { - "ML-DSA-44" => { - let signature = ml_dsa_44::sign_internal( - &MLDSASigningKey(test.sk.try_into().unwrap()), - &test.message, - rnd, - ) - .unwrap(); - assert_eq!(signature.as_slice(), expected_result.signature); - } - - "ML-DSA-65" => { - let signature = ml_dsa_65::sign_internal( - &MLDSASigningKey(test.sk.try_into().unwrap()), - &test.message, - rnd, - ) - .unwrap(); - assert_eq!(signature.as_slice(), expected_result.signature); - } - - "ML-DSA-87" => { - let signature = ml_dsa_87::sign_internal( - &MLDSASigningKey(test.sk.try_into().unwrap()), - &test.message, - rnd, - ) - .unwrap(); - assert_eq!(signature.as_slice(), expected_result.signature); - } - _ => unimplemented!(), - } + siggen_inner(test, &results, kat.tgId, ¶meter_set); } } } -#[test] -fn sigver() { +#[inline(never)] +#[allow(non_snake_case)] +fn siggen_inner( + test: SigGenTest, + results: &Results, + tgId: usize, + parameter_set: &String, +) { use libcrux_ml_dsa::*; + eprintln!(" {}", test.tcId); + let expected_result = results + .testGroups + .iter() + .find(|tg| tg.tgId == tgId) + .unwrap() + .tests + .iter() + .find(|t| t.tcId == test.tcId) + .unwrap(); + + let Randomness(rnd) = test.rnd.unwrap_or(Randomness([0u8; 32])); + + match parameter_set.as_str() { + "ML-DSA-44" => { + let signature = ml_dsa_44::sign_internal( + &MLDSASigningKey(test.sk.try_into().unwrap()), + &test.message, + rnd, + ) + .unwrap(); + assert_eq!(signature.as_slice(), expected_result.signature); + } + "ML-DSA-65" => { + let signature = ml_dsa_65::sign_internal( + &MLDSASigningKey(test.sk.try_into().unwrap()), + &test.message, + rnd, + ) + .unwrap(); + assert_eq!(signature.as_slice(), expected_result.signature); + } + + "ML-DSA-87" => { + let signature = ml_dsa_87::sign_internal( + &MLDSASigningKey(test.sk.try_into().unwrap()), + &test.message, + rnd, + ) + .unwrap(); + assert_eq!(signature.as_slice(), expected_result.signature); + } + _ => unimplemented!(), + } +} + +#[test] +fn sigver() { let prompts: Prompts = read("sigver", "prompt.json"); assert!(prompts.algorithm == "ML-DSA"); assert!(prompts.revision == "FIPS204"); @@ -219,47 +238,60 @@ fn sigver() { eprintln!("{parameter_set}"); for test in kat.tests { - eprintln!(" {}", test.tcId); - let expected_result = results - .testGroups - .iter() - .find(|tg| tg.tgId == kat.tgId) - .unwrap() - .tests - .iter() - .find(|t| t.tcId == test.tcId) - .unwrap(); - - match parameter_set.as_str() { - "ML-DSA-44" => { - let valid = ml_dsa_44::verify_internal( - &MLDSAVerificationKey(kat.pk.clone().try_into().unwrap()), - &test.message, - &MLDSASignature(test.signature.try_into().unwrap()), - ); - assert_eq!(valid.is_ok(), expected_result.testPassed); - } - - "ML-DSA-65" => { - let valid = ml_dsa_65::verify_internal( - &MLDSAVerificationKey(kat.pk.clone().try_into().unwrap()), - &test.message, - &MLDSASignature(test.signature.try_into().unwrap()), - ); - assert_eq!(valid.is_ok(), expected_result.testPassed); - } - - "ML-DSA-87" => { - let valid = ml_dsa_87::verify_internal( - &MLDSAVerificationKey(kat.pk.clone().try_into().unwrap()), - &test.message, - &MLDSASignature(test.signature.try_into().unwrap()), - ); - assert_eq!(valid.is_ok(), expected_result.testPassed); - } - _ => unimplemented!(), - } + sigver_inner(test, &results, kat.tgId, &kat.pk, ¶meter_set); + } + } +} + +#[inline(never)] +#[allow(non_snake_case)] +fn sigver_inner( + test: SigVerTest, + results: &Results, + tgId: usize, + pk: &[u8], + parameter_set: &String, +) { + use libcrux_ml_dsa::*; + eprintln!(" {}", test.tcId); + let expected_result = results + .testGroups + .iter() + .find(|tg| tg.tgId == tgId) + .unwrap() + .tests + .iter() + .find(|t| t.tcId == test.tcId) + .unwrap(); + + match parameter_set.as_str() { + "ML-DSA-44" => { + let valid = ml_dsa_44::verify_internal( + &MLDSAVerificationKey(pk.to_owned().try_into().unwrap()), + &test.message, + &MLDSASignature(test.signature.try_into().unwrap()), + ); + assert_eq!(valid.is_ok(), expected_result.testPassed); + } + + "ML-DSA-65" => { + let valid = ml_dsa_65::verify_internal( + &MLDSAVerificationKey(pk.to_owned().try_into().unwrap()), + &test.message, + &MLDSASignature(test.signature.try_into().unwrap()), + ); + assert_eq!(valid.is_ok(), expected_result.testPassed); + } + + "ML-DSA-87" => { + let valid = ml_dsa_87::verify_internal( + &MLDSAVerificationKey(pk.to_owned().try_into().unwrap()), + &test.message, + &MLDSASignature(test.signature.try_into().unwrap()), + ); + assert_eq!(valid.is_ok(), expected_result.testPassed); } + _ => unimplemented!(), } } diff --git a/libcrux-ml-kem/Cargo.toml b/libcrux-ml-kem/Cargo.toml index 87e585f3c..08e922560 100644 --- a/libcrux-ml-kem/Cargo.toml +++ b/libcrux-ml-kem/Cargo.toml @@ -26,8 +26,7 @@ rand = { version = "0.8", optional = true } libcrux-platform = { version = "0.0.2-beta.2", path = "../sys/platform" } libcrux-sha3 = { version = "0.0.2-beta.2", path = "../libcrux-sha3" } libcrux-intrinsics = { version = "0.0.2-beta.2", path = "../libcrux-intrinsics" } - -hax-lib.workspace = true +hax-lib = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax/" } [features] # By default all variants and std are enabled. @@ -44,9 +43,6 @@ mlkem512 = [] mlkem768 = [] mlkem1024 = [] -# Enable the unpacked API -unpacked = [] - # Enable Round 3 Kyber in addition to ML-KEM kyber = [] @@ -83,7 +79,7 @@ name = "keygen" required-features = ["mlkem768"] [package.metadata."docs.rs"] -features = ["pre-verification", "kyber", "unpacked"] +features = ["pre-verification", "kyber"] rustdoc-args = ["--cfg", "doc_cfg"] [lints.rust] diff --git a/libcrux-ml-kem/c/code_gen.txt b/libcrux-ml-kem/c/code_gen.txt index 69ab3fe65..72e8e591e 100644 --- a/libcrux-ml-kem/c/code_gen.txt +++ b/libcrux-ml-kem/c/code_gen.txt @@ -3,4 +3,4 @@ Charon: 3a133fe0eee9bd3928d5bb16c24ddd2dd0f3ee7f Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc -Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 +Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 diff --git a/libcrux-ml-kem/c/internal/libcrux_core.h b/libcrux-ml-kem/c/internal/libcrux_core.h index bec9045cd..cc309c138 100644 --- a/libcrux-ml-kem/c/internal/libcrux_core.h +++ b/libcrux-ml-kem/c/internal/libcrux_core.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __internal_libcrux_core_H @@ -60,18 +60,6 @@ typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair768_s { uint8_t snd[1184U]; } libcrux_ml_kem_utils_extraction_helper_Keypair768; -/** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPublicKey)#16} -*/ -/** -A monomorphic instance of libcrux_ml_kem.types.from_5a -with const generics -- SIZE= 1568 -*/ -libcrux_ml_kem_types_MlKemPublicKey_64 libcrux_ml_kem_types_from_5a_af( - uint8_t value[1568U]); - /** This function found in impl {libcrux_ml_kem::types::MlKemKeyPair#21} @@ -88,28 +76,16 @@ libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_types_from_3a_94( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPrivateKey)#9} +libcrux_ml_kem::types::MlKemPrivateKey)#12} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_7f +A monomorphic instance of libcrux_ml_kem.types.from_9a with const generics - SIZE= 3168 */ -libcrux_ml_kem_types_MlKemPrivateKey_83 libcrux_ml_kem_types_from_7f_39( +libcrux_ml_kem_types_MlKemPrivateKey_83 libcrux_ml_kem_types_from_9a_39( uint8_t value[3168U]); -/** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPublicKey)#16} -*/ -/** -A monomorphic instance of libcrux_ml_kem.types.from_5a -with const generics -- SIZE= 1184 -*/ -libcrux_ml_kem_types_MlKemPublicKey_30 libcrux_ml_kem_types_from_5a_d0( - uint8_t value[1184U]); - /** This function found in impl {libcrux_ml_kem::types::MlKemKeyPair#21} @@ -126,28 +102,16 @@ libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_types_from_3a_74( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPrivateKey)#9} +libcrux_ml_kem::types::MlKemPrivateKey)#12} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_7f +A monomorphic instance of libcrux_ml_kem.types.from_9a with const generics - SIZE= 2400 */ -libcrux_ml_kem_types_MlKemPrivateKey_d9 libcrux_ml_kem_types_from_7f_28( +libcrux_ml_kem_types_MlKemPrivateKey_d9 libcrux_ml_kem_types_from_9a_28( uint8_t value[2400U]); -/** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPublicKey)#16} -*/ -/** -A monomorphic instance of libcrux_ml_kem.types.from_5a -with const generics -- SIZE= 800 -*/ -libcrux_ml_kem_types_MlKemPublicKey_52 libcrux_ml_kem_types_from_5a_4d( - uint8_t value[800U]); - /** This function found in impl {libcrux_ml_kem::types::MlKemKeyPair#21} @@ -164,14 +128,14 @@ libcrux_ml_kem_types_MlKemKeyPair_3e libcrux_ml_kem_types_from_3a_fa( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPrivateKey)#9} +libcrux_ml_kem::types::MlKemPrivateKey)#12} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_7f +A monomorphic instance of libcrux_ml_kem.types.from_9a with const generics - SIZE= 1632 */ -libcrux_ml_kem_types_MlKemPrivateKey_fa libcrux_ml_kem_types_from_7f_2a( +libcrux_ml_kem_types_MlKemPrivateKey_fa libcrux_ml_kem_types_from_9a_2a( uint8_t value[1632U]); /** @@ -187,26 +151,62 @@ uint8_t *libcrux_ml_kem_types_as_slice_fd_d0( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemCiphertext)#2} +libcrux_ml_kem::types::MlKemPublicKey)#19} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_5f +with const generics +- SIZE= 1184 +*/ +libcrux_ml_kem_types_MlKemPublicKey_30 libcrux_ml_kem_types_from_5f_d0( + uint8_t value[1184U]); + +typedef struct Eurydice_slice_uint8_t_x4_s { + Eurydice_slice fst; + Eurydice_slice snd; + Eurydice_slice thd; + Eurydice_slice f3; +} Eurydice_slice_uint8_t_x4; + +/** +A monomorphic instance of libcrux_ml_kem.types.unpack_private_key +with const generics +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +Eurydice_slice_uint8_t_x4 libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_slice private_key); + +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemCiphertext)#5} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_01 +A monomorphic instance of libcrux_ml_kem.types.from_00 with const generics - SIZE= 1088 */ -libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types_from_01_80( +libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types_from_00_80( uint8_t value[1088U]); +/** +A monomorphic instance of libcrux_ml_kem.utils.prf_input_inc +with const generics +- K= 3 +*/ +uint8_t libcrux_ml_kem_utils_prf_input_inc_e0(uint8_t (*prf_inputs)[33U], + uint8_t domain_separator); + /** This function found in impl {(core::convert::AsRef<@Slice> for -libcrux_ml_kem::types::MlKemCiphertext)#1} +libcrux_ml_kem::types::MlKemCiphertext)#4} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +A monomorphic instance of libcrux_ml_kem.types.as_ref_43 with const generics - SIZE= 1088 */ -Eurydice_slice libcrux_ml_kem_types_as_ref_00_80( +Eurydice_slice libcrux_ml_kem_types_as_ref_43_80( libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self); /** @@ -233,26 +233,55 @@ uint8_t *libcrux_ml_kem_types_as_slice_fd_4d( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemCiphertext)#2} +libcrux_ml_kem::types::MlKemPublicKey)#19} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_01 +A monomorphic instance of libcrux_ml_kem.types.from_5f +with const generics +- SIZE= 800 +*/ +libcrux_ml_kem_types_MlKemPublicKey_52 libcrux_ml_kem_types_from_5f_4d( + uint8_t value[800U]); + +/** +A monomorphic instance of libcrux_ml_kem.types.unpack_private_key +with const generics +- CPA_SECRET_KEY_SIZE= 768 +- PUBLIC_KEY_SIZE= 800 +*/ +Eurydice_slice_uint8_t_x4 libcrux_ml_kem_types_unpack_private_key_0c( + Eurydice_slice private_key); + +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemCiphertext)#5} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_00 with const generics - SIZE= 768 */ -libcrux_ml_kem_types_MlKemCiphertext_1a libcrux_ml_kem_types_from_01_d0( +libcrux_ml_kem_types_MlKemCiphertext_1a libcrux_ml_kem_types_from_00_d0( uint8_t value[768U]); +/** +A monomorphic instance of libcrux_ml_kem.utils.prf_input_inc +with const generics +- K= 2 +*/ +uint8_t libcrux_ml_kem_utils_prf_input_inc_fd(uint8_t (*prf_inputs)[33U], + uint8_t domain_separator); + /** This function found in impl {(core::convert::AsRef<@Slice> for -libcrux_ml_kem::types::MlKemCiphertext)#1} +libcrux_ml_kem::types::MlKemCiphertext)#4} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +A monomorphic instance of libcrux_ml_kem.types.as_ref_43 with const generics - SIZE= 768 */ -Eurydice_slice libcrux_ml_kem_types_as_ref_00_d0( +Eurydice_slice libcrux_ml_kem_types_as_ref_43_d0( libcrux_ml_kem_types_MlKemCiphertext_1a *self); /** @@ -277,6 +306,27 @@ with const generics uint8_t *libcrux_ml_kem_types_as_slice_fd_af( libcrux_ml_kem_types_MlKemPublicKey_64 *self); +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemPublicKey)#19} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_5f +with const generics +- SIZE= 1568 +*/ +libcrux_ml_kem_types_MlKemPublicKey_64 libcrux_ml_kem_types_from_5f_af( + uint8_t value[1568U]); + +/** +A monomorphic instance of libcrux_ml_kem.types.unpack_private_key +with const generics +- CPA_SECRET_KEY_SIZE= 1536 +- PUBLIC_KEY_SIZE= 1568 +*/ +Eurydice_slice_uint8_t_x4 libcrux_ml_kem_types_unpack_private_key_1f( + Eurydice_slice private_key); + /** A monomorphic instance of core.result.Result with types uint8_t[32size_t], core_array_TryFromSliceError @@ -314,16 +364,24 @@ void libcrux_ml_kem_utils_into_padded_array_b6(Eurydice_slice slice, /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemCiphertext)#2} +libcrux_ml_kem::types::MlKemCiphertext)#5} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_01 +A monomorphic instance of libcrux_ml_kem.types.from_00 with const generics - SIZE= 1568 */ -libcrux_ml_kem_types_MlKemCiphertext_64 libcrux_ml_kem_types_from_01_af( +libcrux_ml_kem_types_MlKemCiphertext_64 libcrux_ml_kem_types_from_00_af( uint8_t value[1568U]); +/** +A monomorphic instance of libcrux_ml_kem.utils.prf_input_inc +with const generics +- K= 4 +*/ +uint8_t libcrux_ml_kem_utils_prf_input_inc_ac(uint8_t (*prf_inputs)[33U], + uint8_t domain_separator); + /** Pad the `slice` with `0`s at the end. */ @@ -337,14 +395,14 @@ void libcrux_ml_kem_utils_into_padded_array_c8(Eurydice_slice slice, /** This function found in impl {(core::convert::AsRef<@Slice> for -libcrux_ml_kem::types::MlKemCiphertext)#1} +libcrux_ml_kem::types::MlKemCiphertext)#4} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +A monomorphic instance of libcrux_ml_kem.types.as_ref_43 with const generics - SIZE= 1568 */ -Eurydice_slice libcrux_ml_kem_types_as_ref_00_af( +Eurydice_slice libcrux_ml_kem_types_as_ref_43_af( libcrux_ml_kem_types_MlKemCiphertext_64 *self); /** diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h index 415e60735..3b4f9397e 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __internal_libcrux_mlkem_avx2_H @@ -43,6 +43,16 @@ with const generics */ bool libcrux_ml_kem_ind_cca_validate_public_key_ed(uint8_t *public_key); +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_only_ae( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key); + /** A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash @@ -130,6 +140,16 @@ with const generics */ bool libcrux_ml_kem_ind_cca_validate_public_key_1e(uint8_t *public_key); +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 4 +- SECRET_KEY_SIZE= 3168 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_only_5e( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key); + /** A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash @@ -217,6 +237,16 @@ with const generics */ bool libcrux_ml_kem_ind_cca_validate_public_key_ba(uint8_t *public_key); +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 2 +- SECRET_KEY_SIZE= 1632 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_only_4d( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key); + /** A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash diff --git a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h index e795935db..4cddab71a 100644 --- a/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/internal/libcrux_mlkem_portable.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __internal_libcrux_mlkem_portable_H @@ -48,6 +48,16 @@ with const generics */ bool libcrux_ml_kem_ind_cca_validate_public_key_00(uint8_t *public_key); +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] +with const generics +- K= 4 +- SECRET_KEY_SIZE= 3168 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_only_60( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key); + /** A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] @@ -135,6 +145,16 @@ with const generics */ bool libcrux_ml_kem_ind_cca_validate_public_key_86(uint8_t *public_key); +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] +with const generics +- K= 2 +- SECRET_KEY_SIZE= 1632 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_only_30( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key); + /** A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] @@ -222,6 +242,16 @@ with const generics */ bool libcrux_ml_kem_ind_cca_validate_public_key_6c(uint8_t *public_key); +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_only_d6( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key); + /** A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h index 7f8fb03e9..771d3a368 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __internal_libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h index c21de7718..4701013e7 100644 --- a/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/internal/libcrux_sha3_internal.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __internal_libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_core.c b/libcrux-ml-kem/c/libcrux_core.c index 4b786c0db..ce68f6089 100644 --- a/libcrux-ml-kem/c/libcrux_core.c +++ b/libcrux-ml-kem/c/libcrux_core.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "internal/libcrux_core.h" @@ -71,25 +71,6 @@ void libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_i memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -/** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPublicKey)#16} -*/ -/** -A monomorphic instance of libcrux_ml_kem.types.from_5a -with const generics -- SIZE= 1568 -*/ -libcrux_ml_kem_types_MlKemPublicKey_64 libcrux_ml_kem_types_from_5a_af( - uint8_t value[1568U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_value[1568U]; - memcpy(copy_of_value, value, (size_t)1568U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPublicKey_64 lit; - memcpy(lit.value, copy_of_value, (size_t)1568U * sizeof(uint8_t)); - return lit; -} - /** This function found in impl {libcrux_ml_kem::types::MlKemKeyPair#21} @@ -109,14 +90,14 @@ libcrux_ml_kem_mlkem1024_MlKem1024KeyPair libcrux_ml_kem_types_from_3a_94( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPrivateKey)#9} +libcrux_ml_kem::types::MlKemPrivateKey)#12} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_7f +A monomorphic instance of libcrux_ml_kem.types.from_9a with const generics - SIZE= 3168 */ -libcrux_ml_kem_types_MlKemPrivateKey_83 libcrux_ml_kem_types_from_7f_39( +libcrux_ml_kem_types_MlKemPrivateKey_83 libcrux_ml_kem_types_from_9a_39( uint8_t value[3168U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[3168U]; @@ -126,25 +107,6 @@ libcrux_ml_kem_types_MlKemPrivateKey_83 libcrux_ml_kem_types_from_7f_39( return lit; } -/** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPublicKey)#16} -*/ -/** -A monomorphic instance of libcrux_ml_kem.types.from_5a -with const generics -- SIZE= 1184 -*/ -libcrux_ml_kem_types_MlKemPublicKey_30 libcrux_ml_kem_types_from_5a_d0( - uint8_t value[1184U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_value[1184U]; - memcpy(copy_of_value, value, (size_t)1184U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPublicKey_30 lit; - memcpy(lit.value, copy_of_value, (size_t)1184U * sizeof(uint8_t)); - return lit; -} - /** This function found in impl {libcrux_ml_kem::types::MlKemKeyPair#21} @@ -164,14 +126,14 @@ libcrux_ml_kem_mlkem768_MlKem768KeyPair libcrux_ml_kem_types_from_3a_74( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPrivateKey)#9} +libcrux_ml_kem::types::MlKemPrivateKey)#12} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_7f +A monomorphic instance of libcrux_ml_kem.types.from_9a with const generics - SIZE= 2400 */ -libcrux_ml_kem_types_MlKemPrivateKey_d9 libcrux_ml_kem_types_from_7f_28( +libcrux_ml_kem_types_MlKemPrivateKey_d9 libcrux_ml_kem_types_from_9a_28( uint8_t value[2400U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[2400U]; @@ -181,25 +143,6 @@ libcrux_ml_kem_types_MlKemPrivateKey_d9 libcrux_ml_kem_types_from_7f_28( return lit; } -/** -This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPublicKey)#16} -*/ -/** -A monomorphic instance of libcrux_ml_kem.types.from_5a -with const generics -- SIZE= 800 -*/ -libcrux_ml_kem_types_MlKemPublicKey_52 libcrux_ml_kem_types_from_5a_4d( - uint8_t value[800U]) { - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_value[800U]; - memcpy(copy_of_value, value, (size_t)800U * sizeof(uint8_t)); - libcrux_ml_kem_types_MlKemPublicKey_52 lit; - memcpy(lit.value, copy_of_value, (size_t)800U * sizeof(uint8_t)); - return lit; -} - /** This function found in impl {libcrux_ml_kem::types::MlKemKeyPair#21} @@ -218,14 +161,14 @@ libcrux_ml_kem_types_MlKemKeyPair_3e libcrux_ml_kem_types_from_3a_fa( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPrivateKey)#9} +libcrux_ml_kem::types::MlKemPrivateKey)#12} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_7f +A monomorphic instance of libcrux_ml_kem.types.from_9a with const generics - SIZE= 1632 */ -libcrux_ml_kem_types_MlKemPrivateKey_fa libcrux_ml_kem_types_from_7f_2a( +libcrux_ml_kem_types_MlKemPrivateKey_fa libcrux_ml_kem_types_from_9a_2a( uint8_t value[1632U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[1632U]; @@ -250,14 +193,60 @@ uint8_t *libcrux_ml_kem_types_as_slice_fd_d0( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemCiphertext)#2} +libcrux_ml_kem::types::MlKemPublicKey)#19} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_5f +with const generics +- SIZE= 1184 */ +libcrux_ml_kem_types_MlKemPublicKey_30 libcrux_ml_kem_types_from_5f_d0( + uint8_t value[1184U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_value[1184U]; + memcpy(copy_of_value, value, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey_30 lit; + memcpy(lit.value, copy_of_value, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + /** -A monomorphic instance of libcrux_ml_kem.types.from_01 +A monomorphic instance of libcrux_ml_kem.types.unpack_private_key +with const generics +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +Eurydice_slice_uint8_t_x4 libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_slice private_key) { + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + private_key, (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + return (CLITERAL(Eurydice_slice_uint8_t_x4){.fst = ind_cpa_secret_key, + .snd = ind_cpa_public_key, + .thd = ind_cpa_public_key_hash, + .f3 = implicit_rejection_value}); +} + +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemCiphertext)#5} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_00 with const generics - SIZE= 1088 */ -libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types_from_01_80( +libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types_from_00_80( uint8_t value[1088U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[1088U]; @@ -267,16 +256,33 @@ libcrux_ml_kem_mlkem768_MlKem768Ciphertext libcrux_ml_kem_types_from_01_80( return lit; } +/** +A monomorphic instance of libcrux_ml_kem.utils.prf_input_inc +with const generics +- K= 3 +*/ +uint8_t libcrux_ml_kem_utils_prf_input_inc_e0(uint8_t (*prf_inputs)[33U], + uint8_t domain_separator) { + uint8_t ret[3U][33U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)3U, prf_inputs, ret, uint8_t[33U], void *); + LowStar_Ignore_ignore(ret, uint8_t[3U][33U], void *); + KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + return domain_separator; +} + /** This function found in impl {(core::convert::AsRef<@Slice> for -libcrux_ml_kem::types::MlKemCiphertext)#1} +libcrux_ml_kem::types::MlKemCiphertext)#4} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +A monomorphic instance of libcrux_ml_kem.types.as_ref_43 with const generics - SIZE= 1088 */ -Eurydice_slice libcrux_ml_kem_types_as_ref_00_80( +Eurydice_slice libcrux_ml_kem_types_as_ref_43_80( libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t); } @@ -315,14 +321,60 @@ uint8_t *libcrux_ml_kem_types_as_slice_fd_4d( /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemCiphertext)#2} +libcrux_ml_kem::types::MlKemPublicKey)#19} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_5f +with const generics +- SIZE= 800 +*/ +libcrux_ml_kem_types_MlKemPublicKey_52 libcrux_ml_kem_types_from_5f_4d( + uint8_t value[800U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_value[800U]; + memcpy(copy_of_value, value, (size_t)800U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey_52 lit; + memcpy(lit.value, copy_of_value, (size_t)800U * sizeof(uint8_t)); + return lit; +} + +/** +A monomorphic instance of libcrux_ml_kem.types.unpack_private_key +with const generics +- CPA_SECRET_KEY_SIZE= 768 +- PUBLIC_KEY_SIZE= 800 +*/ +Eurydice_slice_uint8_t_x4 libcrux_ml_kem_types_unpack_private_key_0c( + Eurydice_slice private_key) { + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + private_key, (size_t)768U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + secret_key0, (size_t)800U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + return (CLITERAL(Eurydice_slice_uint8_t_x4){.fst = ind_cpa_secret_key, + .snd = ind_cpa_public_key, + .thd = ind_cpa_public_key_hash, + .f3 = implicit_rejection_value}); +} + +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemCiphertext)#5} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_01 +A monomorphic instance of libcrux_ml_kem.types.from_00 with const generics - SIZE= 768 */ -libcrux_ml_kem_types_MlKemCiphertext_1a libcrux_ml_kem_types_from_01_d0( +libcrux_ml_kem_types_MlKemCiphertext_1a libcrux_ml_kem_types_from_00_d0( uint8_t value[768U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[768U]; @@ -332,16 +384,33 @@ libcrux_ml_kem_types_MlKemCiphertext_1a libcrux_ml_kem_types_from_01_d0( return lit; } +/** +A monomorphic instance of libcrux_ml_kem.utils.prf_input_inc +with const generics +- K= 2 +*/ +uint8_t libcrux_ml_kem_utils_prf_input_inc_fd(uint8_t (*prf_inputs)[33U], + uint8_t domain_separator) { + uint8_t ret[2U][33U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)2U, prf_inputs, ret, uint8_t[33U], void *); + LowStar_Ignore_ignore(ret, uint8_t[2U][33U], void *); + KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + return domain_separator; +} + /** This function found in impl {(core::convert::AsRef<@Slice> for -libcrux_ml_kem::types::MlKemCiphertext)#1} +libcrux_ml_kem::types::MlKemCiphertext)#4} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +A monomorphic instance of libcrux_ml_kem.types.as_ref_43 with const generics - SIZE= 768 */ -Eurydice_slice libcrux_ml_kem_types_as_ref_00_d0( +Eurydice_slice libcrux_ml_kem_types_as_ref_43_d0( libcrux_ml_kem_types_MlKemCiphertext_1a *self) { return Eurydice_array_to_slice((size_t)768U, self->value, uint8_t); } @@ -378,6 +447,52 @@ uint8_t *libcrux_ml_kem_types_as_slice_fd_af( return self->value; } +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemPublicKey)#19} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_5f +with const generics +- SIZE= 1568 +*/ +libcrux_ml_kem_types_MlKemPublicKey_64 libcrux_ml_kem_types_from_5f_af( + uint8_t value[1568U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_value[1568U]; + memcpy(copy_of_value, value, (size_t)1568U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey_64 lit; + memcpy(lit.value, copy_of_value, (size_t)1568U * sizeof(uint8_t)); + return lit; +} + +/** +A monomorphic instance of libcrux_ml_kem.types.unpack_private_key +with const generics +- CPA_SECRET_KEY_SIZE= 1536 +- PUBLIC_KEY_SIZE= 1568 +*/ +Eurydice_slice_uint8_t_x4 libcrux_ml_kem_types_unpack_private_key_1f( + Eurydice_slice private_key) { + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + private_key, (size_t)1536U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + secret_key0, (size_t)1568U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + return (CLITERAL(Eurydice_slice_uint8_t_x4){.fst = ind_cpa_secret_key, + .snd = ind_cpa_public_key, + .thd = ind_cpa_public_key_hash, + .f3 = implicit_rejection_value}); +} + /** This function found in impl {core::result::Result[TraitClause@0, TraitClause@1]} @@ -420,14 +535,14 @@ void libcrux_ml_kem_utils_into_padded_array_b6(Eurydice_slice slice, /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemCiphertext)#2} +libcrux_ml_kem::types::MlKemCiphertext)#5} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_01 +A monomorphic instance of libcrux_ml_kem.types.from_00 with const generics - SIZE= 1568 */ -libcrux_ml_kem_types_MlKemCiphertext_64 libcrux_ml_kem_types_from_01_af( +libcrux_ml_kem_types_MlKemCiphertext_64 libcrux_ml_kem_types_from_00_af( uint8_t value[1568U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[1568U]; @@ -437,6 +552,23 @@ libcrux_ml_kem_types_MlKemCiphertext_64 libcrux_ml_kem_types_from_01_af( return lit; } +/** +A monomorphic instance of libcrux_ml_kem.utils.prf_input_inc +with const generics +- K= 4 +*/ +uint8_t libcrux_ml_kem_utils_prf_input_inc_ac(uint8_t (*prf_inputs)[33U], + uint8_t domain_separator) { + uint8_t ret[4U][33U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)4U, prf_inputs, ret, uint8_t[33U], void *); + LowStar_Ignore_ignore(ret, uint8_t[4U][33U], void *); + KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U;); + return domain_separator; +} + /** Pad the `slice` with `0`s at the end. */ @@ -458,14 +590,14 @@ void libcrux_ml_kem_utils_into_padded_array_c8(Eurydice_slice slice, /** This function found in impl {(core::convert::AsRef<@Slice> for -libcrux_ml_kem::types::MlKemCiphertext)#1} +libcrux_ml_kem::types::MlKemCiphertext)#4} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +A monomorphic instance of libcrux_ml_kem.types.as_ref_43 with const generics - SIZE= 1568 */ -Eurydice_slice libcrux_ml_kem_types_as_ref_00_af( +Eurydice_slice libcrux_ml_kem_types_as_ref_43_af( libcrux_ml_kem_types_MlKemCiphertext_64 *self) { return Eurydice_array_to_slice((size_t)1568U, self->value, uint8_t); } diff --git a/libcrux-ml-kem/c/libcrux_core.h b/libcrux-ml-kem/c/libcrux_core.h index 003c85595..41bbf32c7 100644 --- a/libcrux-ml-kem/c/libcrux_core.h +++ b/libcrux-ml-kem/c/libcrux_core.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_core_H @@ -54,15 +54,6 @@ static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); -/** -A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey -with const generics -- $1568size_t -*/ -typedef struct libcrux_ml_kem_types_MlKemPublicKey_64_s { - uint8_t value[1568U]; -} libcrux_ml_kem_types_MlKemPublicKey_64; - /** A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey with const generics @@ -72,19 +63,19 @@ typedef struct libcrux_ml_kem_types_MlKemPrivateKey_83_s { uint8_t value[3168U]; } libcrux_ml_kem_types_MlKemPrivateKey_83; -typedef struct libcrux_ml_kem_mlkem1024_MlKem1024KeyPair_s { - libcrux_ml_kem_types_MlKemPrivateKey_83 sk; - libcrux_ml_kem_types_MlKemPublicKey_64 pk; -} libcrux_ml_kem_mlkem1024_MlKem1024KeyPair; - /** A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey with const generics -- $1184size_t +- $1568size_t */ -typedef struct libcrux_ml_kem_types_MlKemPublicKey_30_s { - uint8_t value[1184U]; -} libcrux_ml_kem_types_MlKemPublicKey_30; +typedef struct libcrux_ml_kem_types_MlKemPublicKey_64_s { + uint8_t value[1568U]; +} libcrux_ml_kem_types_MlKemPublicKey_64; + +typedef struct libcrux_ml_kem_mlkem1024_MlKem1024KeyPair_s { + libcrux_ml_kem_types_MlKemPrivateKey_83 sk; + libcrux_ml_kem_types_MlKemPublicKey_64 pk; +} libcrux_ml_kem_mlkem1024_MlKem1024KeyPair; /** A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey @@ -95,19 +86,19 @@ typedef struct libcrux_ml_kem_types_MlKemPrivateKey_d9_s { uint8_t value[2400U]; } libcrux_ml_kem_types_MlKemPrivateKey_d9; -typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s { - libcrux_ml_kem_types_MlKemPrivateKey_d9 sk; - libcrux_ml_kem_types_MlKemPublicKey_30 pk; -} libcrux_ml_kem_mlkem768_MlKem768KeyPair; - /** A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey with const generics -- $800size_t +- $1184size_t */ -typedef struct libcrux_ml_kem_types_MlKemPublicKey_52_s { - uint8_t value[800U]; -} libcrux_ml_kem_types_MlKemPublicKey_52; +typedef struct libcrux_ml_kem_types_MlKemPublicKey_30_s { + uint8_t value[1184U]; +} libcrux_ml_kem_types_MlKemPublicKey_30; + +typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s { + libcrux_ml_kem_types_MlKemPrivateKey_d9 sk; + libcrux_ml_kem_types_MlKemPublicKey_30 pk; +} libcrux_ml_kem_mlkem768_MlKem768KeyPair; /** A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey @@ -118,6 +109,15 @@ typedef struct libcrux_ml_kem_types_MlKemPrivateKey_fa_s { uint8_t value[1632U]; } libcrux_ml_kem_types_MlKemPrivateKey_fa; +/** +A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey +with const generics +- $800size_t +*/ +typedef struct libcrux_ml_kem_types_MlKemPublicKey_52_s { + uint8_t value[800U]; +} libcrux_ml_kem_types_MlKemPublicKey_52; + /** A monomorphic instance of libcrux_ml_kem.types.MlKemKeyPair with const generics @@ -129,6 +129,11 @@ typedef struct libcrux_ml_kem_types_MlKemKeyPair_3e_s { libcrux_ml_kem_types_MlKemPublicKey_52 pk; } libcrux_ml_kem_types_MlKemKeyPair_3e; +typedef struct Eurydice_slice_uint8_t_x2_s { + Eurydice_slice fst; + Eurydice_slice snd; +} Eurydice_slice_uint8_t_x2; + typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s { uint8_t value[1088U]; } libcrux_ml_kem_mlkem768_MlKem768Ciphertext; @@ -207,11 +212,6 @@ with types uint8_t[8size_t], core_array_TryFromSliceError */ void core_result_unwrap_26_68(core_result_Result_15 self, uint8_t ret[8U]); -typedef struct Eurydice_slice_uint8_t_x2_s { - Eurydice_slice fst; - Eurydice_slice snd; -} Eurydice_slice_uint8_t_x2; - typedef struct Eurydice_slice_uint8_t_1size_t__x2_s { Eurydice_slice fst[1U]; Eurydice_slice snd[1U]; diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024.h b/libcrux-ml-kem/c/libcrux_mlkem1024.h index 1119f346c..1458de6ac 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem1024_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c index 1a54ebf6b..363093548 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "libcrux_mlkem1024_avx2.h" @@ -151,9 +151,6 @@ tuple_fa libcrux_ml_kem_mlkem1024_avx2_encapsulate( return encapsulate_8f(uu____0, copy_of_randomness); } -/** - Portable generate key pair. -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.generate_keypair_avx2 with const @@ -244,6 +241,28 @@ bool libcrux_ml_kem_mlkem1024_avx2_validate_private_key( return validate_private_key_6b(private_key, ciphertext); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.avx2.validate_private_key_only with const +generics +- K= 4 +- SECRET_KEY_SIZE= 3168 +*/ +static KRML_MUSTINLINE bool validate_private_key_only_44( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_5e(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem1024_avx2_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key) { + return validate_private_key_only_44(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.validate_public_key_avx2 with const diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h index d5ff384b0..cfc2f915e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem1024_avx2_H @@ -58,6 +58,14 @@ bool libcrux_ml_kem_mlkem1024_avx2_validate_private_key( libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, libcrux_ml_kem_types_MlKemCiphertext_64 *ciphertext); +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem1024_avx2_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key); + /** Validate a public key. diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c index 85d86f144..b4d771a73 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "libcrux_mlkem1024_portable.h" @@ -155,6 +155,28 @@ bool libcrux_ml_kem_mlkem1024_portable_validate_private_key( return validate_private_key_6b(private_key, ciphertext); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key_only with +const generics +- K= 4 +- SECRET_KEY_SIZE= 3168 +*/ +static KRML_MUSTINLINE bool validate_private_key_only_44( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_60(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem1024_portable_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key) { + return validate_private_key_only_44(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.portable.validate_public_key with const diff --git a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h index dc3177ebd..908abf6ae 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem1024_portable.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem1024_portable_H @@ -58,6 +58,14 @@ bool libcrux_ml_kem_mlkem1024_portable_validate_private_key( libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, libcrux_ml_kem_types_MlKemCiphertext_64 *ciphertext); +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem1024_portable_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key); + /** Validate a public key. diff --git a/libcrux-ml-kem/c/libcrux_mlkem512.h b/libcrux-ml-kem/c/libcrux_mlkem512.h index 86a9d0700..a289a8989 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem512_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c index 781ff4da2..3c2fdb66d 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "libcrux_mlkem512_avx2.h" @@ -151,9 +151,6 @@ tuple_41 libcrux_ml_kem_mlkem512_avx2_encapsulate( return encapsulate_35(uu____0, copy_of_randomness); } -/** - Portable generate key pair. -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.generate_keypair_avx2 with const @@ -244,6 +241,28 @@ bool libcrux_ml_kem_mlkem512_avx2_validate_private_key( return validate_private_key_1c(private_key, ciphertext); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.avx2.validate_private_key_only with const +generics +- K= 2 +- SECRET_KEY_SIZE= 1632 +*/ +static KRML_MUSTINLINE bool validate_private_key_only_49( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_4d(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem512_avx2_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key) { + return validate_private_key_only_49(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.validate_public_key_avx2 with const diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h index bb8088679..e364a95e1 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem512_avx2_H @@ -58,6 +58,14 @@ bool libcrux_ml_kem_mlkem512_avx2_validate_private_key( libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key, libcrux_ml_kem_types_MlKemCiphertext_1a *ciphertext); +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem512_avx2_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key); + /** Validate a public key. diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c index e1443ee16..a0d72c45e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "libcrux_mlkem512_portable.h" @@ -155,6 +155,28 @@ bool libcrux_ml_kem_mlkem512_portable_validate_private_key( return validate_private_key_1c(private_key, ciphertext); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key_only with +const generics +- K= 2 +- SECRET_KEY_SIZE= 1632 +*/ +static KRML_MUSTINLINE bool validate_private_key_only_49( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_30(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem512_portable_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key) { + return validate_private_key_only_49(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.portable.validate_public_key with const diff --git a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h index 49e8b1dc2..a49a44922 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem512_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem512_portable.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem512_portable_H @@ -58,6 +58,14 @@ bool libcrux_ml_kem_mlkem512_portable_validate_private_key( libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key, libcrux_ml_kem_types_MlKemCiphertext_1a *ciphertext); +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem512_portable_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key); + /** Validate a public key. diff --git a/libcrux-ml-kem/c/libcrux_mlkem768.h b/libcrux-ml-kem/c/libcrux_mlkem768.h index 64e186c43..3421b1abd 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem768_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c index 6ab9ef817..ce89c4f56 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "libcrux_mlkem768_avx2.h" @@ -151,9 +151,6 @@ tuple_c2 libcrux_ml_kem_mlkem768_avx2_encapsulate( return encapsulate_cd(uu____0, copy_of_randomness); } -/** - Portable generate key pair. -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.generate_keypair_avx2 with const @@ -244,6 +241,28 @@ bool libcrux_ml_kem_mlkem768_avx2_validate_private_key( return validate_private_key_31(private_key, ciphertext); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.avx2.validate_private_key_only with const +generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +*/ +static KRML_MUSTINLINE bool validate_private_key_only_41( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_ae(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem768_avx2_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return validate_private_key_only_41(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.validate_public_key_avx2 with const diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h index 0e0ae18d7..41d4fc949 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem768_avx2_H @@ -58,6 +58,14 @@ bool libcrux_ml_kem_mlkem768_avx2_validate_private_key( libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext); +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem768_avx2_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key); + /** Validate a public key. diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c index 424ec0f54..15e054591 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "libcrux_mlkem768_portable.h" @@ -155,6 +155,28 @@ bool libcrux_ml_kem_mlkem768_portable_validate_private_key( return validate_private_key_31(private_key, ciphertext); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key_only with +const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +*/ +static KRML_MUSTINLINE bool validate_private_key_only_41( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_d6(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem768_portable_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return validate_private_key_only_41(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.portable.validate_public_key with const diff --git a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h index c3eef51ed..06075ff39 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem768_portable.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem768_portable_H @@ -58,6 +58,14 @@ bool libcrux_ml_kem_mlkem768_portable_validate_private_key( libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext); +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +bool libcrux_ml_kem_mlkem768_portable_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key); + /** Validate a public key. diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c index 50828fb37..83b151b39 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "internal/libcrux_mlkem_avx2.h" @@ -1817,16 +1817,14 @@ static KRML_MUSTINLINE void H_a9_e0(Eurydice_slice input, uint8_t ret[32U]) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics - K= 3 - SECRET_KEY_SIZE= 2400 -- CIPHERTEXT_SIZE= 1088 */ -bool libcrux_ml_kem_ind_cca_validate_private_key_12( - libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { +bool libcrux_ml_kem_ind_cca_validate_private_key_only_ae( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { uint8_t t[32U]; H_a9_e0(Eurydice_array_to_subslice2(/* Eurydice can't access values directly on the types. We need to go to the @@ -1843,6 +1841,20 @@ bool libcrux_ml_kem_ind_cca_validate_private_key_12( (size_t)32U, t, &expected, uint8_t, uint8_t, bool); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CIPHERTEXT_SIZE= 1088 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_12( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_ae(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types @@ -2731,11 +2743,8 @@ static KRML_MUSTINLINE uint8_t sample_vector_cbd_then_ntt_b41( KRML_MAYBE_FOR3( i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[3U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)3U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; PRFxN_a9_41(prf_inputs, prf_outputs); KRML_MAYBE_FOR3( @@ -2997,30 +3006,28 @@ static KRML_MUSTINLINE void generate_keypair_unpacked_221( } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_avx2_SIMD256Vector, -libcrux_ml_kem_hash_functions_avx2_Simd256Hash, libcrux_ml_kem_variant_MlKem + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics - K= 3 - PRIVATE_KEY_SIZE= 1152 - PUBLIC_KEY_SIZE= 1184 - RANKED_BYTES_PER_RING_ELEMENT= 1152 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 */ -static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 -generate_keypair_bb1(Eurydice_slice key_generation_seed) { - IndCpaPrivateKeyUnpacked_63 private_key = default_1a_ab(); - IndCpaPublicKeyUnpacked_63 public_key = default_8d_ab(); - generate_keypair_unpacked_221(key_generation_seed, &private_key, &public_key); +static libcrux_ml_kem_utils_extraction_helper_Keypair768 +serialize_unpacked_secret_key_8c(IndCpaPublicKeyUnpacked_63 *public_key, + IndCpaPrivateKeyUnpacked_63 *private_key) { uint8_t public_key_serialized[1184U]; serialize_public_key_ed( - /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key.t_as_ntt, - Eurydice_array_to_slice((size_t)32U, public_key.seed_for_A, uint8_t), + /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key->t_as_ntt, + Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), public_key_serialized); uint8_t secret_key_serialized[1152U]; serialize_secret_key_ed( - /* sk := Encode_12(sˆ mod^{+}q) */ private_key.secret_as_ntt, + /* sk := Encode_12(sˆ mod^{+}q) */ private_key->secret_as_ntt, secret_key_serialized); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[1152U]; @@ -3039,18 +3046,37 @@ generate_keypair_bb1(Eurydice_slice key_generation_seed) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash, libcrux_ml_kem_variant_MlKem +with const generics +- K= 3 +- PRIVATE_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 +generate_keypair_bb1(Eurydice_slice key_generation_seed) { + IndCpaPrivateKeyUnpacked_63 private_key = default_1a_ab(); + IndCpaPublicKeyUnpacked_63 public_key = default_8d_ab(); + generate_keypair_unpacked_221(key_generation_seed, &private_key, &public_key); + return serialize_unpacked_secret_key_8c(&public_key, &private_key); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics - K= 3 - SERIALIZED_KEY_LEN= 2400 */ -static KRML_MUSTINLINE void serialize_kem_secret_key_ae( +static KRML_MUSTINLINE void serialize_kem_secret_key_mut_ae( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( @@ -3059,7 +3085,7 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_ae( uint8_t), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( @@ -3069,13 +3095,14 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_ae( public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - H_a9_e0(public_key, ret0); + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t); + uint8_t ret[32U]; + H_a9_e0(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( @@ -3084,6 +3111,21 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_ae( uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), uint8_t), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 3 +- SERIALIZED_KEY_LEN= 2400 +*/ +static KRML_MUSTINLINE void serialize_kem_secret_key_ae( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + serialize_kem_secret_key_mut_ae(private_key, public_key, + implicit_rejection_value, out); memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } @@ -3125,13 +3167,13 @@ libcrux_ml_kem_ind_cca_generate_keypair_d61(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_d9 private_key = - libcrux_ml_kem_types_from_7f_28(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_28(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_d9 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1184U]; memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_74( - uu____2, libcrux_ml_kem_types_from_5a_d0(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_d0(copy_of_public_key)); } /** @@ -3152,6 +3194,46 @@ static KRML_MUSTINLINE void entropy_preprocess_d8_be(Eurydice_slice randomness, memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE void build_unpacked_public_key_mut_fa1( + Eurydice_slice public_key, + IndCpaPublicKeyUnpacked_63 *unpacked_public_key) { + Eurydice_slice uu____0 = Eurydice_slice_subslice_to( + /* tˆ := Decode_12(pk) */ public_key, (size_t)1152U, uint8_t, size_t); + deserialize_ring_elements_reduced_ab(uu____0, unpacked_public_key->t_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, + (size_t)1152U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____1)[3U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + sample_matrix_A_6c1(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE IndCpaPublicKeyUnpacked_63 +build_unpacked_public_key_fa1(Eurydice_slice public_key) { + IndCpaPublicKeyUnpacked_63 unpacked_public_key = default_8d_ab(); + build_unpacked_public_key_mut_fa1(public_key, &unpacked_public_key); + return unpacked_public_key; +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd with types libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -3172,11 +3254,8 @@ sample_ring_element_cbd_b41(uint8_t prf_input[33U], uint8_t domain_separator) { KRML_MAYBE_FOR3( i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[3U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)3U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; PRFxN_a9_41(prf_inputs, prf_outputs); KRML_MAYBE_FOR3( @@ -4024,10 +4103,11 @@ static KRML_MUSTINLINE void compress_then_serialize_5_61( A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 3 - COMPRESSION_FACTOR= 4 - OUT_LEN= 128 */ -static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_78( +static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_ed( libcrux_ml_kem_polynomial_PolynomialRingElement_f6 re, Eurydice_slice out) { compress_then_serialize_4_61(re, out); } @@ -4108,7 +4188,7 @@ static KRML_MUSTINLINE void encrypt_unpacked_741( uint8_t)); /* c_2 := Encode_{dv}(Compress_q(v,d_v)) */ libcrux_ml_kem_polynomial_PolynomialRingElement_f6 uu____6 = v; - compress_then_serialize_ring_element_v_78( + compress_then_serialize_ring_element_v_ed( uu____6, Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, uint8_t, size_t)); memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); @@ -4135,29 +4215,15 @@ static KRML_MUSTINLINE void encrypt_741(Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, uint8_t ret[1088U]) { - IndCpaPublicKeyUnpacked_63 unpacked_public_key = default_8d_ab(); - deserialize_ring_elements_reduced_ab( - Eurydice_slice_subslice_to(/* tˆ := Decode_12(pk) */ - public_key, (size_t)1152U, uint8_t, size_t), - unpacked_public_key.t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 - do for j from 0 to k − 1 do AˆT[i][j] := - Parse(XOF(ρ, i, j)) end for end for */ - public_key, - (size_t)1152U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____0)[3U] = - unpacked_public_key.A; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_b6(seed, ret0); - sample_matrix_A_6c1(uu____0, ret0, false); - IndCpaPublicKeyUnpacked_63 *uu____1 = &unpacked_public_key; + IndCpaPublicKeyUnpacked_63 unpacked_public_key = + build_unpacked_public_key_fa1(public_key); + IndCpaPublicKeyUnpacked_63 *uu____0 = &unpacked_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_message[32U]; memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - uint8_t ret1[1088U]; - encrypt_unpacked_741(uu____1, copy_of_message, randomness, ret1); - memcpy(ret, ret1, (size_t)1088U * sizeof(uint8_t)); + uint8_t ret0[1088U]; + encrypt_unpacked_741(uu____0, copy_of_message, randomness, ret0); + memcpy(ret, ret0, (size_t)1088U * sizeof(uint8_t)); } /** @@ -4236,7 +4302,7 @@ tuple_c2 libcrux_ml_kem_ind_cca_encapsulate_701( uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = - libcrux_ml_kem_types_from_01_80(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_80(copy_of_ciphertext); uint8_t shared_secret_array[32U]; kdf_d8_ae(shared_secret, shared_secret_array); libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = ciphertext0; @@ -4763,10 +4829,11 @@ deserialize_then_decompress_5_61(Eurydice_slice serialized) { A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 3 - COMPRESSION_FACTOR= 4 */ static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f6 -deserialize_then_decompress_ring_element_v_42(Eurydice_slice serialized) { +deserialize_then_decompress_ring_element_v_ed(Eurydice_slice serialized) { return deserialize_then_decompress_4_61(serialized); } @@ -4865,7 +4932,7 @@ static KRML_MUSTINLINE void decrypt_unpacked_2f( deserialize_then_decompress_u_ed( /* u := Decompress_q(Decode_{d_u}(c), d_u) */ ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement_f6 v = - deserialize_then_decompress_ring_element_v_42( + deserialize_then_decompress_ring_element_v_ed( Eurydice_array_to_subslice_from( (size_t)1088U, /* v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) */ @@ -4957,20 +5024,13 @@ with const generics void libcrux_ml_kem_ind_cca_decapsulate_a11( libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), - (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; decrypt_2f(ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; @@ -4983,28 +5043,28 @@ void libcrux_ml_kem_ind_cca_decapsulate_a11( ind_cpa_public_key_hash, uint8_t); uint8_t hashed[64U]; G_a9_e0(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1120U]; libcrux_ml_kem_utils_into_padded_array_15(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_80(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; PRF_a9_41(Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1088U]; - encrypt_741(uu____5, copy_of_decrypted, pseudorandomness, + encrypt_741(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; kdf_d8_ae(Eurydice_array_to_slice((size_t)32U, @@ -5014,7 +5074,7 @@ void libcrux_ml_kem_ind_cca_decapsulate_a11( kdf_d8_ae(shared_secret0, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_80(ciphertext), + libcrux_ml_kem_types_as_ref_43_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -5180,16 +5240,14 @@ static KRML_MUSTINLINE void H_a9_ac(Eurydice_slice input, uint8_t ret[32U]) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics - K= 4 - SECRET_KEY_SIZE= 3168 -- CIPHERTEXT_SIZE= 1568 */ -bool libcrux_ml_kem_ind_cca_validate_private_key_b9( - libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, - libcrux_ml_kem_types_MlKemCiphertext_64 *_ciphertext) { +bool libcrux_ml_kem_ind_cca_validate_private_key_only_5e( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key) { uint8_t t[32U]; H_a9_ac(Eurydice_array_to_subslice2(/* Eurydice can't access values directly on the types. We need to go to the @@ -5206,6 +5264,20 @@ bool libcrux_ml_kem_ind_cca_validate_private_key_b9( (size_t)32U, t, &expected, uint8_t, uint8_t, bool); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 4 +- SECRET_KEY_SIZE= 3168 +- CIPHERTEXT_SIZE= 1568 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_b9( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, + libcrux_ml_kem_types_MlKemCiphertext_64 *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_5e(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types @@ -5793,11 +5865,8 @@ static KRML_MUSTINLINE uint8_t sample_vector_cbd_then_ntt_b4( KRML_MAYBE_FOR4( i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[4U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)4U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_ac(prf_inputs, domain_separator); uint8_t prf_outputs[4U][128U]; PRFxN_a9_44(prf_inputs, prf_outputs); KRML_MAYBE_FOR4( @@ -5979,30 +6048,28 @@ static KRML_MUSTINLINE void generate_keypair_unpacked_22( } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_avx2_SIMD256Vector, -libcrux_ml_kem_hash_functions_avx2_Simd256Hash, libcrux_ml_kem_variant_MlKem + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics - K= 4 - PRIVATE_KEY_SIZE= 1536 - PUBLIC_KEY_SIZE= 1568 - RANKED_BYTES_PER_RING_ELEMENT= 1536 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 */ -static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair1024 -generate_keypair_bb0(Eurydice_slice key_generation_seed) { - IndCpaPrivateKeyUnpacked_39 private_key = default_1a_42(); - IndCpaPublicKeyUnpacked_39 public_key = default_8d_42(); - generate_keypair_unpacked_22(key_generation_seed, &private_key, &public_key); +static libcrux_ml_kem_utils_extraction_helper_Keypair1024 +serialize_unpacked_secret_key_c9(IndCpaPublicKeyUnpacked_39 *public_key, + IndCpaPrivateKeyUnpacked_39 *private_key) { uint8_t public_key_serialized[1568U]; serialize_public_key_1e( - /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key.t_as_ntt, - Eurydice_array_to_slice((size_t)32U, public_key.seed_for_A, uint8_t), + /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key->t_as_ntt, + Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), public_key_serialized); uint8_t secret_key_serialized[1536U]; serialize_secret_key_78( - /* sk := Encode_12(sˆ mod^{+}q) */ private_key.secret_as_ntt, + /* sk := Encode_12(sˆ mod^{+}q) */ private_key->secret_as_ntt, secret_key_serialized); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[1536U]; @@ -6021,18 +6088,37 @@ generate_keypair_bb0(Eurydice_slice key_generation_seed) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash, libcrux_ml_kem_variant_MlKem +with const generics +- K= 4 +- PRIVATE_KEY_SIZE= 1536 +- PUBLIC_KEY_SIZE= 1568 +- RANKED_BYTES_PER_RING_ELEMENT= 1536 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair1024 +generate_keypair_bb0(Eurydice_slice key_generation_seed) { + IndCpaPrivateKeyUnpacked_39 private_key = default_1a_42(); + IndCpaPublicKeyUnpacked_39 public_key = default_8d_42(); + generate_keypair_unpacked_22(key_generation_seed, &private_key, &public_key); + return serialize_unpacked_secret_key_c9(&public_key, &private_key); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics - K= 4 - SERIALIZED_KEY_LEN= 3168 */ -static KRML_MUSTINLINE void serialize_kem_secret_key_5e( +static KRML_MUSTINLINE void serialize_kem_secret_key_mut_5e( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { - uint8_t out[3168U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( @@ -6041,7 +6127,7 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_5e( uint8_t), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( @@ -6051,13 +6137,14 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_5e( public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - H_a9_ac(public_key, ret0); + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t); + uint8_t ret[32U]; + H_a9_ac(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( @@ -6066,6 +6153,21 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_5e( uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), uint8_t), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 4 +- SERIALIZED_KEY_LEN= 3168 +*/ +static KRML_MUSTINLINE void serialize_kem_secret_key_5e( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { + uint8_t out[3168U] = {0U}; + serialize_kem_secret_key_mut_5e(private_key, public_key, + implicit_rejection_value, out); memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); } @@ -6107,13 +6209,13 @@ libcrux_ml_kem_ind_cca_generate_keypair_d60(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_83 private_key = - libcrux_ml_kem_types_from_7f_39(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_39(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_83 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1568U]; memcpy(copy_of_public_key, public_key, (size_t)1568U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_94( - uu____2, libcrux_ml_kem_types_from_5a_af(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_af(copy_of_public_key)); } /** @@ -6134,6 +6236,46 @@ static KRML_MUSTINLINE void entropy_preprocess_d8_6a(Eurydice_slice randomness, memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics +- K= 4 +- T_AS_NTT_ENCODED_SIZE= 1536 +*/ +static KRML_MUSTINLINE void build_unpacked_public_key_mut_fa0( + Eurydice_slice public_key, + IndCpaPublicKeyUnpacked_39 *unpacked_public_key) { + Eurydice_slice uu____0 = Eurydice_slice_subslice_to( + /* tˆ := Decode_12(pk) */ public_key, (size_t)1536U, uint8_t, size_t); + deserialize_ring_elements_reduced_42(uu____0, unpacked_public_key->t_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, + (size_t)1536U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____1)[4U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + sample_matrix_A_6c(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics +- K= 4 +- T_AS_NTT_ENCODED_SIZE= 1536 +*/ +static KRML_MUSTINLINE IndCpaPublicKeyUnpacked_39 +build_unpacked_public_key_fa0(Eurydice_slice public_key) { + IndCpaPublicKeyUnpacked_39 unpacked_public_key = default_8d_42(); + build_unpacked_public_key_mut_fa0(public_key, &unpacked_public_key); + return unpacked_public_key; +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd with types libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -6154,11 +6296,8 @@ sample_ring_element_cbd_b4(uint8_t prf_input[33U], uint8_t domain_separator) { KRML_MAYBE_FOR4( i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[4U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)4U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_ac(prf_inputs, domain_separator); uint8_t prf_outputs[4U][128U]; PRFxN_a9_44(prf_inputs, prf_outputs); KRML_MAYBE_FOR4( @@ -6363,10 +6502,11 @@ static KRML_MUSTINLINE void compress_then_serialize_u_c9( A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 4 - COMPRESSION_FACTOR= 5 - OUT_LEN= 160 */ -static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_ff( +static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_1e( libcrux_ml_kem_polynomial_PolynomialRingElement_f6 re, Eurydice_slice out) { compress_then_serialize_5_61(re, out); } @@ -6447,7 +6587,7 @@ static KRML_MUSTINLINE void encrypt_unpacked_74( (size_t)1408U, uint8_t)); /* c_2 := Encode_{dv}(Compress_q(v,d_v)) */ libcrux_ml_kem_polynomial_PolynomialRingElement_f6 uu____6 = v; - compress_then_serialize_ring_element_v_ff( + compress_then_serialize_ring_element_v_1e( uu____6, Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, uint8_t, size_t)); memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); @@ -6474,29 +6614,15 @@ static KRML_MUSTINLINE void encrypt_740(Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, uint8_t ret[1568U]) { - IndCpaPublicKeyUnpacked_39 unpacked_public_key = default_8d_42(); - deserialize_ring_elements_reduced_42( - Eurydice_slice_subslice_to(/* tˆ := Decode_12(pk) */ - public_key, (size_t)1536U, uint8_t, size_t), - unpacked_public_key.t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 - do for j from 0 to k − 1 do AˆT[i][j] := - Parse(XOF(ρ, i, j)) end for end for */ - public_key, - (size_t)1536U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____0)[4U] = - unpacked_public_key.A; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_b6(seed, ret0); - sample_matrix_A_6c(uu____0, ret0, false); - IndCpaPublicKeyUnpacked_39 *uu____1 = &unpacked_public_key; + IndCpaPublicKeyUnpacked_39 unpacked_public_key = + build_unpacked_public_key_fa0(public_key); + IndCpaPublicKeyUnpacked_39 *uu____0 = &unpacked_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_message[32U]; memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - uint8_t ret1[1568U]; - encrypt_unpacked_74(uu____1, copy_of_message, randomness, ret1); - memcpy(ret, ret1, (size_t)1568U * sizeof(uint8_t)); + uint8_t ret0[1568U]; + encrypt_unpacked_74(uu____0, copy_of_message, randomness, ret0); + memcpy(ret, ret0, (size_t)1568U * sizeof(uint8_t)); } /** @@ -6575,7 +6701,7 @@ tuple_fa libcrux_ml_kem_ind_cca_encapsulate_700( uint8_t copy_of_ciphertext[1568U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1568U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemCiphertext_64 ciphertext0 = - libcrux_ml_kem_types_from_01_af(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_af(copy_of_ciphertext); uint8_t shared_secret_array[32U]; kdf_d8_5e(shared_secret, shared_secret_array); libcrux_ml_kem_types_MlKemCiphertext_64 uu____5 = ciphertext0; @@ -6693,10 +6819,11 @@ static KRML_MUSTINLINE void deserialize_then_decompress_u_1e( A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 4 - COMPRESSION_FACTOR= 5 */ static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f6 -deserialize_then_decompress_ring_element_v_b4(Eurydice_slice serialized) { +deserialize_then_decompress_ring_element_v_78(Eurydice_slice serialized) { return deserialize_then_decompress_5_61(serialized); } @@ -6738,7 +6865,7 @@ static KRML_MUSTINLINE void decrypt_unpacked_37( deserialize_then_decompress_u_1e( /* u := Decompress_q(Decode_{d_u}(c), d_u) */ ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement_f6 v = - deserialize_then_decompress_ring_element_v_b4( + deserialize_then_decompress_ring_element_v_78( Eurydice_array_to_subslice_from( (size_t)1568U, /* v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) */ @@ -6818,20 +6945,13 @@ with const generics void libcrux_ml_kem_ind_cca_decapsulate_a10( libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, libcrux_ml_kem_types_MlKemCiphertext_64 *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t), - (size_t)1536U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_1f( + Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1568U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; decrypt_37(ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; @@ -6844,28 +6964,28 @@ void libcrux_ml_kem_ind_cca_decapsulate_a10( ind_cpa_public_key_hash, uint8_t); uint8_t hashed[64U]; G_a9_ac(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1600U]; libcrux_ml_kem_utils_into_padded_array_7f(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_af(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_af(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; PRF_a9_44(Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1568U]; - encrypt_740(uu____5, copy_of_decrypted, pseudorandomness, + encrypt_740(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; kdf_d8_5e(Eurydice_array_to_slice((size_t)32U, @@ -6875,7 +6995,7 @@ void libcrux_ml_kem_ind_cca_decapsulate_a10( kdf_d8_5e(shared_secret0, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_af(ciphertext), + libcrux_ml_kem_types_as_ref_43_af(ciphertext), Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -7041,16 +7161,14 @@ static KRML_MUSTINLINE void H_a9_fd(Eurydice_slice input, uint8_t ret[32U]) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics - K= 2 - SECRET_KEY_SIZE= 1632 -- CIPHERTEXT_SIZE= 768 */ -bool libcrux_ml_kem_ind_cca_validate_private_key_ad( - libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key, - libcrux_ml_kem_types_MlKemCiphertext_1a *_ciphertext) { +bool libcrux_ml_kem_ind_cca_validate_private_key_only_4d( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key) { uint8_t t[32U]; H_a9_fd(Eurydice_array_to_subslice2(/* Eurydice can't access values directly on the types. We need to go to the @@ -7067,6 +7185,20 @@ bool libcrux_ml_kem_ind_cca_validate_private_key_ad( (size_t)32U, t, &expected, uint8_t, uint8_t, bool); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 2 +- SECRET_KEY_SIZE= 1632 +- CIPHERTEXT_SIZE= 768 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_ad( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key, + libcrux_ml_kem_types_MlKemCiphertext_1a *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_4d(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types @@ -7633,11 +7765,8 @@ static KRML_MUSTINLINE uint8_t sample_vector_cbd_then_ntt_b40( KRML_MAYBE_FOR2( i, (size_t)0U, (size_t)2U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[2U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)2U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_fd(prf_inputs, domain_separator); uint8_t prf_outputs[2U][192U]; PRFxN_a9_49(prf_inputs, prf_outputs); KRML_MAYBE_FOR2( @@ -7819,30 +7948,28 @@ static KRML_MUSTINLINE void generate_keypair_unpacked_220( } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_avx2_SIMD256Vector, -libcrux_ml_kem_hash_functions_avx2_Simd256Hash, libcrux_ml_kem_variant_MlKem + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics - K= 2 - PRIVATE_KEY_SIZE= 768 - PUBLIC_KEY_SIZE= 800 - RANKED_BYTES_PER_RING_ELEMENT= 768 -- ETA1= 3 -- ETA1_RANDOMNESS_SIZE= 192 */ -static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair512 -generate_keypair_bb(Eurydice_slice key_generation_seed) { - IndCpaPrivateKeyUnpacked_94 private_key = default_1a_89(); - IndCpaPublicKeyUnpacked_94 public_key = default_8d_89(); - generate_keypair_unpacked_220(key_generation_seed, &private_key, &public_key); +static libcrux_ml_kem_utils_extraction_helper_Keypair512 +serialize_unpacked_secret_key_2d(IndCpaPublicKeyUnpacked_94 *public_key, + IndCpaPrivateKeyUnpacked_94 *private_key) { uint8_t public_key_serialized[800U]; serialize_public_key_ba( - /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key.t_as_ntt, - Eurydice_array_to_slice((size_t)32U, public_key.seed_for_A, uint8_t), + /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key->t_as_ntt, + Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), public_key_serialized); uint8_t secret_key_serialized[768U]; serialize_secret_key_29( - /* sk := Encode_12(sˆ mod^{+}q) */ private_key.secret_as_ntt, + /* sk := Encode_12(sˆ mod^{+}q) */ private_key->secret_as_ntt, secret_key_serialized); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[768U]; @@ -7861,18 +7988,37 @@ generate_keypair_bb(Eurydice_slice key_generation_seed) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash, libcrux_ml_kem_variant_MlKem +with const generics +- K= 2 +- PRIVATE_KEY_SIZE= 768 +- PUBLIC_KEY_SIZE= 800 +- RANKED_BYTES_PER_RING_ELEMENT= 768 +- ETA1= 3 +- ETA1_RANDOMNESS_SIZE= 192 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair512 +generate_keypair_bb(Eurydice_slice key_generation_seed) { + IndCpaPrivateKeyUnpacked_94 private_key = default_1a_89(); + IndCpaPublicKeyUnpacked_94 public_key = default_8d_89(); + generate_keypair_unpacked_220(key_generation_seed, &private_key, &public_key); + return serialize_unpacked_secret_key_2d(&public_key, &private_key); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics - K= 2 - SERIALIZED_KEY_LEN= 1632 */ -static KRML_MUSTINLINE void serialize_kem_secret_key_4d( +static KRML_MUSTINLINE void serialize_kem_secret_key_mut_4d( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { - uint8_t out[1632U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( @@ -7881,7 +8027,7 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_4d( uint8_t), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( @@ -7891,13 +8037,14 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_4d( public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - H_a9_fd(public_key, ret0); + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t); + uint8_t ret[32U]; + H_a9_fd(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( @@ -7906,6 +8053,21 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_4d( uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), uint8_t), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 2 +- SERIALIZED_KEY_LEN= 1632 +*/ +static KRML_MUSTINLINE void serialize_kem_secret_key_4d( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { + uint8_t out[1632U] = {0U}; + serialize_kem_secret_key_mut_4d(private_key, public_key, + implicit_rejection_value, out); memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); } @@ -7947,13 +8109,13 @@ libcrux_ml_kem_types_MlKemKeyPair_3e libcrux_ml_kem_ind_cca_generate_keypair_d6( memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_fa private_key = - libcrux_ml_kem_types_from_7f_2a(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_2a(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_fa uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[800U]; memcpy(copy_of_public_key, public_key, (size_t)800U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_fa( - uu____2, libcrux_ml_kem_types_from_5a_4d(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_4d(copy_of_public_key)); } /** @@ -7974,6 +8136,46 @@ static KRML_MUSTINLINE void entropy_preprocess_d8_f8(Eurydice_slice randomness, memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics +- K= 2 +- T_AS_NTT_ENCODED_SIZE= 768 +*/ +static KRML_MUSTINLINE void build_unpacked_public_key_mut_fa( + Eurydice_slice public_key, + IndCpaPublicKeyUnpacked_94 *unpacked_public_key) { + Eurydice_slice uu____0 = Eurydice_slice_subslice_to( + /* tˆ := Decode_12(pk) */ public_key, (size_t)768U, uint8_t, size_t); + deserialize_ring_elements_reduced_89(uu____0, unpacked_public_key->t_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, + (size_t)768U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____1)[2U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + sample_matrix_A_6c0(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics +- K= 2 +- T_AS_NTT_ENCODED_SIZE= 768 +*/ +static KRML_MUSTINLINE IndCpaPublicKeyUnpacked_94 +build_unpacked_public_key_fa(Eurydice_slice public_key) { + IndCpaPublicKeyUnpacked_94 unpacked_public_key = default_8d_89(); + build_unpacked_public_key_mut_fa(public_key, &unpacked_public_key); + return unpacked_public_key; +} + /** A monomorphic instance of libcrux_ml_kem.hash_functions.avx2.PRFxN with const generics @@ -8040,11 +8242,8 @@ sample_ring_element_cbd_b40(uint8_t prf_input[33U], uint8_t domain_separator) { KRML_MAYBE_FOR2( i, (size_t)0U, (size_t)2U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[2U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)2U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_fd(prf_inputs, domain_separator); uint8_t prf_outputs[2U][128U]; PRFxN_a9_490(prf_inputs, prf_outputs); KRML_MAYBE_FOR2( @@ -8207,6 +8406,19 @@ static KRML_MUSTINLINE void compress_then_serialize_u_2d( } } +/** +A monomorphic instance of +libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types +libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 2 +- COMPRESSION_FACTOR= 4 +- OUT_LEN= 128 +*/ +static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_ba( + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 re, Eurydice_slice out) { + compress_then_serialize_4_61(re, out); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_unpacked with types libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -8283,7 +8495,7 @@ static KRML_MUSTINLINE void encrypt_unpacked_740( uint8_t)); /* c_2 := Encode_{dv}(Compress_q(v,d_v)) */ libcrux_ml_kem_polynomial_PolynomialRingElement_f6 uu____6 = v; - compress_then_serialize_ring_element_v_78( + compress_then_serialize_ring_element_v_ba( uu____6, Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, uint8_t, size_t)); memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); @@ -8310,29 +8522,15 @@ static KRML_MUSTINLINE void encrypt_74(Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, uint8_t ret[768U]) { - IndCpaPublicKeyUnpacked_94 unpacked_public_key = default_8d_89(); - deserialize_ring_elements_reduced_89( - Eurydice_slice_subslice_to(/* tˆ := Decode_12(pk) */ - public_key, (size_t)768U, uint8_t, size_t), - unpacked_public_key.t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 - do for j from 0 to k − 1 do AˆT[i][j] := - Parse(XOF(ρ, i, j)) end for end for */ - public_key, - (size_t)768U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____0)[2U] = - unpacked_public_key.A; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_b6(seed, ret0); - sample_matrix_A_6c0(uu____0, ret0, false); - IndCpaPublicKeyUnpacked_94 *uu____1 = &unpacked_public_key; + IndCpaPublicKeyUnpacked_94 unpacked_public_key = + build_unpacked_public_key_fa(public_key); + IndCpaPublicKeyUnpacked_94 *uu____0 = &unpacked_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_message[32U]; memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - uint8_t ret1[768U]; - encrypt_unpacked_740(uu____1, copy_of_message, randomness, ret1); - memcpy(ret, ret1, (size_t)768U * sizeof(uint8_t)); + uint8_t ret0[768U]; + encrypt_unpacked_740(uu____0, copy_of_message, randomness, ret0); + memcpy(ret, ret0, (size_t)768U * sizeof(uint8_t)); } /** @@ -8411,7 +8609,7 @@ tuple_41 libcrux_ml_kem_ind_cca_encapsulate_70( uint8_t copy_of_ciphertext[768U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)768U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemCiphertext_1a ciphertext0 = - libcrux_ml_kem_types_from_01_d0(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_d0(copy_of_ciphertext); uint8_t shared_secret_array[32U]; kdf_d8_4d(shared_secret, shared_secret_array); libcrux_ml_kem_types_MlKemCiphertext_1a uu____5 = ciphertext0; @@ -8495,6 +8693,18 @@ static KRML_MUSTINLINE void deserialize_then_decompress_u_ba( (size_t)2U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f6)); } +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types +libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 2 +- COMPRESSION_FACTOR= 4 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f6 +deserialize_then_decompress_ring_element_v_29(Eurydice_slice serialized) { + return deserialize_then_decompress_4_61(serialized); +} + /** A monomorphic instance of libcrux_ml_kem.matrix.compute_message with types libcrux_ml_kem_vector_avx2_SIMD256Vector @@ -8533,7 +8743,7 @@ static KRML_MUSTINLINE void decrypt_unpacked_4b( deserialize_then_decompress_u_ba( /* u := Decompress_q(Decode_{d_u}(c), d_u) */ ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement_f6 v = - deserialize_then_decompress_ring_element_v_42( + deserialize_then_decompress_ring_element_v_29( Eurydice_array_to_subslice_from( (size_t)768U, /* v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) */ @@ -8613,20 +8823,13 @@ with const generics void libcrux_ml_kem_ind_cca_decapsulate_a1( libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key, libcrux_ml_kem_types_MlKemCiphertext_1a *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t), - (size_t)768U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_0c( + Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)800U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; decrypt_4b(ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; @@ -8639,28 +8842,28 @@ void libcrux_ml_kem_ind_cca_decapsulate_a1( ind_cpa_public_key_hash, uint8_t); uint8_t hashed[64U]; G_a9_fd(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[800U]; libcrux_ml_kem_utils_into_padded_array_4d(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_d0(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_d0(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; PRF_a9_49(Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[768U]; - encrypt_74(uu____5, copy_of_decrypted, pseudorandomness, expected_ciphertext); + encrypt_74(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; kdf_d8_4d(Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret0, uint8_t), @@ -8669,7 +8872,7 @@ void libcrux_ml_kem_ind_cca_decapsulate_a1( kdf_d8_4d(shared_secret0, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_d0(ciphertext), + libcrux_ml_kem_types_as_ref_43_d0(ciphertext), Eurydice_array_to_slice((size_t)768U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, diff --git a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h index 287b05703..746140725 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_avx2.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.c b/libcrux-ml-kem/c/libcrux_mlkem_portable.c index 0a607c53e..7aa7f360e 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.c +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "internal/libcrux_mlkem_portable.h" @@ -2675,16 +2675,14 @@ static KRML_MUSTINLINE void H_f1_ac(Eurydice_slice input, uint8_t ret[32U]) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const generics - K= 4 - SECRET_KEY_SIZE= 3168 -- CIPHERTEXT_SIZE= 1568 */ -bool libcrux_ml_kem_ind_cca_validate_private_key_b5( - libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, - libcrux_ml_kem_types_MlKemCiphertext_64 *_ciphertext) { +bool libcrux_ml_kem_ind_cca_validate_private_key_only_60( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key) { uint8_t t[32U]; H_f1_ac(Eurydice_array_to_subslice2(/* Eurydice can't access values directly on the types. We need to go to the @@ -2701,6 +2699,20 @@ bool libcrux_ml_kem_ind_cca_validate_private_key_b5( (size_t)32U, t, &expected, uint8_t, uint8_t, bool); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] +with const generics +- K= 4 +- SECRET_KEY_SIZE= 3168 +- CIPHERTEXT_SIZE= 1568 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_b5( + libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, + libcrux_ml_kem_types_MlKemCiphertext_64 *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_60(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types @@ -3593,11 +3605,8 @@ static KRML_MUSTINLINE uint8_t sample_vector_cbd_then_ntt_3b( KRML_MAYBE_FOR4( i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[4U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)4U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_ac(prf_inputs, domain_separator); uint8_t prf_outputs[4U][128U]; PRFxN_f1_44(prf_inputs, prf_outputs); KRML_MAYBE_FOR4( @@ -3870,30 +3879,28 @@ static KRML_MUSTINLINE void generate_keypair_unpacked_1c( } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]], -libcrux_ml_kem_variant_MlKem with const generics + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics - K= 4 - PRIVATE_KEY_SIZE= 1536 - PUBLIC_KEY_SIZE= 1568 - RANKED_BYTES_PER_RING_ELEMENT= 1536 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 */ -static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair1024 -generate_keypair_151(Eurydice_slice key_generation_seed) { - IndCpaPrivateKeyUnpacked_af private_key = default_1a_d0(); - IndCpaPublicKeyUnpacked_af public_key = default_8d_d0(); - generate_keypair_unpacked_1c(key_generation_seed, &private_key, &public_key); +static libcrux_ml_kem_utils_extraction_helper_Keypair1024 +serialize_unpacked_secret_key_2f(IndCpaPublicKeyUnpacked_af *public_key, + IndCpaPrivateKeyUnpacked_af *private_key) { uint8_t public_key_serialized[1568U]; serialize_public_key_00( - /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key.t_as_ntt, - Eurydice_array_to_slice((size_t)32U, public_key.seed_for_A, uint8_t), + /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key->t_as_ntt, + Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), public_key_serialized); uint8_t secret_key_serialized[1536U]; serialize_secret_key_ff( - /* sk := Encode_12(sˆ mod^{+}q) */ private_key.secret_as_ntt, + /* sk := Encode_12(sˆ mod^{+}q) */ private_key->secret_as_ntt, secret_key_serialized); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[1536U]; @@ -3912,18 +3919,37 @@ generate_keypair_151(Eurydice_slice key_generation_seed) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 4 +- PRIVATE_KEY_SIZE= 1536 +- PUBLIC_KEY_SIZE= 1568 +- RANKED_BYTES_PER_RING_ELEMENT= 1536 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair1024 +generate_keypair_151(Eurydice_slice key_generation_seed) { + IndCpaPrivateKeyUnpacked_af private_key = default_1a_d0(); + IndCpaPublicKeyUnpacked_af public_key = default_8d_d0(); + generate_keypair_unpacked_1c(key_generation_seed, &private_key, &public_key); + return serialize_unpacked_secret_key_2f(&public_key, &private_key); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const generics - K= 4 - SERIALIZED_KEY_LEN= 3168 */ -static KRML_MUSTINLINE void serialize_kem_secret_key_60( +static KRML_MUSTINLINE void serialize_kem_secret_key_mut_60( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { - uint8_t out[3168U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( @@ -3932,7 +3958,7 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_60( uint8_t), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( @@ -3942,13 +3968,14 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_60( public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - H_f1_ac(public_key, ret0); + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t); + uint8_t ret[32U]; + H_f1_ac(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( @@ -3957,6 +3984,21 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_60( uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), uint8_t), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] +with const generics +- K= 4 +- SERIALIZED_KEY_LEN= 3168 +*/ +static KRML_MUSTINLINE void serialize_kem_secret_key_60( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[3168U]) { + uint8_t out[3168U] = {0U}; + serialize_kem_secret_key_mut_60(private_key, public_key, + implicit_rejection_value, out); memcpy(ret, out, (size_t)3168U * sizeof(uint8_t)); } @@ -3998,13 +4040,13 @@ libcrux_ml_kem_ind_cca_generate_keypair_f81(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)3168U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_83 private_key = - libcrux_ml_kem_types_from_7f_39(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_39(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_83 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1568U]; memcpy(copy_of_public_key, public_key, (size_t)1568U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_94( - uu____2, libcrux_ml_kem_types_from_5a_af(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_af(copy_of_public_key)); } /** @@ -4025,6 +4067,48 @@ static KRML_MUSTINLINE void entropy_preprocess_d8_03(Eurydice_slice randomness, memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const +generics +- K= 4 +- T_AS_NTT_ENCODED_SIZE= 1536 +*/ +static KRML_MUSTINLINE void build_unpacked_public_key_mut_3f( + Eurydice_slice public_key, + IndCpaPublicKeyUnpacked_af *unpacked_public_key) { + Eurydice_slice uu____0 = Eurydice_slice_subslice_to( + /* tˆ := Decode_12(pk) */ public_key, (size_t)1536U, uint8_t, size_t); + deserialize_ring_elements_reduced_d0(uu____0, unpacked_public_key->t_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, + (size_t)1536U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[4U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + sample_matrix_A_2b(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$4size_t]] with const +generics +- K= 4 +- T_AS_NTT_ENCODED_SIZE= 1536 +*/ +static KRML_MUSTINLINE IndCpaPublicKeyUnpacked_af +build_unpacked_public_key_3f1(Eurydice_slice public_key) { + IndCpaPublicKeyUnpacked_af unpacked_public_key = default_8d_d0(); + build_unpacked_public_key_mut_3f(public_key, &unpacked_public_key); + return unpacked_public_key; +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, @@ -4046,11 +4130,8 @@ sample_ring_element_cbd_3b(uint8_t prf_input[33U], uint8_t domain_separator) { KRML_MAYBE_FOR4( i, (size_t)0U, (size_t)4U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[4U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)4U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR4(i, (size_t)0U, (size_t)4U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_ac(prf_inputs, domain_separator); uint8_t prf_outputs[4U][128U]; PRFxN_f1_44(prf_inputs, prf_outputs); KRML_MAYBE_FOR4( @@ -4704,10 +4785,11 @@ static KRML_MUSTINLINE void compress_then_serialize_5_8c( A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 4 - COMPRESSION_FACTOR= 5 - OUT_LEN= 160 */ -static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_8e( +static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_00( libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, Eurydice_slice out) { compress_then_serialize_5_8c(re, out); } @@ -4789,7 +4871,7 @@ static KRML_MUSTINLINE void encrypt_unpacked_2a( (size_t)1408U, uint8_t)); /* c_2 := Encode_{dv}(Compress_q(v,d_v)) */ libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____6 = v; - compress_then_serialize_ring_element_v_8e( + compress_then_serialize_ring_element_v_00( uu____6, Eurydice_array_to_subslice_from((size_t)1568U, ciphertext, (size_t)1408U, uint8_t, size_t)); memcpy(ret, ciphertext, (size_t)1568U * sizeof(uint8_t)); @@ -4817,29 +4899,15 @@ static KRML_MUSTINLINE void encrypt_2a1(Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, uint8_t ret[1568U]) { - IndCpaPublicKeyUnpacked_af unpacked_public_key = default_8d_d0(); - deserialize_ring_elements_reduced_d0( - Eurydice_slice_subslice_to(/* tˆ := Decode_12(pk) */ - public_key, (size_t)1536U, uint8_t, size_t), - unpacked_public_key.t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 - do for j from 0 to k − 1 do AˆT[i][j] := - Parse(XOF(ρ, i, j)) end for end for */ - public_key, - (size_t)1536U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____0)[4U] = - unpacked_public_key.A; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_b6(seed, ret0); - sample_matrix_A_2b(uu____0, ret0, false); - IndCpaPublicKeyUnpacked_af *uu____1 = &unpacked_public_key; + IndCpaPublicKeyUnpacked_af unpacked_public_key = + build_unpacked_public_key_3f1(public_key); + IndCpaPublicKeyUnpacked_af *uu____0 = &unpacked_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_message[32U]; memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - uint8_t ret1[1568U]; - encrypt_unpacked_2a(uu____1, copy_of_message, randomness, ret1); - memcpy(ret, ret1, (size_t)1568U * sizeof(uint8_t)); + uint8_t ret0[1568U]; + encrypt_unpacked_2a(uu____0, copy_of_message, randomness, ret0); + memcpy(ret, ret0, (size_t)1568U * sizeof(uint8_t)); } /** @@ -4918,7 +4986,7 @@ tuple_fa libcrux_ml_kem_ind_cca_encapsulate_ca1( uint8_t copy_of_ciphertext[1568U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1568U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemCiphertext_64 ciphertext0 = - libcrux_ml_kem_types_from_01_af(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_af(copy_of_ciphertext); uint8_t shared_secret_array[32U]; kdf_d8_60(shared_secret, shared_secret_array); libcrux_ml_kem_types_MlKemCiphertext_64 uu____5 = ciphertext0; @@ -5017,8 +5085,8 @@ generics */ static libcrux_ml_kem_vector_portable_vector_type_PortableVector decompress_ciphertext_coefficient_0d_ef( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return decompress_ciphertext_coefficient_ef(v); + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return decompress_ciphertext_coefficient_ef(a); } /** @@ -5084,8 +5152,8 @@ generics */ static libcrux_ml_kem_vector_portable_vector_type_PortableVector decompress_ciphertext_coefficient_0d_c4( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return decompress_ciphertext_coefficient_c4(v); + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return decompress_ciphertext_coefficient_c4(a); } /** @@ -5213,8 +5281,8 @@ generics */ static libcrux_ml_kem_vector_portable_vector_type_PortableVector decompress_ciphertext_coefficient_0d_d1( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return decompress_ciphertext_coefficient_d1(v); + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return decompress_ciphertext_coefficient_d1(a); } /** @@ -5273,8 +5341,8 @@ generics */ static libcrux_ml_kem_vector_portable_vector_type_PortableVector decompress_ciphertext_coefficient_0d_f4( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { - return decompress_ciphertext_coefficient_f4(v); + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + return decompress_ciphertext_coefficient_f4(a); } /** @@ -5304,10 +5372,11 @@ deserialize_then_decompress_5_8c(Eurydice_slice serialized) { A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 4 - COMPRESSION_FACTOR= 5 */ static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d -deserialize_then_decompress_ring_element_v_9f(Eurydice_slice serialized) { +deserialize_then_decompress_ring_element_v_ff(Eurydice_slice serialized) { return deserialize_then_decompress_5_8c(serialized); } @@ -5411,7 +5480,7 @@ static KRML_MUSTINLINE void decrypt_unpacked_7d( deserialize_then_decompress_u_00( /* u := Decompress_q(Decode_{d_u}(c), d_u) */ ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = - deserialize_then_decompress_ring_element_v_9f( + deserialize_then_decompress_ring_element_v_ff( Eurydice_array_to_subslice_from( (size_t)1568U, /* v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) */ @@ -5503,20 +5572,13 @@ libcrux_ml_kem_variant_MlKem with const generics void libcrux_ml_kem_ind_cca_decapsulate_621( libcrux_ml_kem_types_MlKemPrivateKey_83 *private_key, libcrux_ml_kem_types_MlKemCiphertext_64 *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t), - (size_t)1536U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_1f( + Eurydice_array_to_slice((size_t)3168U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1568U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; decrypt_7d(ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; @@ -5529,28 +5591,28 @@ void libcrux_ml_kem_ind_cca_decapsulate_621( ind_cpa_public_key_hash, uint8_t); uint8_t hashed[64U]; G_f1_ac(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1600U]; libcrux_ml_kem_utils_into_padded_array_7f(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1600U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_af(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_af(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; PRF_f1_44(Eurydice_array_to_slice((size_t)1600U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1568U]; - encrypt_2a1(uu____5, copy_of_decrypted, pseudorandomness, + encrypt_2a1(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; kdf_d8_60(Eurydice_array_to_slice((size_t)32U, @@ -5560,7 +5622,7 @@ void libcrux_ml_kem_ind_cca_decapsulate_621( kdf_d8_60(shared_secret0, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_af(ciphertext), + libcrux_ml_kem_types_as_ref_43_af(ciphertext), Eurydice_array_to_slice((size_t)1568U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -5726,16 +5788,14 @@ static KRML_MUSTINLINE void H_f1_fd(Eurydice_slice input, uint8_t ret[32U]) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] with const generics - K= 2 - SECRET_KEY_SIZE= 1632 -- CIPHERTEXT_SIZE= 768 */ -bool libcrux_ml_kem_ind_cca_validate_private_key_fb( - libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key, - libcrux_ml_kem_types_MlKemCiphertext_1a *_ciphertext) { +bool libcrux_ml_kem_ind_cca_validate_private_key_only_30( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key) { uint8_t t[32U]; H_f1_fd(Eurydice_array_to_subslice2(/* Eurydice can't access values directly on the types. We need to go to the @@ -5752,6 +5812,20 @@ bool libcrux_ml_kem_ind_cca_validate_private_key_fb( (size_t)32U, t, &expected, uint8_t, uint8_t, bool); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] +with const generics +- K= 2 +- SECRET_KEY_SIZE= 1632 +- CIPHERTEXT_SIZE= 768 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_fb( + libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key, + libcrux_ml_kem_types_MlKemCiphertext_1a *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_30(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types @@ -6305,11 +6379,8 @@ static KRML_MUSTINLINE uint8_t sample_vector_cbd_then_ntt_3b0( KRML_MAYBE_FOR2( i, (size_t)0U, (size_t)2U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[2U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)2U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_fd(prf_inputs, domain_separator); uint8_t prf_outputs[2U][192U]; PRFxN_f1_49(prf_inputs, prf_outputs); KRML_MAYBE_FOR2( @@ -6495,30 +6566,28 @@ static KRML_MUSTINLINE void generate_keypair_unpacked_1c0( } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]], -libcrux_ml_kem_variant_MlKem with const generics + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics - K= 2 - PRIVATE_KEY_SIZE= 768 - PUBLIC_KEY_SIZE= 800 - RANKED_BYTES_PER_RING_ELEMENT= 768 -- ETA1= 3 -- ETA1_RANDOMNESS_SIZE= 192 */ -static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair512 -generate_keypair_150(Eurydice_slice key_generation_seed) { - IndCpaPrivateKeyUnpacked_d4 private_key = default_1a_a0(); - IndCpaPublicKeyUnpacked_d4 public_key = default_8d_a0(); - generate_keypair_unpacked_1c0(key_generation_seed, &private_key, &public_key); +static libcrux_ml_kem_utils_extraction_helper_Keypair512 +serialize_unpacked_secret_key_6d(IndCpaPublicKeyUnpacked_d4 *public_key, + IndCpaPrivateKeyUnpacked_d4 *private_key) { uint8_t public_key_serialized[800U]; serialize_public_key_86( - /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key.t_as_ntt, - Eurydice_array_to_slice((size_t)32U, public_key.seed_for_A, uint8_t), + /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key->t_as_ntt, + Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), public_key_serialized); uint8_t secret_key_serialized[768U]; serialize_secret_key_64( - /* sk := Encode_12(sˆ mod^{+}q) */ private_key.secret_as_ntt, + /* sk := Encode_12(sˆ mod^{+}q) */ private_key->secret_as_ntt, secret_key_serialized); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[768U]; @@ -6537,18 +6606,37 @@ generate_keypair_150(Eurydice_slice key_generation_seed) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 2 +- PRIVATE_KEY_SIZE= 768 +- PUBLIC_KEY_SIZE= 800 +- RANKED_BYTES_PER_RING_ELEMENT= 768 +- ETA1= 3 +- ETA1_RANDOMNESS_SIZE= 192 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair512 +generate_keypair_150(Eurydice_slice key_generation_seed) { + IndCpaPrivateKeyUnpacked_d4 private_key = default_1a_a0(); + IndCpaPublicKeyUnpacked_d4 public_key = default_8d_a0(); + generate_keypair_unpacked_1c0(key_generation_seed, &private_key, &public_key); + return serialize_unpacked_secret_key_6d(&public_key, &private_key); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] with const generics - K= 2 - SERIALIZED_KEY_LEN= 1632 */ -static KRML_MUSTINLINE void serialize_kem_secret_key_30( +static KRML_MUSTINLINE void serialize_kem_secret_key_mut_30( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { - uint8_t out[1632U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( @@ -6557,7 +6645,7 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_30( uint8_t), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( @@ -6567,13 +6655,14 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_30( public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - H_f1_fd(public_key, ret0); + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t); + uint8_t ret[32U]; + H_f1_fd(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( @@ -6582,6 +6671,21 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_30( uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), uint8_t), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] +with const generics +- K= 2 +- SERIALIZED_KEY_LEN= 1632 +*/ +static KRML_MUSTINLINE void serialize_kem_secret_key_30( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[1632U]) { + uint8_t out[1632U] = {0U}; + serialize_kem_secret_key_mut_30(private_key, public_key, + implicit_rejection_value, out); memcpy(ret, out, (size_t)1632U * sizeof(uint8_t)); } @@ -6623,13 +6727,13 @@ libcrux_ml_kem_ind_cca_generate_keypair_f80(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)1632U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_fa private_key = - libcrux_ml_kem_types_from_7f_2a(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_2a(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_fa uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[800U]; memcpy(copy_of_public_key, public_key, (size_t)800U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_fa( - uu____2, libcrux_ml_kem_types_from_5a_4d(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_4d(copy_of_public_key)); } /** @@ -6650,6 +6754,48 @@ static KRML_MUSTINLINE void entropy_preprocess_d8_10(Eurydice_slice randomness, memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] with const +generics +- K= 2 +- T_AS_NTT_ENCODED_SIZE= 768 +*/ +static KRML_MUSTINLINE void build_unpacked_public_key_mut_3f0( + Eurydice_slice public_key, + IndCpaPublicKeyUnpacked_d4 *unpacked_public_key) { + Eurydice_slice uu____0 = Eurydice_slice_subslice_to( + /* tˆ := Decode_12(pk) */ public_key, (size_t)768U, uint8_t, size_t); + deserialize_ring_elements_reduced_a0(uu____0, unpacked_public_key->t_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, + (size_t)768U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[2U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + sample_matrix_A_2b0(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$2size_t]] with const +generics +- K= 2 +- T_AS_NTT_ENCODED_SIZE= 768 +*/ +static KRML_MUSTINLINE IndCpaPublicKeyUnpacked_d4 +build_unpacked_public_key_3f0(Eurydice_slice public_key) { + IndCpaPublicKeyUnpacked_d4 unpacked_public_key = default_8d_a0(); + build_unpacked_public_key_mut_3f0(public_key, &unpacked_public_key); + return unpacked_public_key; +} + /** A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN with const generics @@ -6703,11 +6849,8 @@ sample_ring_element_cbd_3b0(uint8_t prf_input[33U], uint8_t domain_separator) { KRML_MAYBE_FOR2( i, (size_t)0U, (size_t)2U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[2U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)2U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR2(i, (size_t)0U, (size_t)2U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_fd(prf_inputs, domain_separator); uint8_t prf_outputs[2U][128U]; PRFxN_f1_490(prf_inputs, prf_outputs); KRML_MAYBE_FOR2( @@ -6914,10 +7057,11 @@ static KRML_MUSTINLINE void compress_then_serialize_u_6d( A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 2 - COMPRESSION_FACTOR= 4 - OUT_LEN= 128 */ -static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_ff0( +static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_86( libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, Eurydice_slice out) { compress_then_serialize_4_8c(re, out); } @@ -7000,7 +7144,7 @@ static KRML_MUSTINLINE void encrypt_unpacked_2a0( uint8_t)); /* c_2 := Encode_{dv}(Compress_q(v,d_v)) */ libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____6 = v; - compress_then_serialize_ring_element_v_ff0( + compress_then_serialize_ring_element_v_86( uu____6, Eurydice_array_to_subslice_from((size_t)768U, ciphertext, (size_t)640U, uint8_t, size_t)); memcpy(ret, ciphertext, (size_t)768U * sizeof(uint8_t)); @@ -7028,29 +7172,15 @@ static KRML_MUSTINLINE void encrypt_2a0(Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, uint8_t ret[768U]) { - IndCpaPublicKeyUnpacked_d4 unpacked_public_key = default_8d_a0(); - deserialize_ring_elements_reduced_a0( - Eurydice_slice_subslice_to(/* tˆ := Decode_12(pk) */ - public_key, (size_t)768U, uint8_t, size_t), - unpacked_public_key.t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 - do for j from 0 to k − 1 do AˆT[i][j] := - Parse(XOF(ρ, i, j)) end for end for */ - public_key, - (size_t)768U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____0)[2U] = - unpacked_public_key.A; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_b6(seed, ret0); - sample_matrix_A_2b0(uu____0, ret0, false); - IndCpaPublicKeyUnpacked_d4 *uu____1 = &unpacked_public_key; + IndCpaPublicKeyUnpacked_d4 unpacked_public_key = + build_unpacked_public_key_3f0(public_key); + IndCpaPublicKeyUnpacked_d4 *uu____0 = &unpacked_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_message[32U]; memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - uint8_t ret1[768U]; - encrypt_unpacked_2a0(uu____1, copy_of_message, randomness, ret1); - memcpy(ret, ret1, (size_t)768U * sizeof(uint8_t)); + uint8_t ret0[768U]; + encrypt_unpacked_2a0(uu____0, copy_of_message, randomness, ret0); + memcpy(ret, ret0, (size_t)768U * sizeof(uint8_t)); } /** @@ -7129,7 +7259,7 @@ tuple_41 libcrux_ml_kem_ind_cca_encapsulate_ca0( uint8_t copy_of_ciphertext[768U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)768U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemCiphertext_1a ciphertext0 = - libcrux_ml_kem_types_from_01_d0(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_d0(copy_of_ciphertext); uint8_t shared_secret_array[32U]; kdf_d8_30(shared_secret, shared_secret_array); libcrux_ml_kem_types_MlKemCiphertext_1a uu____5 = ciphertext0; @@ -7247,10 +7377,11 @@ static KRML_MUSTINLINE void deserialize_then_decompress_u_86( A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 2 - COMPRESSION_FACTOR= 4 */ static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d -deserialize_then_decompress_ring_element_v_d0(Eurydice_slice serialized) { +deserialize_then_decompress_ring_element_v_64(Eurydice_slice serialized) { return deserialize_then_decompress_4_8c(serialized); } @@ -7292,7 +7423,7 @@ static KRML_MUSTINLINE void decrypt_unpacked_d1( deserialize_then_decompress_u_86( /* u := Decompress_q(Decode_{d_u}(c), d_u) */ ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = - deserialize_then_decompress_ring_element_v_d0( + deserialize_then_decompress_ring_element_v_64( Eurydice_array_to_subslice_from( (size_t)768U, /* v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) */ @@ -7372,20 +7503,13 @@ libcrux_ml_kem_variant_MlKem with const generics void libcrux_ml_kem_ind_cca_decapsulate_620( libcrux_ml_kem_types_MlKemPrivateKey_fa *private_key, libcrux_ml_kem_types_MlKemCiphertext_1a *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t), - (size_t)768U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_0c( + Eurydice_array_to_slice((size_t)1632U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)800U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; decrypt_d1(ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; @@ -7398,28 +7522,28 @@ void libcrux_ml_kem_ind_cca_decapsulate_620( ind_cpa_public_key_hash, uint8_t); uint8_t hashed[64U]; G_f1_fd(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[800U]; libcrux_ml_kem_utils_into_padded_array_4d(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)800U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_d0(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_d0(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; PRF_f1_49(Eurydice_array_to_slice((size_t)800U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[768U]; - encrypt_2a0(uu____5, copy_of_decrypted, pseudorandomness, + encrypt_2a0(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; kdf_d8_30(Eurydice_array_to_slice((size_t)32U, @@ -7429,7 +7553,7 @@ void libcrux_ml_kem_ind_cca_decapsulate_620( kdf_d8_30(shared_secret0, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_d0(ciphertext), + libcrux_ml_kem_types_as_ref_43_d0(ciphertext), Eurydice_array_to_slice((size_t)768U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -7595,16 +7719,14 @@ static KRML_MUSTINLINE void H_f1_e0(Eurydice_slice input, uint8_t ret[32U]) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 - SECRET_KEY_SIZE= 2400 -- CIPHERTEXT_SIZE= 1088 */ -bool libcrux_ml_kem_ind_cca_validate_private_key_37( - libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { +bool libcrux_ml_kem_ind_cca_validate_private_key_only_d6( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { uint8_t t[32U]; H_f1_e0(Eurydice_array_to_subslice2(/* Eurydice can't access values directly on the types. We need to go to the @@ -7621,6 +7743,20 @@ bool libcrux_ml_kem_ind_cca_validate_private_key_37( (size_t)32U, t, &expected, uint8_t, uint8_t, bool); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CIPHERTEXT_SIZE= 1088 +*/ +bool libcrux_ml_kem_ind_cca_validate_private_key_37( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_d6(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types @@ -8169,11 +8305,8 @@ static KRML_MUSTINLINE uint8_t sample_vector_cbd_then_ntt_3b1( KRML_MAYBE_FOR3( i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[3U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)3U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; PRFxN_f1_41(prf_inputs, prf_outputs); KRML_MAYBE_FOR3( @@ -8359,30 +8492,28 @@ static KRML_MUSTINLINE void generate_keypair_unpacked_1c1( } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], -libcrux_ml_kem_variant_MlKem with const generics + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics - K= 3 - PRIVATE_KEY_SIZE= 1152 - PUBLIC_KEY_SIZE= 1184 - RANKED_BYTES_PER_RING_ELEMENT= 1152 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 */ -static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 -generate_keypair_15(Eurydice_slice key_generation_seed) { - IndCpaPrivateKeyUnpacked_a0 private_key = default_1a_1b(); - IndCpaPublicKeyUnpacked_a0 public_key = default_8d_1b(); - generate_keypair_unpacked_1c1(key_generation_seed, &private_key, &public_key); +static libcrux_ml_kem_utils_extraction_helper_Keypair768 +serialize_unpacked_secret_key_43(IndCpaPublicKeyUnpacked_a0 *public_key, + IndCpaPrivateKeyUnpacked_a0 *private_key) { uint8_t public_key_serialized[1184U]; serialize_public_key_6c( - /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key.t_as_ntt, - Eurydice_array_to_slice((size_t)32U, public_key.seed_for_A, uint8_t), + /* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ public_key->t_as_ntt, + Eurydice_array_to_slice((size_t)32U, public_key->seed_for_A, uint8_t), public_key_serialized); uint8_t secret_key_serialized[1152U]; serialize_secret_key_89( - /* sk := Encode_12(sˆ mod^{+}q) */ private_key.secret_as_ntt, + /* sk := Encode_12(sˆ mod^{+}q) */ private_key->secret_as_ntt, secret_key_serialized); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[1152U]; @@ -8401,18 +8532,37 @@ generate_keypair_15(Eurydice_slice key_generation_seed) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 3 +- PRIVATE_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 +generate_keypair_15(Eurydice_slice key_generation_seed) { + IndCpaPrivateKeyUnpacked_a0 private_key = default_1a_1b(); + IndCpaPublicKeyUnpacked_a0 public_key = default_8d_1b(); + generate_keypair_unpacked_1c1(key_generation_seed, &private_key, &public_key); + return serialize_unpacked_secret_key_43(&public_key, &private_key); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 - SERIALIZED_KEY_LEN= 2400 */ -static KRML_MUSTINLINE void serialize_kem_secret_key_d6( +static KRML_MUSTINLINE void serialize_kem_secret_key_mut_d6( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( @@ -8421,7 +8571,7 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_d6( uint8_t), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( @@ -8431,13 +8581,14 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_d6( public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - H_f1_e0(public_key, ret0); + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t); + uint8_t ret[32U]; + H_f1_e0(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( @@ -8446,6 +8597,21 @@ static KRML_MUSTINLINE void serialize_kem_secret_key_d6( uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), uint8_t), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- SERIALIZED_KEY_LEN= 2400 +*/ +static KRML_MUSTINLINE void serialize_kem_secret_key_d6( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + serialize_kem_secret_key_mut_d6(private_key, public_key, + implicit_rejection_value, out); memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } @@ -8487,13 +8653,13 @@ libcrux_ml_kem_ind_cca_generate_keypair_f8(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_d9 private_key = - libcrux_ml_kem_types_from_7f_28(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_28(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_d9 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1184U]; memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_74( - uu____2, libcrux_ml_kem_types_from_5a_d0(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_d0(copy_of_public_key)); } /** @@ -8514,6 +8680,48 @@ static KRML_MUSTINLINE void entropy_preprocess_d8_9c(Eurydice_slice randomness, memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE void build_unpacked_public_key_mut_3f1( + Eurydice_slice public_key, + IndCpaPublicKeyUnpacked_a0 *unpacked_public_key) { + Eurydice_slice uu____0 = Eurydice_slice_subslice_to( + /* tˆ := Decode_12(pk) */ public_key, (size_t)1152U, uint8_t, size_t); + deserialize_ring_elements_reduced_1b(uu____0, unpacked_public_key->t_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, + (size_t)1152U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[3U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + sample_matrix_A_2b1(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE IndCpaPublicKeyUnpacked_a0 +build_unpacked_public_key_3f(Eurydice_slice public_key) { + IndCpaPublicKeyUnpacked_a0 unpacked_public_key = default_8d_1b(); + build_unpacked_public_key_mut_3f1(public_key, &unpacked_public_key); + return unpacked_public_key; +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, @@ -8535,11 +8743,8 @@ sample_ring_element_cbd_3b1(uint8_t prf_input[33U], uint8_t domain_separator) { KRML_MAYBE_FOR3( i, (size_t)0U, (size_t)3U, (size_t)1U, memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t));); - uint8_t _prf_inputs_init[3U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)3U * sizeof(uint8_t[33U])); - KRML_MAYBE_FOR3(i, (size_t)0U, (size_t)3U, (size_t)1U, size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U;); + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; PRFxN_f1_41(prf_inputs, prf_outputs); KRML_MAYBE_FOR3( @@ -8702,6 +8907,19 @@ static KRML_MUSTINLINE void compress_then_serialize_u_43( } } +/** +A monomorphic instance of +libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- COMPRESSION_FACTOR= 4 +- OUT_LEN= 128 +*/ +static KRML_MUSTINLINE void compress_then_serialize_ring_element_v_6c( + libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, Eurydice_slice out) { + compress_then_serialize_4_8c(re, out); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt_unpacked with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, @@ -8780,7 +8998,7 @@ static KRML_MUSTINLINE void encrypt_unpacked_2a1( uint8_t)); /* c_2 := Encode_{dv}(Compress_q(v,d_v)) */ libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____6 = v; - compress_then_serialize_ring_element_v_ff0( + compress_then_serialize_ring_element_v_6c( uu____6, Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, uint8_t, size_t)); memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); @@ -8808,29 +9026,15 @@ static KRML_MUSTINLINE void encrypt_2a(Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, uint8_t ret[1088U]) { - IndCpaPublicKeyUnpacked_a0 unpacked_public_key = default_8d_1b(); - deserialize_ring_elements_reduced_1b( - Eurydice_slice_subslice_to(/* tˆ := Decode_12(pk) */ - public_key, (size_t)1152U, uint8_t, size_t), - unpacked_public_key.t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 - do for j from 0 to k − 1 do AˆT[i][j] := - Parse(XOF(ρ, i, j)) end for end for */ - public_key, - (size_t)1152U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____0)[3U] = - unpacked_public_key.A; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_b6(seed, ret0); - sample_matrix_A_2b1(uu____0, ret0, false); - IndCpaPublicKeyUnpacked_a0 *uu____1 = &unpacked_public_key; + IndCpaPublicKeyUnpacked_a0 unpacked_public_key = + build_unpacked_public_key_3f(public_key); + IndCpaPublicKeyUnpacked_a0 *uu____0 = &unpacked_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_message[32U]; memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - uint8_t ret1[1088U]; - encrypt_unpacked_2a1(uu____1, copy_of_message, randomness, ret1); - memcpy(ret, ret1, (size_t)1088U * sizeof(uint8_t)); + uint8_t ret0[1088U]; + encrypt_unpacked_2a1(uu____0, copy_of_message, randomness, ret0); + memcpy(ret, ret0, (size_t)1088U * sizeof(uint8_t)); } /** @@ -8909,7 +9113,7 @@ tuple_c2 libcrux_ml_kem_ind_cca_encapsulate_ca( uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = - libcrux_ml_kem_types_from_01_80(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_80(copy_of_ciphertext); uint8_t shared_secret_array[32U]; kdf_d8_d6(shared_secret, shared_secret_array); libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = ciphertext0; @@ -8993,6 +9197,18 @@ static KRML_MUSTINLINE void deserialize_then_decompress_u_6c( (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); } +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- COMPRESSION_FACTOR= 4 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d +deserialize_then_decompress_ring_element_v_89(Eurydice_slice serialized) { + return deserialize_then_decompress_4_8c(serialized); +} + /** A monomorphic instance of libcrux_ml_kem.matrix.compute_message with types libcrux_ml_kem_vector_portable_vector_type_PortableVector @@ -9031,7 +9247,7 @@ static KRML_MUSTINLINE void decrypt_unpacked_42( deserialize_then_decompress_u_6c( /* u := Decompress_q(Decode_{d_u}(c), d_u) */ ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = - deserialize_then_decompress_ring_element_v_d0( + deserialize_then_decompress_ring_element_v_89( Eurydice_array_to_subslice_from( (size_t)1088U, /* v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) */ @@ -9111,20 +9327,13 @@ libcrux_ml_kem_variant_MlKem with const generics void libcrux_ml_kem_ind_cca_decapsulate_62( libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), - (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; decrypt_42(ind_cpa_secret_key, ciphertext->value, decrypted); uint8_t to_hash0[64U]; @@ -9137,28 +9346,28 @@ void libcrux_ml_kem_ind_cca_decapsulate_62( ind_cpa_public_key_hash, uint8_t); uint8_t hashed[64U]; G_f1_e0(Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1120U]; libcrux_ml_kem_utils_into_padded_array_15(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_80(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; PRF_f1_41(Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1088U]; - encrypt_2a(uu____5, copy_of_decrypted, pseudorandomness, expected_ciphertext); + encrypt_2a(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; kdf_d8_d6(Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret0, uint8_t), @@ -9167,7 +9376,7 @@ void libcrux_ml_kem_ind_cca_decapsulate_62( kdf_d8_d6(shared_secret0, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_80(ciphertext), + libcrux_ml_kem_types_as_ref_43_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, diff --git a/libcrux-ml-kem/c/libcrux_mlkem_portable.h b/libcrux-ml-kem/c/libcrux_mlkem_portable.h index f8b67001d..f01803502 100644 --- a/libcrux-ml-kem/c/libcrux_mlkem_portable.h +++ b/libcrux-ml-kem/c/libcrux_mlkem_portable.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_mlkem_portable_H diff --git a/libcrux-ml-kem/c/libcrux_sha3.h b/libcrux-ml-kem/c/libcrux_sha3.h index bdbeb3672..bd2ae688c 100644 --- a/libcrux-ml-kem/c/libcrux_sha3.h +++ b/libcrux-ml-kem/c/libcrux_sha3.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_sha3_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.c b/libcrux-ml-kem/c/libcrux_sha3_avx2.c index 2713cac33..6b48d2f44 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.c +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "internal/libcrux_sha3_avx2.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_avx2.h b/libcrux-ml-kem/c/libcrux_sha3_avx2.h index dff6d2cc7..3585d26e5 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/c/libcrux_sha3_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_internal.h b/libcrux-ml-kem/c/libcrux_sha3_internal.h index 9fba3cfe9..b7cb02704 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_internal.h +++ b/libcrux-ml-kem/c/libcrux_sha3_internal.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_sha3_internal_H diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.c b/libcrux-ml-kem/c/libcrux_sha3_neon.c index 290cb64db..4340d727d 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.c +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.c @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #include "libcrux_sha3_neon.h" diff --git a/libcrux-ml-kem/c/libcrux_sha3_neon.h b/libcrux-ml-kem/c/libcrux_sha3_neon.h index cd8ec70fa..280eb16d3 100644 --- a/libcrux-ml-kem/c/libcrux_sha3_neon.h +++ b/libcrux-ml-kem/c/libcrux_sha3_neon.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 18a089ceff3ef1a9f6876cd99a9f4f42c0fe05d9 + * Libcrux: 2ecc08ac92e56197cd05d04f3e873d8da088ad11 */ #ifndef __libcrux_sha3_neon_H diff --git a/libcrux-ml-kem/cg.yaml b/libcrux-ml-kem/cg.yaml index 7f81659c7..e2aecda52 100644 --- a/libcrux-ml-kem/cg.yaml +++ b/libcrux-ml-kem/cg.yaml @@ -23,8 +23,6 @@ files: - [libcrux_sha3, simd, avx2, "*"] monomorphizations_exact: - [libcrux_sha3, generic_keccak, KeccakState_55] - - [libcrux_sha3, generic_keccak, absorb_final_fb ] - - [libcrux_sha3, generic_keccak, squeeze_first_three_blocks_97 ] monomorphizations_of: - [libcrux_sha3, avx2, "*"] - [libcrux_sha3, simd, avx2, "*"] @@ -47,34 +45,6 @@ files: monomorphizations_using: - [libcrux_sha3, "*"] - # Header with types only - - - name: libcrux_mlkem768_avx2_types - inline_static: true - api: - monomorphizations_exact: - - [ libcrux_ml_kem, mlkem768, avx2, unpacked, MlKem768KeyPairUnpacked ] - - [ libcrux_ml_kem, mlkem768, avx2, unpacked, MlKem768PublicKeyUnpacked ] - - [ libcrux_ml_kem, ind_cca, unpacked, MlKemPrivateKeyUnpacked_63 ] - - [ libcrux_ml_kem, ind_cca, unpacked, MlKemPublicKeyUnpacked_63 ] - - [ libcrux_ml_kem, ind_cpa, unpacked, IndCpaPrivateKeyUnpacked_63 ] - - [ libcrux_ml_kem, ind_cpa, unpacked, IndCpaPublicKeyUnpacked_63 ] - - [ libcrux_ml_kem, polynomial, PolynomialRingElement_f6 ] - - [ libcrux_ml_kem, vector, avx2, SIMD256Vector ] - - - name: libcrux_mlkem768_portable_types - inline_static: true - api: - monomorphizations_exact: - - [ libcrux_ml_kem, mlkem768, portable, unpacked, MlKem768KeyPairUnpacked ] - - [ libcrux_ml_kem, mlkem768, portable, unpacked, MlKem768PublicKeyUnpacked ] - - [ libcrux_ml_kem, ind_cca, unpacked, MlKemPrivateKeyUnpacked_a0 ] - - [ libcrux_ml_kem, ind_cca, unpacked, MlKemPublicKeyUnpacked_a0 ] - - [ libcrux_ml_kem, ind_cpa, unpacked, IndCpaPrivateKeyUnpacked_a0 ] - - [ libcrux_ml_kem, ind_cpa, unpacked, IndCpaPublicKeyUnpacked_a0 ] - - [ libcrux_ml_kem, polynomial, PolynomialRingElement_1d ] - - [ libcrux_ml_kem, vector, portable, vector_type, PortableVector ] - # MLKEM: MISC NON-ARCHITECTURE SPECIFIC HEADERS - name: libcrux_core inline_static: true diff --git a/libcrux-ml-kem/cg/benches/mlkem768.cc b/libcrux-ml-kem/cg/benches/mlkem768.cc index 7ce70a7e1..02c0cbbb1 100644 --- a/libcrux-ml-kem/cg/benches/mlkem768.cc +++ b/libcrux-ml-kem/cg/benches/mlkem768.cc @@ -35,11 +35,11 @@ kyber768_key_generation_unpacked(benchmark::State &state) uint8_t randomness[64]; generate_random(randomness, 64); libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_portable_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair(randomness, &key_pair); + libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut(randomness, &key_pair); for (auto _ : state) { - libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair(randomness, &key_pair); + libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut(randomness, &key_pair); } } @@ -66,7 +66,7 @@ kyber768_encapsulation_unpacked(benchmark::State &state) generate_random(randomness, 64); libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_portable_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair(randomness, &key_pair); + libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut(randomness, &key_pair); generate_random(randomness, 32); auto ctxt = libcrux_ml_kem_mlkem768_portable_unpacked_encapsulate(&key_pair.public_key, randomness); @@ -102,7 +102,7 @@ kyber768_decapsulation_unpacked(benchmark::State &state) generate_random(randomness, 64); libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_portable_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair(randomness, &key_pair); + libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut(randomness, &key_pair); generate_random(randomness, 32); auto ctxt = libcrux_ml_kem_mlkem768_portable_unpacked_encapsulate(&key_pair.public_key, randomness); @@ -201,12 +201,12 @@ kyber768_key_generation_avx2_unpacked(benchmark::State &state) generate_random(randomness, 64); libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_avx2_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair(randomness, &key_pair); + libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair_mut(randomness, &key_pair); for (auto _ : state) { libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_avx2_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair(randomness, &key_pair); + libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair_mut(randomness, &key_pair); } } @@ -233,7 +233,7 @@ kyber768_encapsulation_avx2_unpacked(benchmark::State &state) generate_random(randomness, 64); libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_avx2_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair(randomness, &key_pair); + libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair_mut(randomness, &key_pair); generate_random(randomness, 32); auto ctxt = libcrux_ml_kem_mlkem768_avx2_unpacked_encapsulate(&key_pair.public_key, randomness); @@ -269,7 +269,7 @@ kyber768_decapsulation_avx2_unpacked(benchmark::State &state) generate_random(randomness, 64); libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_avx2_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair(randomness, &key_pair); + libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair_mut(randomness, &key_pair); generate_random(randomness, 32); auto ctxt = libcrux_ml_kem_mlkem768_avx2_unpacked_encapsulate(&key_pair.public_key, randomness); diff --git a/libcrux-ml-kem/cg/code_gen.txt b/libcrux-ml-kem/cg/code_gen.txt index 13b6368d7..e06b07d6e 100644 --- a/libcrux-ml-kem/cg/code_gen.txt +++ b/libcrux-ml-kem/cg/code_gen.txt @@ -3,4 +3,4 @@ Charon: 3a133fe0eee9bd3928d5bb16c24ddd2dd0f3ee7f Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc -Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d +Libcrux: 8fa4c2d98c5fd5a203b5a37a971a46f2296646d9 diff --git a/libcrux-ml-kem/cg/karamel/endianness.h b/libcrux-ml-kem/cg/karamel/endianness.h new file mode 100644 index 000000000..d59d9854d --- /dev/null +++ b/libcrux-ml-kem/cg/karamel/endianness.h @@ -0,0 +1,228 @@ +/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + Licensed under the Apache 2.0 and MIT Licenses. */ + +#ifndef __LOWSTAR_ENDIANNESS_H +#define __LOWSTAR_ENDIANNESS_H + +#include +#include + +/******************************************************************************/ +/* Implementing C.fst (part 2: endian-ness macros) */ +/******************************************************************************/ + +/* ... for Linux */ +#if defined(__linux__) || defined(__CYGWIN__) || \ + defined(__USE_SYSTEM_ENDIAN_H__) || defined(__GLIBC__) +#include + +/* ... for OSX */ +#elif defined(__APPLE__) +#include +#define htole64(x) OSSwapHostToLittleInt64(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) +#define htobe64(x) OSSwapHostToBigInt64(x) +#define be64toh(x) OSSwapBigToHostInt64(x) + +#define htole16(x) OSSwapHostToLittleInt16(x) +#define le16toh(x) OSSwapLittleToHostInt16(x) +#define htobe16(x) OSSwapHostToBigInt16(x) +#define be16toh(x) OSSwapBigToHostInt16(x) + +#define htole32(x) OSSwapHostToLittleInt32(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#define htobe32(x) OSSwapHostToBigInt32(x) +#define be32toh(x) OSSwapBigToHostInt32(x) + +/* ... for Solaris */ +#elif defined(__sun__) +#include +#define htole64(x) LE_64(x) +#define le64toh(x) LE_64(x) +#define htobe64(x) BE_64(x) +#define be64toh(x) BE_64(x) + +#define htole16(x) LE_16(x) +#define le16toh(x) LE_16(x) +#define htobe16(x) BE_16(x) +#define be16toh(x) BE_16(x) + +#define htole32(x) LE_32(x) +#define le32toh(x) LE_32(x) +#define htobe32(x) BE_32(x) +#define be32toh(x) BE_32(x) + +/* ... for the BSDs */ +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#include +#elif defined(__OpenBSD__) +#include + +/* ... for Windows (MSVC)... not targeting XBOX 360! */ +#elif defined(_MSC_VER) + +#include +#define htobe16(x) _byteswap_ushort(x) +#define htole16(x) (x) +#define be16toh(x) _byteswap_ushort(x) +#define le16toh(x) (x) + +#define htobe32(x) _byteswap_ulong(x) +#define htole32(x) (x) +#define be32toh(x) _byteswap_ulong(x) +#define le32toh(x) (x) + +#define htobe64(x) _byteswap_uint64(x) +#define htole64(x) (x) +#define be64toh(x) _byteswap_uint64(x) +#define le64toh(x) (x) + +/* ... for Windows (GCC-like, e.g. mingw or clang) */ +#elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) && \ + (defined(__GNUC__) || defined(__clang__)) + +#define htobe16(x) __builtin_bswap16(x) +#define htole16(x) (x) +#define be16toh(x) __builtin_bswap16(x) +#define le16toh(x) (x) + +#define htobe32(x) __builtin_bswap32(x) +#define htole32(x) (x) +#define be32toh(x) __builtin_bswap32(x) +#define le32toh(x) (x) + +#define htobe64(x) __builtin_bswap64(x) +#define htole64(x) (x) +#define be64toh(x) __builtin_bswap64(x) +#define le64toh(x) (x) + +/* ... generic big-endian fallback code */ +/* ... AIX doesn't have __BYTE_ORDER__ (with XLC compiler) & is always + * big-endian */ +#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ + defined(_AIX) + +/* byte swapping code inspired by: + * https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h + * */ + +#define htobe32(x) (x) +#define be32toh(x) (x) +#define htole32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +#define le32toh(x) (htole32((x))) + +#define htobe64(x) (x) +#define be64toh(x) (x) +#define htole64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +#define le64toh(x) (htole64((x))) + +/* ... generic little-endian fallback code */ +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +#define htole32(x) (x) +#define le32toh(x) (x) +#define htobe32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +#define be32toh(x) (htobe32((x))) + +#define htole64(x) (x) +#define le64toh(x) (x) +#define htobe64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +#define be64toh(x) (htobe64((x))) + +/* ... couldn't determine endian-ness of the target platform */ +#else +#error "Please define __BYTE_ORDER__!" + +#endif /* defined(__linux__) || ... */ + +/* Loads and stores. These avoid undefined behavior due to unaligned memory + * accesses, via memcpy. */ + +inline static uint16_t load16(uint8_t *b) { + uint16_t x; + memcpy(&x, b, 2); + return x; +} + +inline static uint32_t load32(uint8_t *b) { + uint32_t x; + memcpy(&x, b, 4); + return x; +} + +inline static uint64_t load64(uint8_t *b) { + uint64_t x; + memcpy(&x, b, 8); + return x; +} + +inline static void store16(uint8_t *b, uint16_t i) { memcpy(b, &i, 2); } + +inline static void store32(uint8_t *b, uint32_t i) { memcpy(b, &i, 4); } + +inline static void store64(uint8_t *b, uint64_t i) { memcpy(b, &i, 8); } + +/* Legacy accessors so that this header can serve as an implementation of + * C.Endianness */ +#define load16_le(b) (le16toh(load16(b))) +#define store16_le(b, i) (store16(b, htole16(i))) +#define load16_be(b) (be16toh(load16(b))) +#define store16_be(b, i) (store16(b, htobe16(i))) + +#define load32_le(b) (le32toh(load32(b))) +#define store32_le(b, i) (store32(b, htole32(i))) +#define load32_be(b) (be32toh(load32(b))) +#define store32_be(b, i) (store32(b, htobe32(i))) + +#define load64_le(b) (le64toh(load64(b))) +#define store64_le(b, i) (store64(b, htole64(i))) +#define load64_be(b) (be64toh(load64(b))) +#define store64_be(b, i) (store64(b, htobe64(i))) + +/* Co-existence of LowStar.Endianness and FStar.Endianness generates name + * conflicts, because of course both insist on having no prefixes. Until a + * prefix is added, or until we truly retire FStar.Endianness, solve this issue + * in an elegant way. */ +#define load16_le0 load16_le +#define store16_le0 store16_le +#define load16_be0 load16_be +#define store16_be0 store16_be + +#define load32_le0 load32_le +#define store32_le0 store32_le +#define load32_be0 load32_be +#define store32_be0 store32_be + +#define load64_le0 load64_le +#define store64_le0 store64_le +#define load64_be0 load64_be +#define store64_be0 store64_be + +#define load128_le0 load128_le +#define store128_le0 store128_le +#define load128_be0 load128_be +#define store128_be0 store128_be + +#endif diff --git a/libcrux-ml-kem/cg/libcrux_core.h b/libcrux-ml-kem/cg/libcrux_core.h index 30f40f051..eb35fc5d6 100644 --- a/libcrux-ml-kem/cg/libcrux_core.h +++ b/libcrux-ml-kem/cg/libcrux_core.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d + * Libcrux: 8fa4c2d98c5fd5a203b5a37a971a46f2296646d9 */ #ifndef __libcrux_core_H @@ -209,6 +209,2430 @@ static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_9e( memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); } +/** +A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey +with const generics +- $2400size_t +*/ +typedef struct libcrux_ml_kem_types_MlKemPrivateKey_d9_s { + uint8_t value[2400U]; +} libcrux_ml_kem_types_MlKemPrivateKey_d9; + +/** +This function found in impl {(core::default::Default for +libcrux_ml_kem::types::MlKemPrivateKey)#7} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.default_24 +with const generics +- SIZE= 2400 +*/ +static inline libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_types_default_24_28(void) { + libcrux_ml_kem_types_MlKemPrivateKey_d9 lit; + lit.value[0U] = 0U; + lit.value[1U] = 0U; + lit.value[2U] = 0U; + lit.value[3U] = 0U; + lit.value[4U] = 0U; + lit.value[5U] = 0U; + lit.value[6U] = 0U; + lit.value[7U] = 0U; + lit.value[8U] = 0U; + lit.value[9U] = 0U; + lit.value[10U] = 0U; + lit.value[11U] = 0U; + lit.value[12U] = 0U; + lit.value[13U] = 0U; + lit.value[14U] = 0U; + lit.value[15U] = 0U; + lit.value[16U] = 0U; + lit.value[17U] = 0U; + lit.value[18U] = 0U; + lit.value[19U] = 0U; + lit.value[20U] = 0U; + lit.value[21U] = 0U; + lit.value[22U] = 0U; + lit.value[23U] = 0U; + lit.value[24U] = 0U; + lit.value[25U] = 0U; + lit.value[26U] = 0U; + lit.value[27U] = 0U; + lit.value[28U] = 0U; + lit.value[29U] = 0U; + lit.value[30U] = 0U; + lit.value[31U] = 0U; + lit.value[32U] = 0U; + lit.value[33U] = 0U; + lit.value[34U] = 0U; + lit.value[35U] = 0U; + lit.value[36U] = 0U; + lit.value[37U] = 0U; + lit.value[38U] = 0U; + lit.value[39U] = 0U; + lit.value[40U] = 0U; + lit.value[41U] = 0U; + lit.value[42U] = 0U; + lit.value[43U] = 0U; + lit.value[44U] = 0U; + lit.value[45U] = 0U; + lit.value[46U] = 0U; + lit.value[47U] = 0U; + lit.value[48U] = 0U; + lit.value[49U] = 0U; + lit.value[50U] = 0U; + lit.value[51U] = 0U; + lit.value[52U] = 0U; + lit.value[53U] = 0U; + lit.value[54U] = 0U; + lit.value[55U] = 0U; + lit.value[56U] = 0U; + lit.value[57U] = 0U; + lit.value[58U] = 0U; + lit.value[59U] = 0U; + lit.value[60U] = 0U; + lit.value[61U] = 0U; + lit.value[62U] = 0U; + lit.value[63U] = 0U; + lit.value[64U] = 0U; + lit.value[65U] = 0U; + lit.value[66U] = 0U; + lit.value[67U] = 0U; + lit.value[68U] = 0U; + lit.value[69U] = 0U; + lit.value[70U] = 0U; + lit.value[71U] = 0U; + lit.value[72U] = 0U; + lit.value[73U] = 0U; + lit.value[74U] = 0U; + lit.value[75U] = 0U; + lit.value[76U] = 0U; + lit.value[77U] = 0U; + lit.value[78U] = 0U; + lit.value[79U] = 0U; + lit.value[80U] = 0U; + lit.value[81U] = 0U; + lit.value[82U] = 0U; + lit.value[83U] = 0U; + lit.value[84U] = 0U; + lit.value[85U] = 0U; + lit.value[86U] = 0U; + lit.value[87U] = 0U; + lit.value[88U] = 0U; + lit.value[89U] = 0U; + lit.value[90U] = 0U; + lit.value[91U] = 0U; + lit.value[92U] = 0U; + lit.value[93U] = 0U; + lit.value[94U] = 0U; + lit.value[95U] = 0U; + lit.value[96U] = 0U; + lit.value[97U] = 0U; + lit.value[98U] = 0U; + lit.value[99U] = 0U; + lit.value[100U] = 0U; + lit.value[101U] = 0U; + lit.value[102U] = 0U; + lit.value[103U] = 0U; + lit.value[104U] = 0U; + lit.value[105U] = 0U; + lit.value[106U] = 0U; + lit.value[107U] = 0U; + lit.value[108U] = 0U; + lit.value[109U] = 0U; + lit.value[110U] = 0U; + lit.value[111U] = 0U; + lit.value[112U] = 0U; + lit.value[113U] = 0U; + lit.value[114U] = 0U; + lit.value[115U] = 0U; + lit.value[116U] = 0U; + lit.value[117U] = 0U; + lit.value[118U] = 0U; + lit.value[119U] = 0U; + lit.value[120U] = 0U; + lit.value[121U] = 0U; + lit.value[122U] = 0U; + lit.value[123U] = 0U; + lit.value[124U] = 0U; + lit.value[125U] = 0U; + lit.value[126U] = 0U; + lit.value[127U] = 0U; + lit.value[128U] = 0U; + lit.value[129U] = 0U; + lit.value[130U] = 0U; + lit.value[131U] = 0U; + lit.value[132U] = 0U; + lit.value[133U] = 0U; + lit.value[134U] = 0U; + lit.value[135U] = 0U; + lit.value[136U] = 0U; + lit.value[137U] = 0U; + lit.value[138U] = 0U; + lit.value[139U] = 0U; + lit.value[140U] = 0U; + lit.value[141U] = 0U; + lit.value[142U] = 0U; + lit.value[143U] = 0U; + lit.value[144U] = 0U; + lit.value[145U] = 0U; + lit.value[146U] = 0U; + lit.value[147U] = 0U; + lit.value[148U] = 0U; + lit.value[149U] = 0U; + lit.value[150U] = 0U; + lit.value[151U] = 0U; + lit.value[152U] = 0U; + lit.value[153U] = 0U; + lit.value[154U] = 0U; + lit.value[155U] = 0U; + lit.value[156U] = 0U; + lit.value[157U] = 0U; + lit.value[158U] = 0U; + lit.value[159U] = 0U; + lit.value[160U] = 0U; + lit.value[161U] = 0U; + lit.value[162U] = 0U; + lit.value[163U] = 0U; + lit.value[164U] = 0U; + lit.value[165U] = 0U; + lit.value[166U] = 0U; + lit.value[167U] = 0U; + lit.value[168U] = 0U; + lit.value[169U] = 0U; + lit.value[170U] = 0U; + lit.value[171U] = 0U; + lit.value[172U] = 0U; + lit.value[173U] = 0U; + lit.value[174U] = 0U; + lit.value[175U] = 0U; + lit.value[176U] = 0U; + lit.value[177U] = 0U; + lit.value[178U] = 0U; + lit.value[179U] = 0U; + lit.value[180U] = 0U; + lit.value[181U] = 0U; + lit.value[182U] = 0U; + lit.value[183U] = 0U; + lit.value[184U] = 0U; + lit.value[185U] = 0U; + lit.value[186U] = 0U; + lit.value[187U] = 0U; + lit.value[188U] = 0U; + lit.value[189U] = 0U; + lit.value[190U] = 0U; + lit.value[191U] = 0U; + lit.value[192U] = 0U; + lit.value[193U] = 0U; + lit.value[194U] = 0U; + lit.value[195U] = 0U; + lit.value[196U] = 0U; + lit.value[197U] = 0U; + lit.value[198U] = 0U; + lit.value[199U] = 0U; + lit.value[200U] = 0U; + lit.value[201U] = 0U; + lit.value[202U] = 0U; + lit.value[203U] = 0U; + lit.value[204U] = 0U; + lit.value[205U] = 0U; + lit.value[206U] = 0U; + lit.value[207U] = 0U; + lit.value[208U] = 0U; + lit.value[209U] = 0U; + lit.value[210U] = 0U; + lit.value[211U] = 0U; + lit.value[212U] = 0U; + lit.value[213U] = 0U; + lit.value[214U] = 0U; + lit.value[215U] = 0U; + lit.value[216U] = 0U; + lit.value[217U] = 0U; + lit.value[218U] = 0U; + lit.value[219U] = 0U; + lit.value[220U] = 0U; + lit.value[221U] = 0U; + lit.value[222U] = 0U; + lit.value[223U] = 0U; + lit.value[224U] = 0U; + lit.value[225U] = 0U; + lit.value[226U] = 0U; + lit.value[227U] = 0U; + lit.value[228U] = 0U; + lit.value[229U] = 0U; + lit.value[230U] = 0U; + lit.value[231U] = 0U; + lit.value[232U] = 0U; + lit.value[233U] = 0U; + lit.value[234U] = 0U; + lit.value[235U] = 0U; + lit.value[236U] = 0U; + lit.value[237U] = 0U; + lit.value[238U] = 0U; + lit.value[239U] = 0U; + lit.value[240U] = 0U; + lit.value[241U] = 0U; + lit.value[242U] = 0U; + lit.value[243U] = 0U; + lit.value[244U] = 0U; + lit.value[245U] = 0U; + lit.value[246U] = 0U; + lit.value[247U] = 0U; + lit.value[248U] = 0U; + lit.value[249U] = 0U; + lit.value[250U] = 0U; + lit.value[251U] = 0U; + lit.value[252U] = 0U; + lit.value[253U] = 0U; + lit.value[254U] = 0U; + lit.value[255U] = 0U; + lit.value[256U] = 0U; + lit.value[257U] = 0U; + lit.value[258U] = 0U; + lit.value[259U] = 0U; + lit.value[260U] = 0U; + lit.value[261U] = 0U; + lit.value[262U] = 0U; + lit.value[263U] = 0U; + lit.value[264U] = 0U; + lit.value[265U] = 0U; + lit.value[266U] = 0U; + lit.value[267U] = 0U; + lit.value[268U] = 0U; + lit.value[269U] = 0U; + lit.value[270U] = 0U; + lit.value[271U] = 0U; + lit.value[272U] = 0U; + lit.value[273U] = 0U; + lit.value[274U] = 0U; + lit.value[275U] = 0U; + lit.value[276U] = 0U; + lit.value[277U] = 0U; + lit.value[278U] = 0U; + lit.value[279U] = 0U; + lit.value[280U] = 0U; + lit.value[281U] = 0U; + lit.value[282U] = 0U; + lit.value[283U] = 0U; + lit.value[284U] = 0U; + lit.value[285U] = 0U; + lit.value[286U] = 0U; + lit.value[287U] = 0U; + lit.value[288U] = 0U; + lit.value[289U] = 0U; + lit.value[290U] = 0U; + lit.value[291U] = 0U; + lit.value[292U] = 0U; + lit.value[293U] = 0U; + lit.value[294U] = 0U; + lit.value[295U] = 0U; + lit.value[296U] = 0U; + lit.value[297U] = 0U; + lit.value[298U] = 0U; + lit.value[299U] = 0U; + lit.value[300U] = 0U; + lit.value[301U] = 0U; + lit.value[302U] = 0U; + lit.value[303U] = 0U; + lit.value[304U] = 0U; + lit.value[305U] = 0U; + lit.value[306U] = 0U; + lit.value[307U] = 0U; + lit.value[308U] = 0U; + lit.value[309U] = 0U; + lit.value[310U] = 0U; + lit.value[311U] = 0U; + lit.value[312U] = 0U; + lit.value[313U] = 0U; + lit.value[314U] = 0U; + lit.value[315U] = 0U; + lit.value[316U] = 0U; + lit.value[317U] = 0U; + lit.value[318U] = 0U; + lit.value[319U] = 0U; + lit.value[320U] = 0U; + lit.value[321U] = 0U; + lit.value[322U] = 0U; + lit.value[323U] = 0U; + lit.value[324U] = 0U; + lit.value[325U] = 0U; + lit.value[326U] = 0U; + lit.value[327U] = 0U; + lit.value[328U] = 0U; + lit.value[329U] = 0U; + lit.value[330U] = 0U; + lit.value[331U] = 0U; + lit.value[332U] = 0U; + lit.value[333U] = 0U; + lit.value[334U] = 0U; + lit.value[335U] = 0U; + lit.value[336U] = 0U; + lit.value[337U] = 0U; + lit.value[338U] = 0U; + lit.value[339U] = 0U; + lit.value[340U] = 0U; + lit.value[341U] = 0U; + lit.value[342U] = 0U; + lit.value[343U] = 0U; + lit.value[344U] = 0U; + lit.value[345U] = 0U; + lit.value[346U] = 0U; + lit.value[347U] = 0U; + lit.value[348U] = 0U; + lit.value[349U] = 0U; + lit.value[350U] = 0U; + lit.value[351U] = 0U; + lit.value[352U] = 0U; + lit.value[353U] = 0U; + lit.value[354U] = 0U; + lit.value[355U] = 0U; + lit.value[356U] = 0U; + lit.value[357U] = 0U; + lit.value[358U] = 0U; + lit.value[359U] = 0U; + lit.value[360U] = 0U; + lit.value[361U] = 0U; + lit.value[362U] = 0U; + lit.value[363U] = 0U; + lit.value[364U] = 0U; + lit.value[365U] = 0U; + lit.value[366U] = 0U; + lit.value[367U] = 0U; + lit.value[368U] = 0U; + lit.value[369U] = 0U; + lit.value[370U] = 0U; + lit.value[371U] = 0U; + lit.value[372U] = 0U; + lit.value[373U] = 0U; + lit.value[374U] = 0U; + lit.value[375U] = 0U; + lit.value[376U] = 0U; + lit.value[377U] = 0U; + lit.value[378U] = 0U; + lit.value[379U] = 0U; + lit.value[380U] = 0U; + lit.value[381U] = 0U; + lit.value[382U] = 0U; + lit.value[383U] = 0U; + lit.value[384U] = 0U; + lit.value[385U] = 0U; + lit.value[386U] = 0U; + lit.value[387U] = 0U; + lit.value[388U] = 0U; + lit.value[389U] = 0U; + lit.value[390U] = 0U; + lit.value[391U] = 0U; + lit.value[392U] = 0U; + lit.value[393U] = 0U; + lit.value[394U] = 0U; + lit.value[395U] = 0U; + lit.value[396U] = 0U; + lit.value[397U] = 0U; + lit.value[398U] = 0U; + lit.value[399U] = 0U; + lit.value[400U] = 0U; + lit.value[401U] = 0U; + lit.value[402U] = 0U; + lit.value[403U] = 0U; + lit.value[404U] = 0U; + lit.value[405U] = 0U; + lit.value[406U] = 0U; + lit.value[407U] = 0U; + lit.value[408U] = 0U; + lit.value[409U] = 0U; + lit.value[410U] = 0U; + lit.value[411U] = 0U; + lit.value[412U] = 0U; + lit.value[413U] = 0U; + lit.value[414U] = 0U; + lit.value[415U] = 0U; + lit.value[416U] = 0U; + lit.value[417U] = 0U; + lit.value[418U] = 0U; + lit.value[419U] = 0U; + lit.value[420U] = 0U; + lit.value[421U] = 0U; + lit.value[422U] = 0U; + lit.value[423U] = 0U; + lit.value[424U] = 0U; + lit.value[425U] = 0U; + lit.value[426U] = 0U; + lit.value[427U] = 0U; + lit.value[428U] = 0U; + lit.value[429U] = 0U; + lit.value[430U] = 0U; + lit.value[431U] = 0U; + lit.value[432U] = 0U; + lit.value[433U] = 0U; + lit.value[434U] = 0U; + lit.value[435U] = 0U; + lit.value[436U] = 0U; + lit.value[437U] = 0U; + lit.value[438U] = 0U; + lit.value[439U] = 0U; + lit.value[440U] = 0U; + lit.value[441U] = 0U; + lit.value[442U] = 0U; + lit.value[443U] = 0U; + lit.value[444U] = 0U; + lit.value[445U] = 0U; + lit.value[446U] = 0U; + lit.value[447U] = 0U; + lit.value[448U] = 0U; + lit.value[449U] = 0U; + lit.value[450U] = 0U; + lit.value[451U] = 0U; + lit.value[452U] = 0U; + lit.value[453U] = 0U; + lit.value[454U] = 0U; + lit.value[455U] = 0U; + lit.value[456U] = 0U; + lit.value[457U] = 0U; + lit.value[458U] = 0U; + lit.value[459U] = 0U; + lit.value[460U] = 0U; + lit.value[461U] = 0U; + lit.value[462U] = 0U; + lit.value[463U] = 0U; + lit.value[464U] = 0U; + lit.value[465U] = 0U; + lit.value[466U] = 0U; + lit.value[467U] = 0U; + lit.value[468U] = 0U; + lit.value[469U] = 0U; + lit.value[470U] = 0U; + lit.value[471U] = 0U; + lit.value[472U] = 0U; + lit.value[473U] = 0U; + lit.value[474U] = 0U; + lit.value[475U] = 0U; + lit.value[476U] = 0U; + lit.value[477U] = 0U; + lit.value[478U] = 0U; + lit.value[479U] = 0U; + lit.value[480U] = 0U; + lit.value[481U] = 0U; + lit.value[482U] = 0U; + lit.value[483U] = 0U; + lit.value[484U] = 0U; + lit.value[485U] = 0U; + lit.value[486U] = 0U; + lit.value[487U] = 0U; + lit.value[488U] = 0U; + lit.value[489U] = 0U; + lit.value[490U] = 0U; + lit.value[491U] = 0U; + lit.value[492U] = 0U; + lit.value[493U] = 0U; + lit.value[494U] = 0U; + lit.value[495U] = 0U; + lit.value[496U] = 0U; + lit.value[497U] = 0U; + lit.value[498U] = 0U; + lit.value[499U] = 0U; + lit.value[500U] = 0U; + lit.value[501U] = 0U; + lit.value[502U] = 0U; + lit.value[503U] = 0U; + lit.value[504U] = 0U; + lit.value[505U] = 0U; + lit.value[506U] = 0U; + lit.value[507U] = 0U; + lit.value[508U] = 0U; + lit.value[509U] = 0U; + lit.value[510U] = 0U; + lit.value[511U] = 0U; + lit.value[512U] = 0U; + lit.value[513U] = 0U; + lit.value[514U] = 0U; + lit.value[515U] = 0U; + lit.value[516U] = 0U; + lit.value[517U] = 0U; + lit.value[518U] = 0U; + lit.value[519U] = 0U; + lit.value[520U] = 0U; + lit.value[521U] = 0U; + lit.value[522U] = 0U; + lit.value[523U] = 0U; + lit.value[524U] = 0U; + lit.value[525U] = 0U; + lit.value[526U] = 0U; + lit.value[527U] = 0U; + lit.value[528U] = 0U; + lit.value[529U] = 0U; + lit.value[530U] = 0U; + lit.value[531U] = 0U; + lit.value[532U] = 0U; + lit.value[533U] = 0U; + lit.value[534U] = 0U; + lit.value[535U] = 0U; + lit.value[536U] = 0U; + lit.value[537U] = 0U; + lit.value[538U] = 0U; + lit.value[539U] = 0U; + lit.value[540U] = 0U; + lit.value[541U] = 0U; + lit.value[542U] = 0U; + lit.value[543U] = 0U; + lit.value[544U] = 0U; + lit.value[545U] = 0U; + lit.value[546U] = 0U; + lit.value[547U] = 0U; + lit.value[548U] = 0U; + lit.value[549U] = 0U; + lit.value[550U] = 0U; + lit.value[551U] = 0U; + lit.value[552U] = 0U; + lit.value[553U] = 0U; + lit.value[554U] = 0U; + lit.value[555U] = 0U; + lit.value[556U] = 0U; + lit.value[557U] = 0U; + lit.value[558U] = 0U; + lit.value[559U] = 0U; + lit.value[560U] = 0U; + lit.value[561U] = 0U; + lit.value[562U] = 0U; + lit.value[563U] = 0U; + lit.value[564U] = 0U; + lit.value[565U] = 0U; + lit.value[566U] = 0U; + lit.value[567U] = 0U; + lit.value[568U] = 0U; + lit.value[569U] = 0U; + lit.value[570U] = 0U; + lit.value[571U] = 0U; + lit.value[572U] = 0U; + lit.value[573U] = 0U; + lit.value[574U] = 0U; + lit.value[575U] = 0U; + lit.value[576U] = 0U; + lit.value[577U] = 0U; + lit.value[578U] = 0U; + lit.value[579U] = 0U; + lit.value[580U] = 0U; + lit.value[581U] = 0U; + lit.value[582U] = 0U; + lit.value[583U] = 0U; + lit.value[584U] = 0U; + lit.value[585U] = 0U; + lit.value[586U] = 0U; + lit.value[587U] = 0U; + lit.value[588U] = 0U; + lit.value[589U] = 0U; + lit.value[590U] = 0U; + lit.value[591U] = 0U; + lit.value[592U] = 0U; + lit.value[593U] = 0U; + lit.value[594U] = 0U; + lit.value[595U] = 0U; + lit.value[596U] = 0U; + lit.value[597U] = 0U; + lit.value[598U] = 0U; + lit.value[599U] = 0U; + lit.value[600U] = 0U; + lit.value[601U] = 0U; + lit.value[602U] = 0U; + lit.value[603U] = 0U; + lit.value[604U] = 0U; + lit.value[605U] = 0U; + lit.value[606U] = 0U; + lit.value[607U] = 0U; + lit.value[608U] = 0U; + lit.value[609U] = 0U; + lit.value[610U] = 0U; + lit.value[611U] = 0U; + lit.value[612U] = 0U; + lit.value[613U] = 0U; + lit.value[614U] = 0U; + lit.value[615U] = 0U; + lit.value[616U] = 0U; + lit.value[617U] = 0U; + lit.value[618U] = 0U; + lit.value[619U] = 0U; + lit.value[620U] = 0U; + lit.value[621U] = 0U; + lit.value[622U] = 0U; + lit.value[623U] = 0U; + lit.value[624U] = 0U; + lit.value[625U] = 0U; + lit.value[626U] = 0U; + lit.value[627U] = 0U; + lit.value[628U] = 0U; + lit.value[629U] = 0U; + lit.value[630U] = 0U; + lit.value[631U] = 0U; + lit.value[632U] = 0U; + lit.value[633U] = 0U; + lit.value[634U] = 0U; + lit.value[635U] = 0U; + lit.value[636U] = 0U; + lit.value[637U] = 0U; + lit.value[638U] = 0U; + lit.value[639U] = 0U; + lit.value[640U] = 0U; + lit.value[641U] = 0U; + lit.value[642U] = 0U; + lit.value[643U] = 0U; + lit.value[644U] = 0U; + lit.value[645U] = 0U; + lit.value[646U] = 0U; + lit.value[647U] = 0U; + lit.value[648U] = 0U; + lit.value[649U] = 0U; + lit.value[650U] = 0U; + lit.value[651U] = 0U; + lit.value[652U] = 0U; + lit.value[653U] = 0U; + lit.value[654U] = 0U; + lit.value[655U] = 0U; + lit.value[656U] = 0U; + lit.value[657U] = 0U; + lit.value[658U] = 0U; + lit.value[659U] = 0U; + lit.value[660U] = 0U; + lit.value[661U] = 0U; + lit.value[662U] = 0U; + lit.value[663U] = 0U; + lit.value[664U] = 0U; + lit.value[665U] = 0U; + lit.value[666U] = 0U; + lit.value[667U] = 0U; + lit.value[668U] = 0U; + lit.value[669U] = 0U; + lit.value[670U] = 0U; + lit.value[671U] = 0U; + lit.value[672U] = 0U; + lit.value[673U] = 0U; + lit.value[674U] = 0U; + lit.value[675U] = 0U; + lit.value[676U] = 0U; + lit.value[677U] = 0U; + lit.value[678U] = 0U; + lit.value[679U] = 0U; + lit.value[680U] = 0U; + lit.value[681U] = 0U; + lit.value[682U] = 0U; + lit.value[683U] = 0U; + lit.value[684U] = 0U; + lit.value[685U] = 0U; + lit.value[686U] = 0U; + lit.value[687U] = 0U; + lit.value[688U] = 0U; + lit.value[689U] = 0U; + lit.value[690U] = 0U; + lit.value[691U] = 0U; + lit.value[692U] = 0U; + lit.value[693U] = 0U; + lit.value[694U] = 0U; + lit.value[695U] = 0U; + lit.value[696U] = 0U; + lit.value[697U] = 0U; + lit.value[698U] = 0U; + lit.value[699U] = 0U; + lit.value[700U] = 0U; + lit.value[701U] = 0U; + lit.value[702U] = 0U; + lit.value[703U] = 0U; + lit.value[704U] = 0U; + lit.value[705U] = 0U; + lit.value[706U] = 0U; + lit.value[707U] = 0U; + lit.value[708U] = 0U; + lit.value[709U] = 0U; + lit.value[710U] = 0U; + lit.value[711U] = 0U; + lit.value[712U] = 0U; + lit.value[713U] = 0U; + lit.value[714U] = 0U; + lit.value[715U] = 0U; + lit.value[716U] = 0U; + lit.value[717U] = 0U; + lit.value[718U] = 0U; + lit.value[719U] = 0U; + lit.value[720U] = 0U; + lit.value[721U] = 0U; + lit.value[722U] = 0U; + lit.value[723U] = 0U; + lit.value[724U] = 0U; + lit.value[725U] = 0U; + lit.value[726U] = 0U; + lit.value[727U] = 0U; + lit.value[728U] = 0U; + lit.value[729U] = 0U; + lit.value[730U] = 0U; + lit.value[731U] = 0U; + lit.value[732U] = 0U; + lit.value[733U] = 0U; + lit.value[734U] = 0U; + lit.value[735U] = 0U; + lit.value[736U] = 0U; + lit.value[737U] = 0U; + lit.value[738U] = 0U; + lit.value[739U] = 0U; + lit.value[740U] = 0U; + lit.value[741U] = 0U; + lit.value[742U] = 0U; + lit.value[743U] = 0U; + lit.value[744U] = 0U; + lit.value[745U] = 0U; + lit.value[746U] = 0U; + lit.value[747U] = 0U; + lit.value[748U] = 0U; + lit.value[749U] = 0U; + lit.value[750U] = 0U; + lit.value[751U] = 0U; + lit.value[752U] = 0U; + lit.value[753U] = 0U; + lit.value[754U] = 0U; + lit.value[755U] = 0U; + lit.value[756U] = 0U; + lit.value[757U] = 0U; + lit.value[758U] = 0U; + lit.value[759U] = 0U; + lit.value[760U] = 0U; + lit.value[761U] = 0U; + lit.value[762U] = 0U; + lit.value[763U] = 0U; + lit.value[764U] = 0U; + lit.value[765U] = 0U; + lit.value[766U] = 0U; + lit.value[767U] = 0U; + lit.value[768U] = 0U; + lit.value[769U] = 0U; + lit.value[770U] = 0U; + lit.value[771U] = 0U; + lit.value[772U] = 0U; + lit.value[773U] = 0U; + lit.value[774U] = 0U; + lit.value[775U] = 0U; + lit.value[776U] = 0U; + lit.value[777U] = 0U; + lit.value[778U] = 0U; + lit.value[779U] = 0U; + lit.value[780U] = 0U; + lit.value[781U] = 0U; + lit.value[782U] = 0U; + lit.value[783U] = 0U; + lit.value[784U] = 0U; + lit.value[785U] = 0U; + lit.value[786U] = 0U; + lit.value[787U] = 0U; + lit.value[788U] = 0U; + lit.value[789U] = 0U; + lit.value[790U] = 0U; + lit.value[791U] = 0U; + lit.value[792U] = 0U; + lit.value[793U] = 0U; + lit.value[794U] = 0U; + lit.value[795U] = 0U; + lit.value[796U] = 0U; + lit.value[797U] = 0U; + lit.value[798U] = 0U; + lit.value[799U] = 0U; + lit.value[800U] = 0U; + lit.value[801U] = 0U; + lit.value[802U] = 0U; + lit.value[803U] = 0U; + lit.value[804U] = 0U; + lit.value[805U] = 0U; + lit.value[806U] = 0U; + lit.value[807U] = 0U; + lit.value[808U] = 0U; + lit.value[809U] = 0U; + lit.value[810U] = 0U; + lit.value[811U] = 0U; + lit.value[812U] = 0U; + lit.value[813U] = 0U; + lit.value[814U] = 0U; + lit.value[815U] = 0U; + lit.value[816U] = 0U; + lit.value[817U] = 0U; + lit.value[818U] = 0U; + lit.value[819U] = 0U; + lit.value[820U] = 0U; + lit.value[821U] = 0U; + lit.value[822U] = 0U; + lit.value[823U] = 0U; + lit.value[824U] = 0U; + lit.value[825U] = 0U; + lit.value[826U] = 0U; + lit.value[827U] = 0U; + lit.value[828U] = 0U; + lit.value[829U] = 0U; + lit.value[830U] = 0U; + lit.value[831U] = 0U; + lit.value[832U] = 0U; + lit.value[833U] = 0U; + lit.value[834U] = 0U; + lit.value[835U] = 0U; + lit.value[836U] = 0U; + lit.value[837U] = 0U; + lit.value[838U] = 0U; + lit.value[839U] = 0U; + lit.value[840U] = 0U; + lit.value[841U] = 0U; + lit.value[842U] = 0U; + lit.value[843U] = 0U; + lit.value[844U] = 0U; + lit.value[845U] = 0U; + lit.value[846U] = 0U; + lit.value[847U] = 0U; + lit.value[848U] = 0U; + lit.value[849U] = 0U; + lit.value[850U] = 0U; + lit.value[851U] = 0U; + lit.value[852U] = 0U; + lit.value[853U] = 0U; + lit.value[854U] = 0U; + lit.value[855U] = 0U; + lit.value[856U] = 0U; + lit.value[857U] = 0U; + lit.value[858U] = 0U; + lit.value[859U] = 0U; + lit.value[860U] = 0U; + lit.value[861U] = 0U; + lit.value[862U] = 0U; + lit.value[863U] = 0U; + lit.value[864U] = 0U; + lit.value[865U] = 0U; + lit.value[866U] = 0U; + lit.value[867U] = 0U; + lit.value[868U] = 0U; + lit.value[869U] = 0U; + lit.value[870U] = 0U; + lit.value[871U] = 0U; + lit.value[872U] = 0U; + lit.value[873U] = 0U; + lit.value[874U] = 0U; + lit.value[875U] = 0U; + lit.value[876U] = 0U; + lit.value[877U] = 0U; + lit.value[878U] = 0U; + lit.value[879U] = 0U; + lit.value[880U] = 0U; + lit.value[881U] = 0U; + lit.value[882U] = 0U; + lit.value[883U] = 0U; + lit.value[884U] = 0U; + lit.value[885U] = 0U; + lit.value[886U] = 0U; + lit.value[887U] = 0U; + lit.value[888U] = 0U; + lit.value[889U] = 0U; + lit.value[890U] = 0U; + lit.value[891U] = 0U; + lit.value[892U] = 0U; + lit.value[893U] = 0U; + lit.value[894U] = 0U; + lit.value[895U] = 0U; + lit.value[896U] = 0U; + lit.value[897U] = 0U; + lit.value[898U] = 0U; + lit.value[899U] = 0U; + lit.value[900U] = 0U; + lit.value[901U] = 0U; + lit.value[902U] = 0U; + lit.value[903U] = 0U; + lit.value[904U] = 0U; + lit.value[905U] = 0U; + lit.value[906U] = 0U; + lit.value[907U] = 0U; + lit.value[908U] = 0U; + lit.value[909U] = 0U; + lit.value[910U] = 0U; + lit.value[911U] = 0U; + lit.value[912U] = 0U; + lit.value[913U] = 0U; + lit.value[914U] = 0U; + lit.value[915U] = 0U; + lit.value[916U] = 0U; + lit.value[917U] = 0U; + lit.value[918U] = 0U; + lit.value[919U] = 0U; + lit.value[920U] = 0U; + lit.value[921U] = 0U; + lit.value[922U] = 0U; + lit.value[923U] = 0U; + lit.value[924U] = 0U; + lit.value[925U] = 0U; + lit.value[926U] = 0U; + lit.value[927U] = 0U; + lit.value[928U] = 0U; + lit.value[929U] = 0U; + lit.value[930U] = 0U; + lit.value[931U] = 0U; + lit.value[932U] = 0U; + lit.value[933U] = 0U; + lit.value[934U] = 0U; + lit.value[935U] = 0U; + lit.value[936U] = 0U; + lit.value[937U] = 0U; + lit.value[938U] = 0U; + lit.value[939U] = 0U; + lit.value[940U] = 0U; + lit.value[941U] = 0U; + lit.value[942U] = 0U; + lit.value[943U] = 0U; + lit.value[944U] = 0U; + lit.value[945U] = 0U; + lit.value[946U] = 0U; + lit.value[947U] = 0U; + lit.value[948U] = 0U; + lit.value[949U] = 0U; + lit.value[950U] = 0U; + lit.value[951U] = 0U; + lit.value[952U] = 0U; + lit.value[953U] = 0U; + lit.value[954U] = 0U; + lit.value[955U] = 0U; + lit.value[956U] = 0U; + lit.value[957U] = 0U; + lit.value[958U] = 0U; + lit.value[959U] = 0U; + lit.value[960U] = 0U; + lit.value[961U] = 0U; + lit.value[962U] = 0U; + lit.value[963U] = 0U; + lit.value[964U] = 0U; + lit.value[965U] = 0U; + lit.value[966U] = 0U; + lit.value[967U] = 0U; + lit.value[968U] = 0U; + lit.value[969U] = 0U; + lit.value[970U] = 0U; + lit.value[971U] = 0U; + lit.value[972U] = 0U; + lit.value[973U] = 0U; + lit.value[974U] = 0U; + lit.value[975U] = 0U; + lit.value[976U] = 0U; + lit.value[977U] = 0U; + lit.value[978U] = 0U; + lit.value[979U] = 0U; + lit.value[980U] = 0U; + lit.value[981U] = 0U; + lit.value[982U] = 0U; + lit.value[983U] = 0U; + lit.value[984U] = 0U; + lit.value[985U] = 0U; + lit.value[986U] = 0U; + lit.value[987U] = 0U; + lit.value[988U] = 0U; + lit.value[989U] = 0U; + lit.value[990U] = 0U; + lit.value[991U] = 0U; + lit.value[992U] = 0U; + lit.value[993U] = 0U; + lit.value[994U] = 0U; + lit.value[995U] = 0U; + lit.value[996U] = 0U; + lit.value[997U] = 0U; + lit.value[998U] = 0U; + lit.value[999U] = 0U; + lit.value[1000U] = 0U; + lit.value[1001U] = 0U; + lit.value[1002U] = 0U; + lit.value[1003U] = 0U; + lit.value[1004U] = 0U; + lit.value[1005U] = 0U; + lit.value[1006U] = 0U; + lit.value[1007U] = 0U; + lit.value[1008U] = 0U; + lit.value[1009U] = 0U; + lit.value[1010U] = 0U; + lit.value[1011U] = 0U; + lit.value[1012U] = 0U; + lit.value[1013U] = 0U; + lit.value[1014U] = 0U; + lit.value[1015U] = 0U; + lit.value[1016U] = 0U; + lit.value[1017U] = 0U; + lit.value[1018U] = 0U; + lit.value[1019U] = 0U; + lit.value[1020U] = 0U; + lit.value[1021U] = 0U; + lit.value[1022U] = 0U; + lit.value[1023U] = 0U; + lit.value[1024U] = 0U; + lit.value[1025U] = 0U; + lit.value[1026U] = 0U; + lit.value[1027U] = 0U; + lit.value[1028U] = 0U; + lit.value[1029U] = 0U; + lit.value[1030U] = 0U; + lit.value[1031U] = 0U; + lit.value[1032U] = 0U; + lit.value[1033U] = 0U; + lit.value[1034U] = 0U; + lit.value[1035U] = 0U; + lit.value[1036U] = 0U; + lit.value[1037U] = 0U; + lit.value[1038U] = 0U; + lit.value[1039U] = 0U; + lit.value[1040U] = 0U; + lit.value[1041U] = 0U; + lit.value[1042U] = 0U; + lit.value[1043U] = 0U; + lit.value[1044U] = 0U; + lit.value[1045U] = 0U; + lit.value[1046U] = 0U; + lit.value[1047U] = 0U; + lit.value[1048U] = 0U; + lit.value[1049U] = 0U; + lit.value[1050U] = 0U; + lit.value[1051U] = 0U; + lit.value[1052U] = 0U; + lit.value[1053U] = 0U; + lit.value[1054U] = 0U; + lit.value[1055U] = 0U; + lit.value[1056U] = 0U; + lit.value[1057U] = 0U; + lit.value[1058U] = 0U; + lit.value[1059U] = 0U; + lit.value[1060U] = 0U; + lit.value[1061U] = 0U; + lit.value[1062U] = 0U; + lit.value[1063U] = 0U; + lit.value[1064U] = 0U; + lit.value[1065U] = 0U; + lit.value[1066U] = 0U; + lit.value[1067U] = 0U; + lit.value[1068U] = 0U; + lit.value[1069U] = 0U; + lit.value[1070U] = 0U; + lit.value[1071U] = 0U; + lit.value[1072U] = 0U; + lit.value[1073U] = 0U; + lit.value[1074U] = 0U; + lit.value[1075U] = 0U; + lit.value[1076U] = 0U; + lit.value[1077U] = 0U; + lit.value[1078U] = 0U; + lit.value[1079U] = 0U; + lit.value[1080U] = 0U; + lit.value[1081U] = 0U; + lit.value[1082U] = 0U; + lit.value[1083U] = 0U; + lit.value[1084U] = 0U; + lit.value[1085U] = 0U; + lit.value[1086U] = 0U; + lit.value[1087U] = 0U; + lit.value[1088U] = 0U; + lit.value[1089U] = 0U; + lit.value[1090U] = 0U; + lit.value[1091U] = 0U; + lit.value[1092U] = 0U; + lit.value[1093U] = 0U; + lit.value[1094U] = 0U; + lit.value[1095U] = 0U; + lit.value[1096U] = 0U; + lit.value[1097U] = 0U; + lit.value[1098U] = 0U; + lit.value[1099U] = 0U; + lit.value[1100U] = 0U; + lit.value[1101U] = 0U; + lit.value[1102U] = 0U; + lit.value[1103U] = 0U; + lit.value[1104U] = 0U; + lit.value[1105U] = 0U; + lit.value[1106U] = 0U; + lit.value[1107U] = 0U; + lit.value[1108U] = 0U; + lit.value[1109U] = 0U; + lit.value[1110U] = 0U; + lit.value[1111U] = 0U; + lit.value[1112U] = 0U; + lit.value[1113U] = 0U; + lit.value[1114U] = 0U; + lit.value[1115U] = 0U; + lit.value[1116U] = 0U; + lit.value[1117U] = 0U; + lit.value[1118U] = 0U; + lit.value[1119U] = 0U; + lit.value[1120U] = 0U; + lit.value[1121U] = 0U; + lit.value[1122U] = 0U; + lit.value[1123U] = 0U; + lit.value[1124U] = 0U; + lit.value[1125U] = 0U; + lit.value[1126U] = 0U; + lit.value[1127U] = 0U; + lit.value[1128U] = 0U; + lit.value[1129U] = 0U; + lit.value[1130U] = 0U; + lit.value[1131U] = 0U; + lit.value[1132U] = 0U; + lit.value[1133U] = 0U; + lit.value[1134U] = 0U; + lit.value[1135U] = 0U; + lit.value[1136U] = 0U; + lit.value[1137U] = 0U; + lit.value[1138U] = 0U; + lit.value[1139U] = 0U; + lit.value[1140U] = 0U; + lit.value[1141U] = 0U; + lit.value[1142U] = 0U; + lit.value[1143U] = 0U; + lit.value[1144U] = 0U; + lit.value[1145U] = 0U; + lit.value[1146U] = 0U; + lit.value[1147U] = 0U; + lit.value[1148U] = 0U; + lit.value[1149U] = 0U; + lit.value[1150U] = 0U; + lit.value[1151U] = 0U; + lit.value[1152U] = 0U; + lit.value[1153U] = 0U; + lit.value[1154U] = 0U; + lit.value[1155U] = 0U; + lit.value[1156U] = 0U; + lit.value[1157U] = 0U; + lit.value[1158U] = 0U; + lit.value[1159U] = 0U; + lit.value[1160U] = 0U; + lit.value[1161U] = 0U; + lit.value[1162U] = 0U; + lit.value[1163U] = 0U; + lit.value[1164U] = 0U; + lit.value[1165U] = 0U; + lit.value[1166U] = 0U; + lit.value[1167U] = 0U; + lit.value[1168U] = 0U; + lit.value[1169U] = 0U; + lit.value[1170U] = 0U; + lit.value[1171U] = 0U; + lit.value[1172U] = 0U; + lit.value[1173U] = 0U; + lit.value[1174U] = 0U; + lit.value[1175U] = 0U; + lit.value[1176U] = 0U; + lit.value[1177U] = 0U; + lit.value[1178U] = 0U; + lit.value[1179U] = 0U; + lit.value[1180U] = 0U; + lit.value[1181U] = 0U; + lit.value[1182U] = 0U; + lit.value[1183U] = 0U; + lit.value[1184U] = 0U; + lit.value[1185U] = 0U; + lit.value[1186U] = 0U; + lit.value[1187U] = 0U; + lit.value[1188U] = 0U; + lit.value[1189U] = 0U; + lit.value[1190U] = 0U; + lit.value[1191U] = 0U; + lit.value[1192U] = 0U; + lit.value[1193U] = 0U; + lit.value[1194U] = 0U; + lit.value[1195U] = 0U; + lit.value[1196U] = 0U; + lit.value[1197U] = 0U; + lit.value[1198U] = 0U; + lit.value[1199U] = 0U; + lit.value[1200U] = 0U; + lit.value[1201U] = 0U; + lit.value[1202U] = 0U; + lit.value[1203U] = 0U; + lit.value[1204U] = 0U; + lit.value[1205U] = 0U; + lit.value[1206U] = 0U; + lit.value[1207U] = 0U; + lit.value[1208U] = 0U; + lit.value[1209U] = 0U; + lit.value[1210U] = 0U; + lit.value[1211U] = 0U; + lit.value[1212U] = 0U; + lit.value[1213U] = 0U; + lit.value[1214U] = 0U; + lit.value[1215U] = 0U; + lit.value[1216U] = 0U; + lit.value[1217U] = 0U; + lit.value[1218U] = 0U; + lit.value[1219U] = 0U; + lit.value[1220U] = 0U; + lit.value[1221U] = 0U; + lit.value[1222U] = 0U; + lit.value[1223U] = 0U; + lit.value[1224U] = 0U; + lit.value[1225U] = 0U; + lit.value[1226U] = 0U; + lit.value[1227U] = 0U; + lit.value[1228U] = 0U; + lit.value[1229U] = 0U; + lit.value[1230U] = 0U; + lit.value[1231U] = 0U; + lit.value[1232U] = 0U; + lit.value[1233U] = 0U; + lit.value[1234U] = 0U; + lit.value[1235U] = 0U; + lit.value[1236U] = 0U; + lit.value[1237U] = 0U; + lit.value[1238U] = 0U; + lit.value[1239U] = 0U; + lit.value[1240U] = 0U; + lit.value[1241U] = 0U; + lit.value[1242U] = 0U; + lit.value[1243U] = 0U; + lit.value[1244U] = 0U; + lit.value[1245U] = 0U; + lit.value[1246U] = 0U; + lit.value[1247U] = 0U; + lit.value[1248U] = 0U; + lit.value[1249U] = 0U; + lit.value[1250U] = 0U; + lit.value[1251U] = 0U; + lit.value[1252U] = 0U; + lit.value[1253U] = 0U; + lit.value[1254U] = 0U; + lit.value[1255U] = 0U; + lit.value[1256U] = 0U; + lit.value[1257U] = 0U; + lit.value[1258U] = 0U; + lit.value[1259U] = 0U; + lit.value[1260U] = 0U; + lit.value[1261U] = 0U; + lit.value[1262U] = 0U; + lit.value[1263U] = 0U; + lit.value[1264U] = 0U; + lit.value[1265U] = 0U; + lit.value[1266U] = 0U; + lit.value[1267U] = 0U; + lit.value[1268U] = 0U; + lit.value[1269U] = 0U; + lit.value[1270U] = 0U; + lit.value[1271U] = 0U; + lit.value[1272U] = 0U; + lit.value[1273U] = 0U; + lit.value[1274U] = 0U; + lit.value[1275U] = 0U; + lit.value[1276U] = 0U; + lit.value[1277U] = 0U; + lit.value[1278U] = 0U; + lit.value[1279U] = 0U; + lit.value[1280U] = 0U; + lit.value[1281U] = 0U; + lit.value[1282U] = 0U; + lit.value[1283U] = 0U; + lit.value[1284U] = 0U; + lit.value[1285U] = 0U; + lit.value[1286U] = 0U; + lit.value[1287U] = 0U; + lit.value[1288U] = 0U; + lit.value[1289U] = 0U; + lit.value[1290U] = 0U; + lit.value[1291U] = 0U; + lit.value[1292U] = 0U; + lit.value[1293U] = 0U; + lit.value[1294U] = 0U; + lit.value[1295U] = 0U; + lit.value[1296U] = 0U; + lit.value[1297U] = 0U; + lit.value[1298U] = 0U; + lit.value[1299U] = 0U; + lit.value[1300U] = 0U; + lit.value[1301U] = 0U; + lit.value[1302U] = 0U; + lit.value[1303U] = 0U; + lit.value[1304U] = 0U; + lit.value[1305U] = 0U; + lit.value[1306U] = 0U; + lit.value[1307U] = 0U; + lit.value[1308U] = 0U; + lit.value[1309U] = 0U; + lit.value[1310U] = 0U; + lit.value[1311U] = 0U; + lit.value[1312U] = 0U; + lit.value[1313U] = 0U; + lit.value[1314U] = 0U; + lit.value[1315U] = 0U; + lit.value[1316U] = 0U; + lit.value[1317U] = 0U; + lit.value[1318U] = 0U; + lit.value[1319U] = 0U; + lit.value[1320U] = 0U; + lit.value[1321U] = 0U; + lit.value[1322U] = 0U; + lit.value[1323U] = 0U; + lit.value[1324U] = 0U; + lit.value[1325U] = 0U; + lit.value[1326U] = 0U; + lit.value[1327U] = 0U; + lit.value[1328U] = 0U; + lit.value[1329U] = 0U; + lit.value[1330U] = 0U; + lit.value[1331U] = 0U; + lit.value[1332U] = 0U; + lit.value[1333U] = 0U; + lit.value[1334U] = 0U; + lit.value[1335U] = 0U; + lit.value[1336U] = 0U; + lit.value[1337U] = 0U; + lit.value[1338U] = 0U; + lit.value[1339U] = 0U; + lit.value[1340U] = 0U; + lit.value[1341U] = 0U; + lit.value[1342U] = 0U; + lit.value[1343U] = 0U; + lit.value[1344U] = 0U; + lit.value[1345U] = 0U; + lit.value[1346U] = 0U; + lit.value[1347U] = 0U; + lit.value[1348U] = 0U; + lit.value[1349U] = 0U; + lit.value[1350U] = 0U; + lit.value[1351U] = 0U; + lit.value[1352U] = 0U; + lit.value[1353U] = 0U; + lit.value[1354U] = 0U; + lit.value[1355U] = 0U; + lit.value[1356U] = 0U; + lit.value[1357U] = 0U; + lit.value[1358U] = 0U; + lit.value[1359U] = 0U; + lit.value[1360U] = 0U; + lit.value[1361U] = 0U; + lit.value[1362U] = 0U; + lit.value[1363U] = 0U; + lit.value[1364U] = 0U; + lit.value[1365U] = 0U; + lit.value[1366U] = 0U; + lit.value[1367U] = 0U; + lit.value[1368U] = 0U; + lit.value[1369U] = 0U; + lit.value[1370U] = 0U; + lit.value[1371U] = 0U; + lit.value[1372U] = 0U; + lit.value[1373U] = 0U; + lit.value[1374U] = 0U; + lit.value[1375U] = 0U; + lit.value[1376U] = 0U; + lit.value[1377U] = 0U; + lit.value[1378U] = 0U; + lit.value[1379U] = 0U; + lit.value[1380U] = 0U; + lit.value[1381U] = 0U; + lit.value[1382U] = 0U; + lit.value[1383U] = 0U; + lit.value[1384U] = 0U; + lit.value[1385U] = 0U; + lit.value[1386U] = 0U; + lit.value[1387U] = 0U; + lit.value[1388U] = 0U; + lit.value[1389U] = 0U; + lit.value[1390U] = 0U; + lit.value[1391U] = 0U; + lit.value[1392U] = 0U; + lit.value[1393U] = 0U; + lit.value[1394U] = 0U; + lit.value[1395U] = 0U; + lit.value[1396U] = 0U; + lit.value[1397U] = 0U; + lit.value[1398U] = 0U; + lit.value[1399U] = 0U; + lit.value[1400U] = 0U; + lit.value[1401U] = 0U; + lit.value[1402U] = 0U; + lit.value[1403U] = 0U; + lit.value[1404U] = 0U; + lit.value[1405U] = 0U; + lit.value[1406U] = 0U; + lit.value[1407U] = 0U; + lit.value[1408U] = 0U; + lit.value[1409U] = 0U; + lit.value[1410U] = 0U; + lit.value[1411U] = 0U; + lit.value[1412U] = 0U; + lit.value[1413U] = 0U; + lit.value[1414U] = 0U; + lit.value[1415U] = 0U; + lit.value[1416U] = 0U; + lit.value[1417U] = 0U; + lit.value[1418U] = 0U; + lit.value[1419U] = 0U; + lit.value[1420U] = 0U; + lit.value[1421U] = 0U; + lit.value[1422U] = 0U; + lit.value[1423U] = 0U; + lit.value[1424U] = 0U; + lit.value[1425U] = 0U; + lit.value[1426U] = 0U; + lit.value[1427U] = 0U; + lit.value[1428U] = 0U; + lit.value[1429U] = 0U; + lit.value[1430U] = 0U; + lit.value[1431U] = 0U; + lit.value[1432U] = 0U; + lit.value[1433U] = 0U; + lit.value[1434U] = 0U; + lit.value[1435U] = 0U; + lit.value[1436U] = 0U; + lit.value[1437U] = 0U; + lit.value[1438U] = 0U; + lit.value[1439U] = 0U; + lit.value[1440U] = 0U; + lit.value[1441U] = 0U; + lit.value[1442U] = 0U; + lit.value[1443U] = 0U; + lit.value[1444U] = 0U; + lit.value[1445U] = 0U; + lit.value[1446U] = 0U; + lit.value[1447U] = 0U; + lit.value[1448U] = 0U; + lit.value[1449U] = 0U; + lit.value[1450U] = 0U; + lit.value[1451U] = 0U; + lit.value[1452U] = 0U; + lit.value[1453U] = 0U; + lit.value[1454U] = 0U; + lit.value[1455U] = 0U; + lit.value[1456U] = 0U; + lit.value[1457U] = 0U; + lit.value[1458U] = 0U; + lit.value[1459U] = 0U; + lit.value[1460U] = 0U; + lit.value[1461U] = 0U; + lit.value[1462U] = 0U; + lit.value[1463U] = 0U; + lit.value[1464U] = 0U; + lit.value[1465U] = 0U; + lit.value[1466U] = 0U; + lit.value[1467U] = 0U; + lit.value[1468U] = 0U; + lit.value[1469U] = 0U; + lit.value[1470U] = 0U; + lit.value[1471U] = 0U; + lit.value[1472U] = 0U; + lit.value[1473U] = 0U; + lit.value[1474U] = 0U; + lit.value[1475U] = 0U; + lit.value[1476U] = 0U; + lit.value[1477U] = 0U; + lit.value[1478U] = 0U; + lit.value[1479U] = 0U; + lit.value[1480U] = 0U; + lit.value[1481U] = 0U; + lit.value[1482U] = 0U; + lit.value[1483U] = 0U; + lit.value[1484U] = 0U; + lit.value[1485U] = 0U; + lit.value[1486U] = 0U; + lit.value[1487U] = 0U; + lit.value[1488U] = 0U; + lit.value[1489U] = 0U; + lit.value[1490U] = 0U; + lit.value[1491U] = 0U; + lit.value[1492U] = 0U; + lit.value[1493U] = 0U; + lit.value[1494U] = 0U; + lit.value[1495U] = 0U; + lit.value[1496U] = 0U; + lit.value[1497U] = 0U; + lit.value[1498U] = 0U; + lit.value[1499U] = 0U; + lit.value[1500U] = 0U; + lit.value[1501U] = 0U; + lit.value[1502U] = 0U; + lit.value[1503U] = 0U; + lit.value[1504U] = 0U; + lit.value[1505U] = 0U; + lit.value[1506U] = 0U; + lit.value[1507U] = 0U; + lit.value[1508U] = 0U; + lit.value[1509U] = 0U; + lit.value[1510U] = 0U; + lit.value[1511U] = 0U; + lit.value[1512U] = 0U; + lit.value[1513U] = 0U; + lit.value[1514U] = 0U; + lit.value[1515U] = 0U; + lit.value[1516U] = 0U; + lit.value[1517U] = 0U; + lit.value[1518U] = 0U; + lit.value[1519U] = 0U; + lit.value[1520U] = 0U; + lit.value[1521U] = 0U; + lit.value[1522U] = 0U; + lit.value[1523U] = 0U; + lit.value[1524U] = 0U; + lit.value[1525U] = 0U; + lit.value[1526U] = 0U; + lit.value[1527U] = 0U; + lit.value[1528U] = 0U; + lit.value[1529U] = 0U; + lit.value[1530U] = 0U; + lit.value[1531U] = 0U; + lit.value[1532U] = 0U; + lit.value[1533U] = 0U; + lit.value[1534U] = 0U; + lit.value[1535U] = 0U; + lit.value[1536U] = 0U; + lit.value[1537U] = 0U; + lit.value[1538U] = 0U; + lit.value[1539U] = 0U; + lit.value[1540U] = 0U; + lit.value[1541U] = 0U; + lit.value[1542U] = 0U; + lit.value[1543U] = 0U; + lit.value[1544U] = 0U; + lit.value[1545U] = 0U; + lit.value[1546U] = 0U; + lit.value[1547U] = 0U; + lit.value[1548U] = 0U; + lit.value[1549U] = 0U; + lit.value[1550U] = 0U; + lit.value[1551U] = 0U; + lit.value[1552U] = 0U; + lit.value[1553U] = 0U; + lit.value[1554U] = 0U; + lit.value[1555U] = 0U; + lit.value[1556U] = 0U; + lit.value[1557U] = 0U; + lit.value[1558U] = 0U; + lit.value[1559U] = 0U; + lit.value[1560U] = 0U; + lit.value[1561U] = 0U; + lit.value[1562U] = 0U; + lit.value[1563U] = 0U; + lit.value[1564U] = 0U; + lit.value[1565U] = 0U; + lit.value[1566U] = 0U; + lit.value[1567U] = 0U; + lit.value[1568U] = 0U; + lit.value[1569U] = 0U; + lit.value[1570U] = 0U; + lit.value[1571U] = 0U; + lit.value[1572U] = 0U; + lit.value[1573U] = 0U; + lit.value[1574U] = 0U; + lit.value[1575U] = 0U; + lit.value[1576U] = 0U; + lit.value[1577U] = 0U; + lit.value[1578U] = 0U; + lit.value[1579U] = 0U; + lit.value[1580U] = 0U; + lit.value[1581U] = 0U; + lit.value[1582U] = 0U; + lit.value[1583U] = 0U; + lit.value[1584U] = 0U; + lit.value[1585U] = 0U; + lit.value[1586U] = 0U; + lit.value[1587U] = 0U; + lit.value[1588U] = 0U; + lit.value[1589U] = 0U; + lit.value[1590U] = 0U; + lit.value[1591U] = 0U; + lit.value[1592U] = 0U; + lit.value[1593U] = 0U; + lit.value[1594U] = 0U; + lit.value[1595U] = 0U; + lit.value[1596U] = 0U; + lit.value[1597U] = 0U; + lit.value[1598U] = 0U; + lit.value[1599U] = 0U; + lit.value[1600U] = 0U; + lit.value[1601U] = 0U; + lit.value[1602U] = 0U; + lit.value[1603U] = 0U; + lit.value[1604U] = 0U; + lit.value[1605U] = 0U; + lit.value[1606U] = 0U; + lit.value[1607U] = 0U; + lit.value[1608U] = 0U; + lit.value[1609U] = 0U; + lit.value[1610U] = 0U; + lit.value[1611U] = 0U; + lit.value[1612U] = 0U; + lit.value[1613U] = 0U; + lit.value[1614U] = 0U; + lit.value[1615U] = 0U; + lit.value[1616U] = 0U; + lit.value[1617U] = 0U; + lit.value[1618U] = 0U; + lit.value[1619U] = 0U; + lit.value[1620U] = 0U; + lit.value[1621U] = 0U; + lit.value[1622U] = 0U; + lit.value[1623U] = 0U; + lit.value[1624U] = 0U; + lit.value[1625U] = 0U; + lit.value[1626U] = 0U; + lit.value[1627U] = 0U; + lit.value[1628U] = 0U; + lit.value[1629U] = 0U; + lit.value[1630U] = 0U; + lit.value[1631U] = 0U; + lit.value[1632U] = 0U; + lit.value[1633U] = 0U; + lit.value[1634U] = 0U; + lit.value[1635U] = 0U; + lit.value[1636U] = 0U; + lit.value[1637U] = 0U; + lit.value[1638U] = 0U; + lit.value[1639U] = 0U; + lit.value[1640U] = 0U; + lit.value[1641U] = 0U; + lit.value[1642U] = 0U; + lit.value[1643U] = 0U; + lit.value[1644U] = 0U; + lit.value[1645U] = 0U; + lit.value[1646U] = 0U; + lit.value[1647U] = 0U; + lit.value[1648U] = 0U; + lit.value[1649U] = 0U; + lit.value[1650U] = 0U; + lit.value[1651U] = 0U; + lit.value[1652U] = 0U; + lit.value[1653U] = 0U; + lit.value[1654U] = 0U; + lit.value[1655U] = 0U; + lit.value[1656U] = 0U; + lit.value[1657U] = 0U; + lit.value[1658U] = 0U; + lit.value[1659U] = 0U; + lit.value[1660U] = 0U; + lit.value[1661U] = 0U; + lit.value[1662U] = 0U; + lit.value[1663U] = 0U; + lit.value[1664U] = 0U; + lit.value[1665U] = 0U; + lit.value[1666U] = 0U; + lit.value[1667U] = 0U; + lit.value[1668U] = 0U; + lit.value[1669U] = 0U; + lit.value[1670U] = 0U; + lit.value[1671U] = 0U; + lit.value[1672U] = 0U; + lit.value[1673U] = 0U; + lit.value[1674U] = 0U; + lit.value[1675U] = 0U; + lit.value[1676U] = 0U; + lit.value[1677U] = 0U; + lit.value[1678U] = 0U; + lit.value[1679U] = 0U; + lit.value[1680U] = 0U; + lit.value[1681U] = 0U; + lit.value[1682U] = 0U; + lit.value[1683U] = 0U; + lit.value[1684U] = 0U; + lit.value[1685U] = 0U; + lit.value[1686U] = 0U; + lit.value[1687U] = 0U; + lit.value[1688U] = 0U; + lit.value[1689U] = 0U; + lit.value[1690U] = 0U; + lit.value[1691U] = 0U; + lit.value[1692U] = 0U; + lit.value[1693U] = 0U; + lit.value[1694U] = 0U; + lit.value[1695U] = 0U; + lit.value[1696U] = 0U; + lit.value[1697U] = 0U; + lit.value[1698U] = 0U; + lit.value[1699U] = 0U; + lit.value[1700U] = 0U; + lit.value[1701U] = 0U; + lit.value[1702U] = 0U; + lit.value[1703U] = 0U; + lit.value[1704U] = 0U; + lit.value[1705U] = 0U; + lit.value[1706U] = 0U; + lit.value[1707U] = 0U; + lit.value[1708U] = 0U; + lit.value[1709U] = 0U; + lit.value[1710U] = 0U; + lit.value[1711U] = 0U; + lit.value[1712U] = 0U; + lit.value[1713U] = 0U; + lit.value[1714U] = 0U; + lit.value[1715U] = 0U; + lit.value[1716U] = 0U; + lit.value[1717U] = 0U; + lit.value[1718U] = 0U; + lit.value[1719U] = 0U; + lit.value[1720U] = 0U; + lit.value[1721U] = 0U; + lit.value[1722U] = 0U; + lit.value[1723U] = 0U; + lit.value[1724U] = 0U; + lit.value[1725U] = 0U; + lit.value[1726U] = 0U; + lit.value[1727U] = 0U; + lit.value[1728U] = 0U; + lit.value[1729U] = 0U; + lit.value[1730U] = 0U; + lit.value[1731U] = 0U; + lit.value[1732U] = 0U; + lit.value[1733U] = 0U; + lit.value[1734U] = 0U; + lit.value[1735U] = 0U; + lit.value[1736U] = 0U; + lit.value[1737U] = 0U; + lit.value[1738U] = 0U; + lit.value[1739U] = 0U; + lit.value[1740U] = 0U; + lit.value[1741U] = 0U; + lit.value[1742U] = 0U; + lit.value[1743U] = 0U; + lit.value[1744U] = 0U; + lit.value[1745U] = 0U; + lit.value[1746U] = 0U; + lit.value[1747U] = 0U; + lit.value[1748U] = 0U; + lit.value[1749U] = 0U; + lit.value[1750U] = 0U; + lit.value[1751U] = 0U; + lit.value[1752U] = 0U; + lit.value[1753U] = 0U; + lit.value[1754U] = 0U; + lit.value[1755U] = 0U; + lit.value[1756U] = 0U; + lit.value[1757U] = 0U; + lit.value[1758U] = 0U; + lit.value[1759U] = 0U; + lit.value[1760U] = 0U; + lit.value[1761U] = 0U; + lit.value[1762U] = 0U; + lit.value[1763U] = 0U; + lit.value[1764U] = 0U; + lit.value[1765U] = 0U; + lit.value[1766U] = 0U; + lit.value[1767U] = 0U; + lit.value[1768U] = 0U; + lit.value[1769U] = 0U; + lit.value[1770U] = 0U; + lit.value[1771U] = 0U; + lit.value[1772U] = 0U; + lit.value[1773U] = 0U; + lit.value[1774U] = 0U; + lit.value[1775U] = 0U; + lit.value[1776U] = 0U; + lit.value[1777U] = 0U; + lit.value[1778U] = 0U; + lit.value[1779U] = 0U; + lit.value[1780U] = 0U; + lit.value[1781U] = 0U; + lit.value[1782U] = 0U; + lit.value[1783U] = 0U; + lit.value[1784U] = 0U; + lit.value[1785U] = 0U; + lit.value[1786U] = 0U; + lit.value[1787U] = 0U; + lit.value[1788U] = 0U; + lit.value[1789U] = 0U; + lit.value[1790U] = 0U; + lit.value[1791U] = 0U; + lit.value[1792U] = 0U; + lit.value[1793U] = 0U; + lit.value[1794U] = 0U; + lit.value[1795U] = 0U; + lit.value[1796U] = 0U; + lit.value[1797U] = 0U; + lit.value[1798U] = 0U; + lit.value[1799U] = 0U; + lit.value[1800U] = 0U; + lit.value[1801U] = 0U; + lit.value[1802U] = 0U; + lit.value[1803U] = 0U; + lit.value[1804U] = 0U; + lit.value[1805U] = 0U; + lit.value[1806U] = 0U; + lit.value[1807U] = 0U; + lit.value[1808U] = 0U; + lit.value[1809U] = 0U; + lit.value[1810U] = 0U; + lit.value[1811U] = 0U; + lit.value[1812U] = 0U; + lit.value[1813U] = 0U; + lit.value[1814U] = 0U; + lit.value[1815U] = 0U; + lit.value[1816U] = 0U; + lit.value[1817U] = 0U; + lit.value[1818U] = 0U; + lit.value[1819U] = 0U; + lit.value[1820U] = 0U; + lit.value[1821U] = 0U; + lit.value[1822U] = 0U; + lit.value[1823U] = 0U; + lit.value[1824U] = 0U; + lit.value[1825U] = 0U; + lit.value[1826U] = 0U; + lit.value[1827U] = 0U; + lit.value[1828U] = 0U; + lit.value[1829U] = 0U; + lit.value[1830U] = 0U; + lit.value[1831U] = 0U; + lit.value[1832U] = 0U; + lit.value[1833U] = 0U; + lit.value[1834U] = 0U; + lit.value[1835U] = 0U; + lit.value[1836U] = 0U; + lit.value[1837U] = 0U; + lit.value[1838U] = 0U; + lit.value[1839U] = 0U; + lit.value[1840U] = 0U; + lit.value[1841U] = 0U; + lit.value[1842U] = 0U; + lit.value[1843U] = 0U; + lit.value[1844U] = 0U; + lit.value[1845U] = 0U; + lit.value[1846U] = 0U; + lit.value[1847U] = 0U; + lit.value[1848U] = 0U; + lit.value[1849U] = 0U; + lit.value[1850U] = 0U; + lit.value[1851U] = 0U; + lit.value[1852U] = 0U; + lit.value[1853U] = 0U; + lit.value[1854U] = 0U; + lit.value[1855U] = 0U; + lit.value[1856U] = 0U; + lit.value[1857U] = 0U; + lit.value[1858U] = 0U; + lit.value[1859U] = 0U; + lit.value[1860U] = 0U; + lit.value[1861U] = 0U; + lit.value[1862U] = 0U; + lit.value[1863U] = 0U; + lit.value[1864U] = 0U; + lit.value[1865U] = 0U; + lit.value[1866U] = 0U; + lit.value[1867U] = 0U; + lit.value[1868U] = 0U; + lit.value[1869U] = 0U; + lit.value[1870U] = 0U; + lit.value[1871U] = 0U; + lit.value[1872U] = 0U; + lit.value[1873U] = 0U; + lit.value[1874U] = 0U; + lit.value[1875U] = 0U; + lit.value[1876U] = 0U; + lit.value[1877U] = 0U; + lit.value[1878U] = 0U; + lit.value[1879U] = 0U; + lit.value[1880U] = 0U; + lit.value[1881U] = 0U; + lit.value[1882U] = 0U; + lit.value[1883U] = 0U; + lit.value[1884U] = 0U; + lit.value[1885U] = 0U; + lit.value[1886U] = 0U; + lit.value[1887U] = 0U; + lit.value[1888U] = 0U; + lit.value[1889U] = 0U; + lit.value[1890U] = 0U; + lit.value[1891U] = 0U; + lit.value[1892U] = 0U; + lit.value[1893U] = 0U; + lit.value[1894U] = 0U; + lit.value[1895U] = 0U; + lit.value[1896U] = 0U; + lit.value[1897U] = 0U; + lit.value[1898U] = 0U; + lit.value[1899U] = 0U; + lit.value[1900U] = 0U; + lit.value[1901U] = 0U; + lit.value[1902U] = 0U; + lit.value[1903U] = 0U; + lit.value[1904U] = 0U; + lit.value[1905U] = 0U; + lit.value[1906U] = 0U; + lit.value[1907U] = 0U; + lit.value[1908U] = 0U; + lit.value[1909U] = 0U; + lit.value[1910U] = 0U; + lit.value[1911U] = 0U; + lit.value[1912U] = 0U; + lit.value[1913U] = 0U; + lit.value[1914U] = 0U; + lit.value[1915U] = 0U; + lit.value[1916U] = 0U; + lit.value[1917U] = 0U; + lit.value[1918U] = 0U; + lit.value[1919U] = 0U; + lit.value[1920U] = 0U; + lit.value[1921U] = 0U; + lit.value[1922U] = 0U; + lit.value[1923U] = 0U; + lit.value[1924U] = 0U; + lit.value[1925U] = 0U; + lit.value[1926U] = 0U; + lit.value[1927U] = 0U; + lit.value[1928U] = 0U; + lit.value[1929U] = 0U; + lit.value[1930U] = 0U; + lit.value[1931U] = 0U; + lit.value[1932U] = 0U; + lit.value[1933U] = 0U; + lit.value[1934U] = 0U; + lit.value[1935U] = 0U; + lit.value[1936U] = 0U; + lit.value[1937U] = 0U; + lit.value[1938U] = 0U; + lit.value[1939U] = 0U; + lit.value[1940U] = 0U; + lit.value[1941U] = 0U; + lit.value[1942U] = 0U; + lit.value[1943U] = 0U; + lit.value[1944U] = 0U; + lit.value[1945U] = 0U; + lit.value[1946U] = 0U; + lit.value[1947U] = 0U; + lit.value[1948U] = 0U; + lit.value[1949U] = 0U; + lit.value[1950U] = 0U; + lit.value[1951U] = 0U; + lit.value[1952U] = 0U; + lit.value[1953U] = 0U; + lit.value[1954U] = 0U; + lit.value[1955U] = 0U; + lit.value[1956U] = 0U; + lit.value[1957U] = 0U; + lit.value[1958U] = 0U; + lit.value[1959U] = 0U; + lit.value[1960U] = 0U; + lit.value[1961U] = 0U; + lit.value[1962U] = 0U; + lit.value[1963U] = 0U; + lit.value[1964U] = 0U; + lit.value[1965U] = 0U; + lit.value[1966U] = 0U; + lit.value[1967U] = 0U; + lit.value[1968U] = 0U; + lit.value[1969U] = 0U; + lit.value[1970U] = 0U; + lit.value[1971U] = 0U; + lit.value[1972U] = 0U; + lit.value[1973U] = 0U; + lit.value[1974U] = 0U; + lit.value[1975U] = 0U; + lit.value[1976U] = 0U; + lit.value[1977U] = 0U; + lit.value[1978U] = 0U; + lit.value[1979U] = 0U; + lit.value[1980U] = 0U; + lit.value[1981U] = 0U; + lit.value[1982U] = 0U; + lit.value[1983U] = 0U; + lit.value[1984U] = 0U; + lit.value[1985U] = 0U; + lit.value[1986U] = 0U; + lit.value[1987U] = 0U; + lit.value[1988U] = 0U; + lit.value[1989U] = 0U; + lit.value[1990U] = 0U; + lit.value[1991U] = 0U; + lit.value[1992U] = 0U; + lit.value[1993U] = 0U; + lit.value[1994U] = 0U; + lit.value[1995U] = 0U; + lit.value[1996U] = 0U; + lit.value[1997U] = 0U; + lit.value[1998U] = 0U; + lit.value[1999U] = 0U; + lit.value[2000U] = 0U; + lit.value[2001U] = 0U; + lit.value[2002U] = 0U; + lit.value[2003U] = 0U; + lit.value[2004U] = 0U; + lit.value[2005U] = 0U; + lit.value[2006U] = 0U; + lit.value[2007U] = 0U; + lit.value[2008U] = 0U; + lit.value[2009U] = 0U; + lit.value[2010U] = 0U; + lit.value[2011U] = 0U; + lit.value[2012U] = 0U; + lit.value[2013U] = 0U; + lit.value[2014U] = 0U; + lit.value[2015U] = 0U; + lit.value[2016U] = 0U; + lit.value[2017U] = 0U; + lit.value[2018U] = 0U; + lit.value[2019U] = 0U; + lit.value[2020U] = 0U; + lit.value[2021U] = 0U; + lit.value[2022U] = 0U; + lit.value[2023U] = 0U; + lit.value[2024U] = 0U; + lit.value[2025U] = 0U; + lit.value[2026U] = 0U; + lit.value[2027U] = 0U; + lit.value[2028U] = 0U; + lit.value[2029U] = 0U; + lit.value[2030U] = 0U; + lit.value[2031U] = 0U; + lit.value[2032U] = 0U; + lit.value[2033U] = 0U; + lit.value[2034U] = 0U; + lit.value[2035U] = 0U; + lit.value[2036U] = 0U; + lit.value[2037U] = 0U; + lit.value[2038U] = 0U; + lit.value[2039U] = 0U; + lit.value[2040U] = 0U; + lit.value[2041U] = 0U; + lit.value[2042U] = 0U; + lit.value[2043U] = 0U; + lit.value[2044U] = 0U; + lit.value[2045U] = 0U; + lit.value[2046U] = 0U; + lit.value[2047U] = 0U; + lit.value[2048U] = 0U; + lit.value[2049U] = 0U; + lit.value[2050U] = 0U; + lit.value[2051U] = 0U; + lit.value[2052U] = 0U; + lit.value[2053U] = 0U; + lit.value[2054U] = 0U; + lit.value[2055U] = 0U; + lit.value[2056U] = 0U; + lit.value[2057U] = 0U; + lit.value[2058U] = 0U; + lit.value[2059U] = 0U; + lit.value[2060U] = 0U; + lit.value[2061U] = 0U; + lit.value[2062U] = 0U; + lit.value[2063U] = 0U; + lit.value[2064U] = 0U; + lit.value[2065U] = 0U; + lit.value[2066U] = 0U; + lit.value[2067U] = 0U; + lit.value[2068U] = 0U; + lit.value[2069U] = 0U; + lit.value[2070U] = 0U; + lit.value[2071U] = 0U; + lit.value[2072U] = 0U; + lit.value[2073U] = 0U; + lit.value[2074U] = 0U; + lit.value[2075U] = 0U; + lit.value[2076U] = 0U; + lit.value[2077U] = 0U; + lit.value[2078U] = 0U; + lit.value[2079U] = 0U; + lit.value[2080U] = 0U; + lit.value[2081U] = 0U; + lit.value[2082U] = 0U; + lit.value[2083U] = 0U; + lit.value[2084U] = 0U; + lit.value[2085U] = 0U; + lit.value[2086U] = 0U; + lit.value[2087U] = 0U; + lit.value[2088U] = 0U; + lit.value[2089U] = 0U; + lit.value[2090U] = 0U; + lit.value[2091U] = 0U; + lit.value[2092U] = 0U; + lit.value[2093U] = 0U; + lit.value[2094U] = 0U; + lit.value[2095U] = 0U; + lit.value[2096U] = 0U; + lit.value[2097U] = 0U; + lit.value[2098U] = 0U; + lit.value[2099U] = 0U; + lit.value[2100U] = 0U; + lit.value[2101U] = 0U; + lit.value[2102U] = 0U; + lit.value[2103U] = 0U; + lit.value[2104U] = 0U; + lit.value[2105U] = 0U; + lit.value[2106U] = 0U; + lit.value[2107U] = 0U; + lit.value[2108U] = 0U; + lit.value[2109U] = 0U; + lit.value[2110U] = 0U; + lit.value[2111U] = 0U; + lit.value[2112U] = 0U; + lit.value[2113U] = 0U; + lit.value[2114U] = 0U; + lit.value[2115U] = 0U; + lit.value[2116U] = 0U; + lit.value[2117U] = 0U; + lit.value[2118U] = 0U; + lit.value[2119U] = 0U; + lit.value[2120U] = 0U; + lit.value[2121U] = 0U; + lit.value[2122U] = 0U; + lit.value[2123U] = 0U; + lit.value[2124U] = 0U; + lit.value[2125U] = 0U; + lit.value[2126U] = 0U; + lit.value[2127U] = 0U; + lit.value[2128U] = 0U; + lit.value[2129U] = 0U; + lit.value[2130U] = 0U; + lit.value[2131U] = 0U; + lit.value[2132U] = 0U; + lit.value[2133U] = 0U; + lit.value[2134U] = 0U; + lit.value[2135U] = 0U; + lit.value[2136U] = 0U; + lit.value[2137U] = 0U; + lit.value[2138U] = 0U; + lit.value[2139U] = 0U; + lit.value[2140U] = 0U; + lit.value[2141U] = 0U; + lit.value[2142U] = 0U; + lit.value[2143U] = 0U; + lit.value[2144U] = 0U; + lit.value[2145U] = 0U; + lit.value[2146U] = 0U; + lit.value[2147U] = 0U; + lit.value[2148U] = 0U; + lit.value[2149U] = 0U; + lit.value[2150U] = 0U; + lit.value[2151U] = 0U; + lit.value[2152U] = 0U; + lit.value[2153U] = 0U; + lit.value[2154U] = 0U; + lit.value[2155U] = 0U; + lit.value[2156U] = 0U; + lit.value[2157U] = 0U; + lit.value[2158U] = 0U; + lit.value[2159U] = 0U; + lit.value[2160U] = 0U; + lit.value[2161U] = 0U; + lit.value[2162U] = 0U; + lit.value[2163U] = 0U; + lit.value[2164U] = 0U; + lit.value[2165U] = 0U; + lit.value[2166U] = 0U; + lit.value[2167U] = 0U; + lit.value[2168U] = 0U; + lit.value[2169U] = 0U; + lit.value[2170U] = 0U; + lit.value[2171U] = 0U; + lit.value[2172U] = 0U; + lit.value[2173U] = 0U; + lit.value[2174U] = 0U; + lit.value[2175U] = 0U; + lit.value[2176U] = 0U; + lit.value[2177U] = 0U; + lit.value[2178U] = 0U; + lit.value[2179U] = 0U; + lit.value[2180U] = 0U; + lit.value[2181U] = 0U; + lit.value[2182U] = 0U; + lit.value[2183U] = 0U; + lit.value[2184U] = 0U; + lit.value[2185U] = 0U; + lit.value[2186U] = 0U; + lit.value[2187U] = 0U; + lit.value[2188U] = 0U; + lit.value[2189U] = 0U; + lit.value[2190U] = 0U; + lit.value[2191U] = 0U; + lit.value[2192U] = 0U; + lit.value[2193U] = 0U; + lit.value[2194U] = 0U; + lit.value[2195U] = 0U; + lit.value[2196U] = 0U; + lit.value[2197U] = 0U; + lit.value[2198U] = 0U; + lit.value[2199U] = 0U; + lit.value[2200U] = 0U; + lit.value[2201U] = 0U; + lit.value[2202U] = 0U; + lit.value[2203U] = 0U; + lit.value[2204U] = 0U; + lit.value[2205U] = 0U; + lit.value[2206U] = 0U; + lit.value[2207U] = 0U; + lit.value[2208U] = 0U; + lit.value[2209U] = 0U; + lit.value[2210U] = 0U; + lit.value[2211U] = 0U; + lit.value[2212U] = 0U; + lit.value[2213U] = 0U; + lit.value[2214U] = 0U; + lit.value[2215U] = 0U; + lit.value[2216U] = 0U; + lit.value[2217U] = 0U; + lit.value[2218U] = 0U; + lit.value[2219U] = 0U; + lit.value[2220U] = 0U; + lit.value[2221U] = 0U; + lit.value[2222U] = 0U; + lit.value[2223U] = 0U; + lit.value[2224U] = 0U; + lit.value[2225U] = 0U; + lit.value[2226U] = 0U; + lit.value[2227U] = 0U; + lit.value[2228U] = 0U; + lit.value[2229U] = 0U; + lit.value[2230U] = 0U; + lit.value[2231U] = 0U; + lit.value[2232U] = 0U; + lit.value[2233U] = 0U; + lit.value[2234U] = 0U; + lit.value[2235U] = 0U; + lit.value[2236U] = 0U; + lit.value[2237U] = 0U; + lit.value[2238U] = 0U; + lit.value[2239U] = 0U; + lit.value[2240U] = 0U; + lit.value[2241U] = 0U; + lit.value[2242U] = 0U; + lit.value[2243U] = 0U; + lit.value[2244U] = 0U; + lit.value[2245U] = 0U; + lit.value[2246U] = 0U; + lit.value[2247U] = 0U; + lit.value[2248U] = 0U; + lit.value[2249U] = 0U; + lit.value[2250U] = 0U; + lit.value[2251U] = 0U; + lit.value[2252U] = 0U; + lit.value[2253U] = 0U; + lit.value[2254U] = 0U; + lit.value[2255U] = 0U; + lit.value[2256U] = 0U; + lit.value[2257U] = 0U; + lit.value[2258U] = 0U; + lit.value[2259U] = 0U; + lit.value[2260U] = 0U; + lit.value[2261U] = 0U; + lit.value[2262U] = 0U; + lit.value[2263U] = 0U; + lit.value[2264U] = 0U; + lit.value[2265U] = 0U; + lit.value[2266U] = 0U; + lit.value[2267U] = 0U; + lit.value[2268U] = 0U; + lit.value[2269U] = 0U; + lit.value[2270U] = 0U; + lit.value[2271U] = 0U; + lit.value[2272U] = 0U; + lit.value[2273U] = 0U; + lit.value[2274U] = 0U; + lit.value[2275U] = 0U; + lit.value[2276U] = 0U; + lit.value[2277U] = 0U; + lit.value[2278U] = 0U; + lit.value[2279U] = 0U; + lit.value[2280U] = 0U; + lit.value[2281U] = 0U; + lit.value[2282U] = 0U; + lit.value[2283U] = 0U; + lit.value[2284U] = 0U; + lit.value[2285U] = 0U; + lit.value[2286U] = 0U; + lit.value[2287U] = 0U; + lit.value[2288U] = 0U; + lit.value[2289U] = 0U; + lit.value[2290U] = 0U; + lit.value[2291U] = 0U; + lit.value[2292U] = 0U; + lit.value[2293U] = 0U; + lit.value[2294U] = 0U; + lit.value[2295U] = 0U; + lit.value[2296U] = 0U; + lit.value[2297U] = 0U; + lit.value[2298U] = 0U; + lit.value[2299U] = 0U; + lit.value[2300U] = 0U; + lit.value[2301U] = 0U; + lit.value[2302U] = 0U; + lit.value[2303U] = 0U; + lit.value[2304U] = 0U; + lit.value[2305U] = 0U; + lit.value[2306U] = 0U; + lit.value[2307U] = 0U; + lit.value[2308U] = 0U; + lit.value[2309U] = 0U; + lit.value[2310U] = 0U; + lit.value[2311U] = 0U; + lit.value[2312U] = 0U; + lit.value[2313U] = 0U; + lit.value[2314U] = 0U; + lit.value[2315U] = 0U; + lit.value[2316U] = 0U; + lit.value[2317U] = 0U; + lit.value[2318U] = 0U; + lit.value[2319U] = 0U; + lit.value[2320U] = 0U; + lit.value[2321U] = 0U; + lit.value[2322U] = 0U; + lit.value[2323U] = 0U; + lit.value[2324U] = 0U; + lit.value[2325U] = 0U; + lit.value[2326U] = 0U; + lit.value[2327U] = 0U; + lit.value[2328U] = 0U; + lit.value[2329U] = 0U; + lit.value[2330U] = 0U; + lit.value[2331U] = 0U; + lit.value[2332U] = 0U; + lit.value[2333U] = 0U; + lit.value[2334U] = 0U; + lit.value[2335U] = 0U; + lit.value[2336U] = 0U; + lit.value[2337U] = 0U; + lit.value[2338U] = 0U; + lit.value[2339U] = 0U; + lit.value[2340U] = 0U; + lit.value[2341U] = 0U; + lit.value[2342U] = 0U; + lit.value[2343U] = 0U; + lit.value[2344U] = 0U; + lit.value[2345U] = 0U; + lit.value[2346U] = 0U; + lit.value[2347U] = 0U; + lit.value[2348U] = 0U; + lit.value[2349U] = 0U; + lit.value[2350U] = 0U; + lit.value[2351U] = 0U; + lit.value[2352U] = 0U; + lit.value[2353U] = 0U; + lit.value[2354U] = 0U; + lit.value[2355U] = 0U; + lit.value[2356U] = 0U; + lit.value[2357U] = 0U; + lit.value[2358U] = 0U; + lit.value[2359U] = 0U; + lit.value[2360U] = 0U; + lit.value[2361U] = 0U; + lit.value[2362U] = 0U; + lit.value[2363U] = 0U; + lit.value[2364U] = 0U; + lit.value[2365U] = 0U; + lit.value[2366U] = 0U; + lit.value[2367U] = 0U; + lit.value[2368U] = 0U; + lit.value[2369U] = 0U; + lit.value[2370U] = 0U; + lit.value[2371U] = 0U; + lit.value[2372U] = 0U; + lit.value[2373U] = 0U; + lit.value[2374U] = 0U; + lit.value[2375U] = 0U; + lit.value[2376U] = 0U; + lit.value[2377U] = 0U; + lit.value[2378U] = 0U; + lit.value[2379U] = 0U; + lit.value[2380U] = 0U; + lit.value[2381U] = 0U; + lit.value[2382U] = 0U; + lit.value[2383U] = 0U; + lit.value[2384U] = 0U; + lit.value[2385U] = 0U; + lit.value[2386U] = 0U; + lit.value[2387U] = 0U; + lit.value[2388U] = 0U; + lit.value[2389U] = 0U; + lit.value[2390U] = 0U; + lit.value[2391U] = 0U; + lit.value[2392U] = 0U; + lit.value[2393U] = 0U; + lit.value[2394U] = 0U; + lit.value[2395U] = 0U; + lit.value[2396U] = 0U; + lit.value[2397U] = 0U; + lit.value[2398U] = 0U; + lit.value[2399U] = 0U; + return lit; +} + typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s { uint8_t value[1088U]; } libcrux_ml_kem_mlkem768_MlKem768Ciphertext; @@ -237,15 +2661,15 @@ typedef struct libcrux_ml_kem_types_MlKemPublicKey_30_s { /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPublicKey)#16} +libcrux_ml_kem::types::MlKemPublicKey)#19} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_5a +A monomorphic instance of libcrux_ml_kem.types.from_5f with const generics - SIZE= 1184 */ static inline libcrux_ml_kem_types_MlKemPublicKey_30 -libcrux_ml_kem_types_from_5a_d0(uint8_t value[1184U]) { +libcrux_ml_kem_types_from_5f_d0(uint8_t value[1184U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[1184U]; memcpy(copy_of_value, value, (size_t)1184U * sizeof(uint8_t)); @@ -254,15 +2678,6 @@ libcrux_ml_kem_types_from_5a_d0(uint8_t value[1184U]) { return lit; } -/** -A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey -with const generics -- $2400size_t -*/ -typedef struct libcrux_ml_kem_types_MlKemPrivateKey_d9_s { - uint8_t value[2400U]; -} libcrux_ml_kem_types_MlKemPrivateKey_d9; - typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s { libcrux_ml_kem_types_MlKemPrivateKey_d9 sk; libcrux_ml_kem_types_MlKemPublicKey_30 pk; @@ -287,15 +2702,15 @@ libcrux_ml_kem_types_from_3a_74(libcrux_ml_kem_types_MlKemPrivateKey_d9 sk, /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemPrivateKey)#9} +libcrux_ml_kem::types::MlKemPrivateKey)#12} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_7f +A monomorphic instance of libcrux_ml_kem.types.from_9a with const generics - SIZE= 2400 */ static inline libcrux_ml_kem_types_MlKemPrivateKey_d9 -libcrux_ml_kem_types_from_7f_28(uint8_t value[2400U]) { +libcrux_ml_kem_types_from_9a_28(uint8_t value[2400U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[2400U]; memcpy(copy_of_value, value, (size_t)2400U * sizeof(uint8_t)); @@ -351,15 +2766,15 @@ typedef struct tuple_c2_s { /** This function found in impl {(core::convert::From<@Array> for -libcrux_ml_kem::types::MlKemCiphertext)#2} +libcrux_ml_kem::types::MlKemCiphertext)#5} */ /** -A monomorphic instance of libcrux_ml_kem.types.from_01 +A monomorphic instance of libcrux_ml_kem.types.from_00 with const generics - SIZE= 1088 */ static inline libcrux_ml_kem_mlkem768_MlKem768Ciphertext -libcrux_ml_kem_types_from_01_80(uint8_t value[1088U]) { +libcrux_ml_kem_types_from_00_80(uint8_t value[1088U]) { /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_value[1088U]; memcpy(copy_of_value, value, (size_t)1088U * sizeof(uint8_t)); @@ -381,6 +2796,25 @@ static inline uint8_t *libcrux_ml_kem_types_as_slice_fd_d0( return self->value; } +/** +A monomorphic instance of libcrux_ml_kem.utils.prf_input_inc +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE uint8_t libcrux_ml_kem_utils_prf_input_inc_e0( + uint8_t (*prf_inputs)[33U], uint8_t domain_separator) { + uint8_t ret[3U][33U]; + core_array___core__clone__Clone_for__Array_T__N___20__clone( + (size_t)3U, prf_inputs, ret, uint8_t[33U], void *); + LowStar_Ignore_ignore(ret, uint8_t[3U][33U], void *); + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U; + } + return domain_separator; +} + /** Pad the `slice` with `0`s at the end. */ @@ -421,14 +2855,14 @@ static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_b6( /** This function found in impl {(core::convert::AsRef<@Slice> for -libcrux_ml_kem::types::MlKemCiphertext)#1} +libcrux_ml_kem::types::MlKemCiphertext)#4} */ /** -A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +A monomorphic instance of libcrux_ml_kem.types.as_ref_43 with const generics - SIZE= 1088 */ -static inline Eurydice_slice libcrux_ml_kem_types_as_ref_00_80( +static inline Eurydice_slice libcrux_ml_kem_types_as_ref_43_80( libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t); } @@ -471,6 +2905,45 @@ static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_24( memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); } +typedef struct Eurydice_slice_uint8_t_x4_s { + Eurydice_slice fst; + Eurydice_slice snd; + Eurydice_slice thd; + Eurydice_slice f3; +} Eurydice_slice_uint8_t_x4; + +typedef struct Eurydice_slice_uint8_t_x2_s { + Eurydice_slice fst; + Eurydice_slice snd; +} Eurydice_slice_uint8_t_x2; + +/** +A monomorphic instance of libcrux_ml_kem.types.unpack_private_key +with const generics +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static inline Eurydice_slice_uint8_t_x4 +libcrux_ml_kem_types_unpack_private_key_b4(Eurydice_slice private_key) { + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + private_key, (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + return (CLITERAL(Eurydice_slice_uint8_t_x4){.fst = ind_cpa_secret_key, + .snd = ind_cpa_public_key, + .thd = ind_cpa_public_key_hash, + .f3 = implicit_rejection_value}); +} + /** A monomorphic instance of core.result.Result with types int16_t[16size_t], core_array_TryFromSliceError @@ -539,11 +3012,6 @@ static inline void unwrap_26_68(Result_15 self, uint8_t ret[8U]) { } } -typedef struct Eurydice_slice_uint8_t_x2_s { - Eurydice_slice fst; - Eurydice_slice snd; -} Eurydice_slice_uint8_t_x2; - typedef struct Eurydice_slice_uint8_t_1size_t__x2_s { Eurydice_slice fst[1U]; Eurydice_slice snd[1U]; diff --git a/libcrux-ml-kem/cg/libcrux_ct_ops.h b/libcrux-ml-kem/cg/libcrux_ct_ops.h index 244aa8e45..61a11d366 100644 --- a/libcrux-ml-kem/cg/libcrux_ct_ops.h +++ b/libcrux-ml-kem/cg/libcrux_ct_ops.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d + * Libcrux: 8fa4c2d98c5fd5a203b5a37a971a46f2296646d9 */ #ifndef __libcrux_ct_ops_H diff --git a/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h index 7a5dafa68..3281a201c 100644 --- a/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d + * Libcrux: 8fa4c2d98c5fd5a203b5a37a971a46f2296646d9 */ #ifndef __libcrux_mlkem768_avx2_H @@ -22,9 +22,7 @@ extern "C" { #include "intrinsics/libcrux_intrinsics_avx2.h" #include "libcrux_core.h" #include "libcrux_ct_ops.h" -#include "libcrux_mlkem768_avx2_types.h" #include "libcrux_mlkem768_portable.h" -#include "libcrux_mlkem768_portable_types.h" #include "libcrux_sha3_avx2.h" #include "libcrux_sha3_portable.h" @@ -46,6 +44,8 @@ static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_avx2_H( memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); } +typedef __m256i libcrux_ml_kem_vector_avx2_SIMD256Vector; + KRML_ATTRIBUTE_TARGET("avx2") static KRML_MUSTINLINE __m256i libcrux_ml_kem_vector_avx2_vec_zero(void) { return libcrux_intrinsics_avx2_mm256_setzero_si256(); @@ -1830,6 +1830,15 @@ static KRML_MUSTINLINE size_t libcrux_ml_kem_vector_avx2_rej_sample_09( return libcrux_ml_kem_vector_avx2_sampling_rejection_sample(input, output); } +/** +A monomorphic instance of libcrux_ml_kem.polynomial.PolynomialRingElement +with types libcrux_ml_kem_vector_avx2_SIMD256Vector + +*/ +typedef struct libcrux_ml_kem_polynomial_PolynomialRingElement_f6_s { + __m256i coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement_f6; + /** This function found in impl {libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, @@ -1932,6 +1941,16 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_deserialize_secret_key_ab( (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f6)); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types +libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_63_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 secret_as_ntt[3U]; +} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_63; + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u.closure with types @@ -2651,11 +2670,12 @@ libcrux_ml_kem_serialize_deserialize_then_decompress_5_61( A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 3 - COMPRESSION_FACTOR= 4 */ KRML_ATTRIBUTE_TARGET("avx2") static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f6 -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_42( +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_ed( Eurydice_slice serialized) { return libcrux_ml_kem_serialize_deserialize_then_decompress_4_61(serialized); } @@ -3043,7 +3063,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_decrypt_unpacked_2f( d_u) */ ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement_f6 v = - libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_42( + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_ed( Eurydice_array_to_subslice_from( (size_t)1088U, /* v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) */ @@ -3133,6 +3153,18 @@ static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_avx2_PRF_a9_41( libcrux_ml_kem_hash_functions_avx2_PRF_9e(input, ret); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.unpacked.IndCpaPublicKeyUnpacked with types +libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 t_as_ntt[3U]; + uint8_t seed_for_A[32U]; + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 A[3U][3U]; +} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63; + /** This function found in impl {(core::default::Default for libcrux_ml_kem::ind_cpa::unpacked::IndCpaPublicKeyUnpackedt_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, (size_t)1152U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____1)[3U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + libcrux_ml_kem_matrix_sample_matrix_A_6c(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_fa( + Eurydice_slice public_key) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 + unpacked_public_key = libcrux_ml_kem_ind_cpa_unpacked_default_8d_ab(); + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_mut_fa(public_key, + &unpacked_public_key); + return unpacked_public_key; +} + /** A monomorphic instance of K. with types libcrux_ml_kem_polynomial_PolynomialRingElement @@ -3938,13 +4018,8 @@ libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_b4( for (size_t i = (size_t)0U; i < (size_t)3U; i++) { memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)); } - uint8_t _prf_inputs_init[3U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)3U * sizeof(uint8_t[33U])); - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U; - } + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; libcrux_ml_kem_hash_functions_avx2_PRFxN_a9_41(prf_inputs, prf_outputs); for (size_t i = (size_t)0U; i < (size_t)3U; i++) { @@ -4028,13 +4103,8 @@ libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_b4(uint8_t prf_input[33U], for (size_t i = (size_t)0U; i < (size_t)3U; i++) { memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)); } - uint8_t _prf_inputs_init[3U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)3U * sizeof(uint8_t[33U])); - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U; - } + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; libcrux_ml_kem_hash_functions_avx2_PRFxN_a9_41(prf_inputs, prf_outputs); for (size_t i = (size_t)0U; i < (size_t)3U; i++) { @@ -4885,12 +4955,13 @@ libcrux_ml_kem_serialize_compress_then_serialize_5_61( A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 3 - COMPRESSION_FACTOR= 4 - OUT_LEN= 128 */ KRML_ATTRIBUTE_TARGET("avx2") static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_78( +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_ed( libcrux_ml_kem_polynomial_PolynomialRingElement_f6 re, Eurydice_slice out) { libcrux_ml_kem_serialize_compress_then_serialize_4_61(re, out); } @@ -4974,7 +5045,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_encrypt_unpacked_74( uint8_t)); /* c_2 := Encode_{dv}(Compress_q(v,d_v)) */ libcrux_ml_kem_polynomial_PolynomialRingElement_f6 uu____6 = v; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_78( + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_ed( uu____6, Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, uint8_t, size_t)); memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); @@ -5002,30 +5073,17 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_encrypt_74( Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, uint8_t ret[1088U]) { libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 - unpacked_public_key = libcrux_ml_kem_ind_cpa_unpacked_default_8d_ab(); - libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_ab( - Eurydice_slice_subslice_to(/* tˆ := Decode_12(pk) */ - public_key, (size_t)1152U, uint8_t, size_t), - unpacked_public_key.t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 - do for j from 0 to k − 1 do AˆT[i][j] := - Parse(XOF(ρ, i, j)) end for end for */ - public_key, (size_t)1152U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____0)[3U] = - unpacked_public_key.A; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_b6(seed, ret0); - libcrux_ml_kem_matrix_sample_matrix_A_6c(uu____0, ret0, false); - libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 *uu____1 = + unpacked_public_key = + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_fa(public_key); + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 *uu____0 = &unpacked_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_message[32U]; memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - uint8_t ret1[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_unpacked_74(uu____1, copy_of_message, - randomness, ret1); - memcpy(ret, ret1, (size_t)1088U * sizeof(uint8_t)); + uint8_t ret0[1088U]; + libcrux_ml_kem_ind_cpa_encrypt_unpacked_74(uu____0, copy_of_message, + randomness, ret0); + memcpy(ret, ret0, (size_t)1088U * sizeof(uint8_t)); } /** @@ -5075,20 +5133,13 @@ KRML_ATTRIBUTE_TARGET("avx2") static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_a1( libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), - (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; libcrux_ml_kem_ind_cpa_decrypt_2f(ind_cpa_secret_key, ciphertext->value, decrypted); @@ -5103,29 +5154,29 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_a1( uint8_t hashed[64U]; libcrux_ml_kem_hash_functions_avx2_G_a9_e0( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1120U]; libcrux_ml_kem_utils_into_padded_array_15(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_80(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; libcrux_ml_kem_hash_functions_avx2_PRF_a9_41( Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_74(uu____5, copy_of_decrypted, + libcrux_ml_kem_ind_cpa_encrypt_74(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; libcrux_ml_kem_variant_kdf_d8_ae( @@ -5136,7 +5187,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_a1( libcrux_ml_kem_variant_kdf_d8_ae(shared_secret0, ciphertext, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_80(ciphertext), + libcrux_ml_kem_types_as_ref_43_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -5311,7 +5362,7 @@ static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_encapsulate_70( uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = - libcrux_ml_kem_types_from_01_80(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_80(copy_of_ciphertext); uint8_t shared_secret_array[32U]; libcrux_ml_kem_variant_kdf_d8_ae(shared_secret, &ciphertext0, shared_secret_array); @@ -5712,39 +5763,35 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_public_key_ed( } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_avx2_SIMD256Vector, -libcrux_ml_kem_hash_functions_avx2_Simd256Hash, libcrux_ml_kem_variant_MlKem + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics - K= 3 - PRIVATE_KEY_SIZE= 1152 - PUBLIC_KEY_SIZE= 1184 - RANKED_BYTES_PER_RING_ELEMENT= 1152 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 */ KRML_ATTRIBUTE_TARGET("avx2") -static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 -libcrux_ml_kem_ind_cpa_generate_keypair_bb(Eurydice_slice key_generation_seed) { - libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_63 private_key = - libcrux_ml_kem_ind_cpa_unpacked_default_1a_ab(); - libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 public_key = - libcrux_ml_kem_ind_cpa_unpacked_default_8d_ab(); - libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_22( - key_generation_seed, &private_key, &public_key); +static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_8c( + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 *public_key, + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_63 *private_key) { uint8_t public_key_serialized[1184U]; libcrux_ml_kem_ind_cpa_serialize_public_key_ed(/* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ - public_key.t_as_ntt, + public_key->t_as_ntt, Eurydice_array_to_slice( (size_t)32U, - public_key.seed_for_A, + public_key->seed_for_A, uint8_t), public_key_serialized); uint8_t secret_key_serialized[1152U]; libcrux_ml_kem_ind_cpa_serialize_secret_key_ed(/* sk := Encode_12(sˆ mod^{+}q) */ - private_key.secret_as_ntt, + private_key->secret_as_ntt, secret_key_serialized); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[1152U]; @@ -5763,19 +5810,44 @@ libcrux_ml_kem_ind_cpa_generate_keypair_bb(Eurydice_slice key_generation_seed) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_avx2_Simd256Hash, libcrux_ml_kem_variant_MlKem +with const generics +- K= 3 +- PRIVATE_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_generate_keypair_bb(Eurydice_slice key_generation_seed) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_63 private_key = + libcrux_ml_kem_ind_cpa_unpacked_default_1a_ab(); + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 public_key = + libcrux_ml_kem_ind_cpa_unpacked_default_8d_ab(); + libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_22( + key_generation_seed, &private_key, &public_key); + return libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_8c(&public_key, + &private_key); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics - K= 3 - SERIALIZED_KEY_LEN= 2400 */ KRML_ATTRIBUTE_TARGET("avx2") -static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_ae( +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_ae( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( @@ -5784,7 +5856,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_ae( uint8_t), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( @@ -5794,13 +5866,14 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_ae( public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - libcrux_ml_kem_hash_functions_avx2_H_a9_e0(public_key, ret0); + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t); + uint8_t ret[32U]; + libcrux_ml_kem_hash_functions_avx2_H_a9_e0(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( @@ -5809,6 +5882,22 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_ae( uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), uint8_t), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 3 +- SERIALIZED_KEY_LEN= 2400 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_ae( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_ae( + private_key, public_key, implicit_rejection_value, out); memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } @@ -5851,18 +5940,15 @@ libcrux_ml_kem_ind_cca_generate_keypair_d6(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_d9 private_key = - libcrux_ml_kem_types_from_7f_28(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_28(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_d9 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1184U]; memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_74( - uu____2, libcrux_ml_kem_types_from_5a_d0(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_d0(copy_of_public_key)); } -/** - Portable generate key pair. -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.generate_keypair_avx2 with const @@ -5980,20 +6066,13 @@ KRML_ATTRIBUTE_TARGET("avx2") static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_a10( libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), - (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; libcrux_ml_kem_ind_cpa_decrypt_2f(ind_cpa_secret_key, ciphertext->value, decrypted); @@ -6008,29 +6087,29 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_a10( uint8_t hashed[64U]; libcrux_ml_kem_hash_functions_avx2_G_a9_e0( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1120U]; libcrux_ml_kem_utils_into_padded_array_15(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_80(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; libcrux_ml_kem_hash_functions_avx2_PRF_a9_41( Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_74(uu____5, copy_of_decrypted, + libcrux_ml_kem_ind_cpa_encrypt_74(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; libcrux_ml_kem_variant_kdf_33_ae( @@ -6041,7 +6120,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_a10( libcrux_ml_kem_variant_kdf_33_ae(shared_secret0, ciphertext, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_80(ciphertext), + libcrux_ml_kem_types_as_ref_43_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -6200,7 +6279,7 @@ static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_encapsulate_700( uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = - libcrux_ml_kem_types_from_01_80(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_80(copy_of_ciphertext); uint8_t shared_secret_array[32U]; libcrux_ml_kem_variant_kdf_33_ae(shared_secret, &ciphertext0, shared_secret_array); @@ -6392,34 +6471,8 @@ libcrux_ml_kem_ind_cpa_generate_keypair_bb0( libcrux_ml_kem_ind_cpa_unpacked_default_8d_ab(); libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_220( key_generation_seed, &private_key, &public_key); - uint8_t public_key_serialized[1184U]; - libcrux_ml_kem_ind_cpa_serialize_public_key_ed(/* pk := (Encode_12(tˆ - mod^{+}q) || ρ) */ - public_key.t_as_ntt, - Eurydice_array_to_slice( - (size_t)32U, - public_key.seed_for_A, - uint8_t), - public_key_serialized); - uint8_t secret_key_serialized[1152U]; - libcrux_ml_kem_ind_cpa_serialize_secret_key_ed(/* sk := Encode_12(sˆ mod^{+}q) - */ - private_key.secret_as_ntt, - secret_key_serialized); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_secret_key_serialized[1152U]; - memcpy(copy_of_secret_key_serialized, secret_key_serialized, - (size_t)1152U * sizeof(uint8_t)); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_public_key_serialized[1184U]; - memcpy(copy_of_public_key_serialized, public_key_serialized, - (size_t)1184U * sizeof(uint8_t)); - libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; - memcpy(lit.fst, copy_of_secret_key_serialized, - (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, copy_of_public_key_serialized, - (size_t)1184U * sizeof(uint8_t)); - return lit; + return libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_8c(&public_key, + &private_key); } /** @@ -6461,13 +6514,13 @@ libcrux_ml_kem_ind_cca_generate_keypair_d60(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_d9 private_key = - libcrux_ml_kem_types_from_7f_28(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_28(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_d9 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1184U]; memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_74( - uu____2, libcrux_ml_kem_types_from_5a_d0(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_d0(copy_of_public_key)); } /** @@ -6529,17 +6582,15 @@ libcrux_ml_kem_mlkem768_avx2_kyber_generate_key_pair(uint8_t randomness[64U]) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash with const generics - K= 3 - SECRET_KEY_SIZE= 2400 -- CIPHERTEXT_SIZE= 1088 */ KRML_ATTRIBUTE_TARGET("avx2") -static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_12( - libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_only_ae( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { uint8_t t[32U]; libcrux_ml_kem_hash_functions_avx2_H_a9_e0( Eurydice_array_to_subslice2(/* Eurydice can't access values directly on @@ -6556,6 +6607,21 @@ static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_12( (size_t)32U, t, &expected, uint8_t, uint8_t, bool); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_avx2_Simd256Hash +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CIPHERTEXT_SIZE= 1088 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_12( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_ae(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.validate_private_key_avx2 with const @@ -6603,6 +6669,32 @@ static inline bool libcrux_ml_kem_mlkem768_avx2_validate_private_key( private_key, ciphertext); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.avx2.validate_private_key_only with const +generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE bool +libcrux_ml_kem_ind_cca_instantiations_avx2_validate_private_key_only_41( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_ae(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static inline bool libcrux_ml_kem_mlkem768_avx2_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return libcrux_ml_kem_ind_cca_instantiations_avx2_validate_private_key_only_41( + private_key); +} + /** A monomorphic instance of libcrux_ml_kem.serialize.deserialize_ring_elements_reduced_out.closure with @@ -6712,6 +6804,34 @@ static inline bool libcrux_ml_kem_mlkem768_avx2_validate_public_key( public_key->value); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.MlKemPrivateKeyUnpacked with types +libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_63_s { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_63 + ind_cpa_private_key; + uint8_t implicit_rejection_value[32U]; +} libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_63; + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.MlKemPublicKeyUnpacked +with types libcrux_ml_kem_vector_avx2_SIMD256Vector +with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_63_s { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 ind_cpa_public_key; + uint8_t public_key_hash[32U]; +} libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_63; + +typedef struct libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked_s { + libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_63 private_key; + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_63 public_key; +} libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked; + /** A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.decapsulate with types libcrux_ml_kem_vector_avx2_SIMD256Vector, @@ -6768,7 +6888,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_decapsulate_12( Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_00_80(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret[32U]; libcrux_ml_kem_hash_functions_avx2_PRF_a9_41( @@ -6784,7 +6904,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_decapsulate_12( uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t selector = libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time( - libcrux_ml_kem_types_as_ref_00_80(ciphertext), + libcrux_ml_kem_types_as_ref_43_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t)); uint8_t ret0[32U]; libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( @@ -6824,9 +6944,6 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_unpacked_decapsulate_avx2_35( libcrux_ml_kem_ind_cca_unpacked_decapsulate_12(key_pair, ciphertext, ret); } -/** - Unpacked decapsulate -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.unpacked.decapsulate with const @@ -6929,7 +7046,7 @@ static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_unpacked_encapsulate_70( uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = - libcrux_ml_kem_types_from_01_80(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_80(copy_of_ciphertext); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_shared_secret_array[32U]; memcpy(copy_of_shared_secret_array, shared_secret_array, @@ -6972,9 +7089,6 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_unpacked_encapsulate_avx2_cd( copy_of_randomness); } -/** - Unpacked encapsulate -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.unpacked.encapsulate with const @@ -7192,9 +7306,6 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_unpacked_generate_keypair_avx2_c6( libcrux_ml_kem_ind_cca_unpacked_generate_keypair_d6(copy_of_randomness, out); } -/** - Generate a key pair -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.unpacked.generate_keypair with const @@ -7223,7 +7334,7 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_unpacked_generate_keypair_c6( Generate ML-KEM 768 Key Pair in "unpacked" form. */ KRML_ATTRIBUTE_TARGET("avx2") -static inline void libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair( +static inline void libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair_mut( uint8_t randomness[64U], libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *key_pair) { /* Passing arrays by value in Rust generates a copy in C */ @@ -7339,6 +7450,22 @@ static KRML_MUSTINLINE .public_key = libcrux_ml_kem_ind_cca_unpacked_default_09_ab()}); } +/** + Generate ML-KEM 768 Key Pair in "unpacked" form. +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static inline libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked +libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair( + uint8_t randomness[64U]) { + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked key_pair = + libcrux_ml_kem_ind_cca_unpacked_default_53_ab(); + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair_mut(uu____0, + &key_pair); + return key_pair; +} + /** Create a new, empty unpacked key. */ @@ -7358,36 +7485,409 @@ libcrux_ml_kem_mlkem768_avx2_unpacked_init_public_key(void) { } /** -This function found in impl -{libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@1]#3} -*/ -/** -A monomorphic instance of -libcrux_ml_kem.ind_cca.unpacked.serialized_public_key_mut_30 with types -libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof.closure +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics - K= 3 -- RANKED_BYTES_PER_RING_ELEMENT= 1152 -- PUBLIC_KEY_SIZE= 1184 */ KRML_ATTRIBUTE_TARGET("avx2") -static KRML_MUSTINLINE void -libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_30_ed( - libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_63 *self, - libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { - libcrux_ml_kem_ind_cpa_serialize_public_key_mut_ed( - self->ind_cpa_public_key.t_as_ntt, - Eurydice_array_to_slice((size_t)32U, self->ind_cpa_public_key.seed_for_A, - uint8_t), - serialized->value); +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f6 +libcrux_ml_kem_sampling_sample_from_xof_closure_b3(int16_t s[272U]) { + return libcrux_ml_kem_polynomial_from_i16_array_ef_61( + Eurydice_array_to_subslice2(s, (size_t)0U, (size_t)256U, int16_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE void libcrux_ml_kem_sampling_sample_from_xof_b3( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_seeds[3U][34U]; + memcpy(copy_of_seeds, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_hash_functions_portable_PortableHash_88 xof_state = + libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_final_f1_e0( + copy_of_seeds); + uint8_t randomness0[3U][504U]; + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_first_three_blocks_f1_e0( + &xof_state, randomness0); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness0[3U][504U]; + memcpy(copy_of_randomness0, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_ed( + copy_of_randomness0, sampled_coefficients, out); + /* Requiring more than 5 blocks to sample a ring element should be very + * unlikely according to: https://eprint.iacr.org/2023/708.pdf To avoid + * failing here, we squeeze more blocks out of the state until we have enough. + */ + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_next_block_f1_e0( + &xof_state, randomness); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[3U][168U]; + memcpy(copy_of_randomness, randomness, + (size_t)3U * sizeof(uint8_t[168U])); + done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_ed0( + copy_of_randomness, sampled_coefficients, out); + } + } + /* Passing arrays by value in Rust generates a copy in C */ + int16_t copy_of_out[3U][272U]; + memcpy(copy_of_out, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 ret0[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + ret0[i] = + libcrux_ml_kem_sampling_sample_from_xof_closure_b3(copy_of_out[i]); + } + memcpy( + ret, ret0, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f6)); +} + +/** +A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE void libcrux_ml_kem_matrix_sample_matrix_A_b3( + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 (*A_transpose)[3U], + uint8_t seed[34U], bool transpose) { + for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) { + size_t i1 = i0; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_seed[34U]; + memcpy(copy_of_seed, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + memcpy(seeds[i], copy_of_seed, (size_t)34U * sizeof(uint8_t)); + } + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t j = i; + seeds[j][32U] = (uint8_t)i1; + seeds[j][33U] = (uint8_t)j; + } + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_seeds[3U][34U]; + memcpy(copy_of_seeds, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 sampled[3U]; + libcrux_ml_kem_sampling_sample_from_xof_b3(copy_of_seeds, sampled); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement_f6), + libcrux_ml_kem_polynomial_PolynomialRingElement_f6); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 sample = sampled[j]; + if (/* A[i][j] = A_transpose[j][i] */ transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + } + } +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key_mut +with types libcrux_ml_kem_vector_avx2_SIMD256Vector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cpa_build_unpacked_public_key_mut_bf( + Eurydice_slice public_key, + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_63 + *unpacked_public_key) { + Eurydice_slice uu____0 = Eurydice_slice_subslice_to( + /* tˆ := Decode_12(pk) */ public_key, (size_t)1152U, uint8_t, size_t); + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_ab( + uu____0, unpacked_public_key->t_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, (size_t)1152U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f6(*uu____1)[3U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + libcrux_ml_kem_matrix_sample_matrix_A_b3(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.keys_from_private_key +with types libcrux_ml_kem_vector_avx2_SIMD256Vector +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- BYTES_PER_RING_ELEMENT= 1152 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_keys_from_private_key_e2( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *key_pair) { + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)3U, + /* XXX: We need to copy_from_slice here because karamel can't handle the + assignment cf. https://github.com/FStarLang/karamel/pull/491 */ + key_pair->private_key.ind_cpa_private_key.secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_f6); + libcrux_ml_kem_polynomial_PolynomialRingElement_f6 ret[3U]; + libcrux_ml_kem_ind_cpa_deserialize_secret_key_ab(ind_cpa_secret_key, ret); + Eurydice_slice_copy( + uu____1, + Eurydice_array_to_slice( + (size_t)3U, ret, libcrux_ml_kem_polynomial_PolynomialRingElement_f6), + libcrux_ml_kem_polynomial_PolynomialRingElement_f6); + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_mut_bf( + ind_cpa_public_key, &key_pair->public_key.ind_cpa_public_key); + Eurydice_slice_copy( + Eurydice_array_to_slice((size_t)32U, key_pair->public_key.public_key_hash, + uint8_t), + ind_cpa_public_key_hash, uint8_t); + Eurydice_slice_copy( + Eurydice_array_to_slice( + (size_t)32U, key_pair->private_key.implicit_rejection_value, uint8_t), + implicit_rejection_value, uint8_t); + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)32U, key_pair->public_key.ind_cpa_public_key.seed_for_A, uint8_t); + Eurydice_slice_copy(uu____2, + Eurydice_slice_subslice_from( + ind_cpa_public_key, (size_t)1152U, uint8_t, size_t), + uint8_t); } /** -This function found in impl -{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]#4} -*/ -/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.avx2.unpacked.keypair_from_private_key +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- BYTES_PER_RING_ELEMENT= 1152 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_instantiations_avx2_unpacked_keypair_from_private_key_ce( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *key_pair) { + libcrux_ml_kem_ind_cca_unpacked_keys_from_private_key_e2(private_key, + key_pair); +} + +/** + Get an unpacked key from a private key. +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static inline void +libcrux_ml_kem_mlkem768_avx2_unpacked_key_pair_from_private_mut( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *key_pair) { + libcrux_ml_kem_ind_cca_instantiations_avx2_unpacked_keypair_from_private_key_ce( + private_key, key_pair); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]#4} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.serialized_private_key_mut_fc with types +libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_fc_2f( + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *self, + libcrux_ml_kem_types_MlKemPrivateKey_d9 *serialized) { + libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = + libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_8c( + &self->public_key.ind_cpa_public_key, + &self->private_key.ind_cpa_private_key); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t ind_cpa_public_key[1184U]; + memcpy(ind_cpa_public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_d6( + Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t), + Eurydice_array_to_slice((size_t)1184U, ind_cpa_public_key, uint8_t), + Eurydice_array_to_slice( + (size_t)32U, self->private_key.implicit_rejection_value, uint8_t), + serialized->value); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]#4} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.serialized_private_key_fc with types +libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_fc_2f( + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *self) { + libcrux_ml_kem_types_MlKemPrivateKey_d9 sk = + libcrux_ml_kem_types_default_24_28(); + libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_fc_2f(self, &sk); + return sk; +} + +/** + Get the serialized private key. +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static inline libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_mlkem768_avx2_unpacked_key_pair_serialized_private_key( + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *key_pair) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_fc_2f(key_pair); +} + +/** + Get the serialized private key. +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static inline void +libcrux_ml_kem_mlkem768_avx2_unpacked_key_pair_serialized_private_key_mut( + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *key_pair, + libcrux_ml_kem_types_MlKemPrivateKey_d9 *serialized) { + libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_fc_2f(key_pair, + serialized); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@1]#3} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.serialized_30 +with types libcrux_ml_kem_vector_avx2_SIMD256Vector +with const generics +- K= 3 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_ind_cca_unpacked_serialized_30_ed( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_63 *self) { + uint8_t ret[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key_ed( + self->ind_cpa_public_key.t_as_ntt, + Eurydice_array_to_slice((size_t)32U, self->ind_cpa_public_key.seed_for_A, + uint8_t), + ret); + return libcrux_ml_kem_types_from_5f_d0(ret); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]#4} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.serialized_public_key_fc with types +libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics +- K= 3 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_fc_ed( + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *self) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_30_ed(&self->public_key); +} + +KRML_ATTRIBUTE_TARGET("avx2") +static inline libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_mlkem768_avx2_unpacked_key_pair_serialized_public_key( + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *key_pair) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_fc_ed(key_pair); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@1]#3} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.serialized_mut_30 +with types libcrux_ml_kem_vector_avx2_SIMD256Vector +with const generics +- K= 3 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +KRML_ATTRIBUTE_TARGET("avx2") +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_serialized_mut_30_ed( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_63 *self, + libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { + libcrux_ml_kem_ind_cpa_serialize_public_key_mut_ed( + self->ind_cpa_public_key.t_as_ntt, + Eurydice_array_to_slice((size_t)32U, self->ind_cpa_public_key.seed_for_A, + uint8_t), + serialized->value); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]#4} +*/ +/** A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.serialized_public_key_mut_fc with types libcrux_ml_kem_vector_avx2_SIMD256Vector with const generics @@ -7400,16 +7900,13 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_fc_ed( libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *self, libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { - libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_30_ed( - &self->public_key, serialized); + libcrux_ml_kem_ind_cca_unpacked_serialized_mut_30_ed(&self->public_key, + serialized); } -/** - Get the serialized public key. -*/ KRML_ATTRIBUTE_TARGET("avx2") static inline void -libcrux_ml_kem_mlkem768_avx2_unpacked_key_pair_serialized_public_key( +libcrux_ml_kem_mlkem768_avx2_unpacked_key_pair_serialized_public_key_mut( libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked *key_pair, libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_fc_ed(key_pair, @@ -7509,15 +8006,11 @@ static inline void libcrux_ml_kem_mlkem768_avx2_unpacked_public_key( pk[0U] = uu____0; } -/** - Get the serialized public key. -*/ KRML_ATTRIBUTE_TARGET("avx2") static inline void libcrux_ml_kem_mlkem768_avx2_unpacked_serialized_public_key( libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_63 *public_key, libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { - libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_30_ed(public_key, - serialized); + libcrux_ml_kem_ind_cca_unpacked_serialized_mut_30_ed(public_key, serialized); } /** @@ -7564,9 +8057,6 @@ libcrux_ml_kem_ind_cca_unpacked_unpack_public_key_6d( (size_t)32U * sizeof(uint8_t)); } -/** - Get the unpacked public key. -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.unpacked.unpack_public_key_avx2 with @@ -7586,9 +8076,6 @@ libcrux_ml_kem_ind_cca_instantiations_avx2_unpacked_unpack_public_key_avx2_a5( unpacked_public_key); } -/** - Get the unpacked public key. -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.avx2.unpacked.unpack_public_key with const @@ -7629,6 +8116,9 @@ static inline __m256i libcrux_ml_kem_vector_avx2_clone_78(__m256i *self) { return self[0U]; } +typedef libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_63 + libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768PublicKeyUnpacked; + #if defined(__cplusplus) } #endif diff --git a/libcrux-ml-kem/cg/libcrux_mlkem768_avx2_types.h b/libcrux-ml-kem/cg/libcrux_mlkem768_avx2_types.h index fe16c7d0b..b939c9240 100644 --- a/libcrux-ml-kem/cg/libcrux_mlkem768_avx2_types.h +++ b/libcrux-ml-kem/cg/libcrux_mlkem768_avx2_types.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d + * Libcrux: 38837f1aab3f2ae348a0cb53cf44d97652e2c977 */ #ifndef __libcrux_mlkem768_avx2_types_H diff --git a/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h b/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h index a5cfe8f8d..34d13c6e3 100644 --- a/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d + * Libcrux: 8fa4c2d98c5fd5a203b5a37a971a46f2296646d9 */ #ifndef __libcrux_mlkem768_portable_H @@ -21,7 +21,6 @@ extern "C" { #include "eurydice_glue.h" #include "libcrux_core.h" #include "libcrux_ct_ops.h" -#include "libcrux_mlkem768_portable_types.h" #include "libcrux_sha3_portable.h" #define LIBCRUX_ML_KEM_HASH_FUNCTIONS_BLOCK_SIZE ((size_t)168U) @@ -106,6 +105,10 @@ static KRML_MUSTINLINE int16_t libcrux_ml_kem_polynomial_get_zeta(size_t i) { #define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ (62209U) +typedef struct libcrux_ml_kem_vector_portable_vector_type_PortableVector_s { + int16_t elements[16U]; +} libcrux_ml_kem_vector_portable_vector_type_PortableVector; + static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_vector_type_from_i16_array( Eurydice_slice array) { @@ -2544,6 +2547,15 @@ typedef libcrux_ml_kem_types_MlKemPublicKey_30 LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) +/** +A monomorphic instance of libcrux_ml_kem.polynomial.PolynomialRingElement +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector + +*/ +typedef struct libcrux_ml_kem_polynomial_PolynomialRingElement_1d_s { + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement_1d; + /** This function found in impl {libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0, @@ -2644,6 +2656,16 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_deserialize_secret_key_1b( (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_1d)); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d secret_as_ntt[3U]; +} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0; + /** A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u.closure with types @@ -2690,9 +2712,9 @@ generics */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_ef( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_ef( - v); + a); } /** @@ -2761,9 +2783,9 @@ generics */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_c4( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_c4( - v); + a); } /** @@ -3074,9 +3096,9 @@ generics */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_d1( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_d1( - v); + a); } /** @@ -3138,9 +3160,9 @@ generics */ static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_f4( - libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_f4( - v); + a); } /** @@ -3173,10 +3195,11 @@ libcrux_ml_kem_serialize_deserialize_then_decompress_5_8c( A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 - COMPRESSION_FACTOR= 4 */ static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_1d -libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_d0( +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_89( Eurydice_slice serialized) { return libcrux_ml_kem_serialize_deserialize_then_decompress_4_8c(serialized); } @@ -3577,7 +3600,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_decrypt_unpacked_42( d_u) */ ciphertext, u_as_ntt); libcrux_ml_kem_polynomial_PolynomialRingElement_1d v = - libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_d0( + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_89( Eurydice_array_to_subslice_from( (size_t)1088U, /* v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) */ @@ -3663,6 +3686,18 @@ static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_f1_41( libcrux_ml_kem_hash_functions_portable_PRF_9e(input, ret); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.unpacked.IndCpaPublicKeyUnpacked with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_1d t_as_ntt[3U]; + uint8_t seed_for_A[32U]; + libcrux_ml_kem_polynomial_PolynomialRingElement_1d A[3U][3U]; +} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0; + /** This function found in impl {(core::default::Default for libcrux_ml_kem::ind_cpa::unpacked::IndCpaPublicKeyUnpackedt_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 + do for j from 0 to k − 1 do AˆT[i][j] := + Parse(XOF(ρ, i, j)) end for end for */ + public_key, (size_t)1152U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____1)[3U] = + unpacked_public_key->A; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_b6(seed, ret); + libcrux_ml_kem_matrix_sample_matrix_A_2b(uu____1, ret, false); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.build_unpacked_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_3f( + Eurydice_slice public_key) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 + unpacked_public_key = libcrux_ml_kem_ind_cpa_unpacked_default_8d_1b(); + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_mut_3f(public_key, + &unpacked_public_key); + return unpacked_public_key; +} + /** A monomorphic instance of K. with types libcrux_ml_kem_polynomial_PolynomialRingElement @@ -4436,13 +4519,8 @@ libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_3b( for (size_t i = (size_t)0U; i < (size_t)3U; i++) { memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)); } - uint8_t _prf_inputs_init[3U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)3U * sizeof(uint8_t[33U])); - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U; - } + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; libcrux_ml_kem_hash_functions_portable_PRFxN_f1_41(prf_inputs, prf_outputs); for (size_t i = (size_t)0U; i < (size_t)3U; i++) { @@ -4526,13 +4604,8 @@ libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_3b(uint8_t prf_input[33U], for (size_t i = (size_t)0U; i < (size_t)3U; i++) { memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)); } - uint8_t _prf_inputs_init[3U][33U]; - memcpy(_prf_inputs_init, prf_inputs, (size_t)3U * sizeof(uint8_t[33U])); - for (size_t i = (size_t)0U; i < (size_t)3U; i++) { - size_t i0 = i; - prf_inputs[i0][32U] = domain_separator; - domain_separator = (uint32_t)domain_separator + 1U; - } + domain_separator = + libcrux_ml_kem_utils_prf_input_inc_e0(prf_inputs, domain_separator); uint8_t prf_outputs[3U][128U]; libcrux_ml_kem_hash_functions_portable_PRFxN_f1_41(prf_inputs, prf_outputs); for (size_t i = (size_t)0U; i < (size_t)3U; i++) { @@ -5116,11 +5189,12 @@ libcrux_ml_kem_serialize_compress_then_serialize_5_8c( A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 - COMPRESSION_FACTOR= 4 - OUT_LEN= 128 */ static KRML_MUSTINLINE void -libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_ff( +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_6c( libcrux_ml_kem_polynomial_PolynomialRingElement_1d re, Eurydice_slice out) { libcrux_ml_kem_serialize_compress_then_serialize_4_8c(re, out); } @@ -5204,7 +5278,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_encrypt_unpacked_2a( uint8_t)); /* c_2 := Encode_{dv}(Compress_q(v,d_v)) */ libcrux_ml_kem_polynomial_PolynomialRingElement_1d uu____6 = v; - libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_ff( + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_6c( uu____6, Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, (size_t)960U, uint8_t, size_t)); memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); @@ -5232,30 +5306,17 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_encrypt_2a( Eurydice_slice public_key, uint8_t message[32U], Eurydice_slice randomness, uint8_t ret[1088U]) { libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 - unpacked_public_key = libcrux_ml_kem_ind_cpa_unpacked_default_8d_1b(); - libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_1b( - Eurydice_slice_subslice_to(/* tˆ := Decode_12(pk) */ - public_key, (size_t)1152U, uint8_t, size_t), - unpacked_public_key.t_as_ntt); - Eurydice_slice seed = - Eurydice_slice_subslice_from(/* ρ := pk + 12·k·n / 8 for i from 0 to k−1 - do for j from 0 to k − 1 do AˆT[i][j] := - Parse(XOF(ρ, i, j)) end for end for */ - public_key, (size_t)1152U, uint8_t, size_t); - libcrux_ml_kem_polynomial_PolynomialRingElement_1d(*uu____0)[3U] = - unpacked_public_key.A; - uint8_t ret0[34U]; - libcrux_ml_kem_utils_into_padded_array_b6(seed, ret0); - libcrux_ml_kem_matrix_sample_matrix_A_2b(uu____0, ret0, false); - libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 *uu____1 = + unpacked_public_key = + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_3f(public_key); + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 *uu____0 = &unpacked_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_message[32U]; memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); - uint8_t ret1[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_unpacked_2a(uu____1, copy_of_message, - randomness, ret1); - memcpy(ret, ret1, (size_t)1088U * sizeof(uint8_t)); + uint8_t ret0[1088U]; + libcrux_ml_kem_ind_cpa_encrypt_unpacked_2a(uu____0, copy_of_message, + randomness, ret0); + memcpy(ret, ret0, (size_t)1088U * sizeof(uint8_t)); } /** @@ -5303,20 +5364,13 @@ libcrux_ml_kem_variant_MlKem with const generics static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_62( libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), - (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; libcrux_ml_kem_ind_cpa_decrypt_42(ind_cpa_secret_key, ciphertext->value, decrypted); @@ -5331,29 +5385,29 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_62( uint8_t hashed[64U]; libcrux_ml_kem_hash_functions_portable_G_f1_e0( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1120U]; libcrux_ml_kem_utils_into_padded_array_15(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_80(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; libcrux_ml_kem_hash_functions_portable_PRF_f1_41( Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_2a(uu____5, copy_of_decrypted, + libcrux_ml_kem_ind_cpa_encrypt_2a(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; libcrux_ml_kem_variant_kdf_d8_d6( @@ -5364,7 +5418,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_62( libcrux_ml_kem_variant_kdf_d8_d6(shared_secret0, ciphertext, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_80(ciphertext), + libcrux_ml_kem_types_as_ref_43_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -5506,7 +5560,7 @@ static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_encapsulate_ca( uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = - libcrux_ml_kem_types_from_01_80(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_80(copy_of_ciphertext); uint8_t shared_secret_array[32U]; libcrux_ml_kem_variant_kdf_d8_d6(shared_secret, &ciphertext0, shared_secret_array); @@ -5871,38 +5925,34 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_public_key_6c( } /** -A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair -with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, -libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], -libcrux_ml_kem_variant_MlKem with const generics + Serialize the secret key from the unpacked key pair generation. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_unpacked_secret_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics - K= 3 - PRIVATE_KEY_SIZE= 1152 - PUBLIC_KEY_SIZE= 1184 - RANKED_BYTES_PER_RING_ELEMENT= 1152 -- ETA1= 2 -- ETA1_RANDOMNESS_SIZE= 128 */ -static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 -libcrux_ml_kem_ind_cpa_generate_keypair_15(Eurydice_slice key_generation_seed) { - libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 private_key = - libcrux_ml_kem_ind_cpa_unpacked_default_1a_1b(); - libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 public_key = - libcrux_ml_kem_ind_cpa_unpacked_default_8d_1b(); - libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_1c( - key_generation_seed, &private_key, &public_key); +static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_43( + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 *public_key, + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 *private_key) { uint8_t public_key_serialized[1184U]; libcrux_ml_kem_ind_cpa_serialize_public_key_6c(/* pk := (Encode_12(tˆ mod^{+}q) || ρ) */ - public_key.t_as_ntt, + public_key->t_as_ntt, Eurydice_array_to_slice( (size_t)32U, - public_key.seed_for_A, + public_key->seed_for_A, uint8_t), public_key_serialized); uint8_t secret_key_serialized[1152U]; libcrux_ml_kem_ind_cpa_serialize_secret_key_89(/* sk := Encode_12(sˆ mod^{+}q) */ - private_key.secret_as_ntt, + private_key->secret_as_ntt, secret_key_serialized); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_secret_key_serialized[1152U]; @@ -5921,18 +5971,42 @@ libcrux_ml_kem_ind_cpa_generate_keypair_15(Eurydice_slice key_generation_seed) { } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 3 +- PRIVATE_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_generate_keypair_15(Eurydice_slice key_generation_seed) { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 private_key = + libcrux_ml_kem_ind_cpa_unpacked_default_1a_1b(); + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 public_key = + libcrux_ml_kem_ind_cpa_unpacked_default_8d_1b(); + libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_1c( + key_generation_seed, &private_key, &public_key); + return libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_43(&public_key, + &private_key); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key_mut with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 - SERIALIZED_KEY_LEN= 2400 */ -static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_d6( +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_d6( Eurydice_slice private_key, Eurydice_slice public_key, - Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { - uint8_t out[2400U] = {0U}; + Eurydice_slice implicit_rejection_value, uint8_t *serialized) { size_t pointer = (size_t)0U; - uint8_t *uu____0 = out; + uint8_t *uu____0 = serialized; size_t uu____1 = pointer; size_t uu____2 = pointer; Eurydice_slice_copy( @@ -5941,7 +6015,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_d6( uint8_t), private_key, uint8_t); pointer = pointer + Eurydice_slice_len(private_key, uint8_t); - uint8_t *uu____3 = out; + uint8_t *uu____3 = serialized; size_t uu____4 = pointer; size_t uu____5 = pointer; Eurydice_slice_copy( @@ -5951,13 +6025,14 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_d6( public_key, uint8_t); pointer = pointer + Eurydice_slice_len(public_key, uint8_t); Eurydice_slice uu____6 = Eurydice_array_to_subslice2( - out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); - uint8_t ret0[32U]; - libcrux_ml_kem_hash_functions_portable_H_f1_e0(public_key, ret0); + serialized, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, + uint8_t); + uint8_t ret[32U]; + libcrux_ml_kem_hash_functions_portable_H_f1_e0(public_key, ret); Eurydice_slice_copy( - uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uu____6, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; - uint8_t *uu____7 = out; + uint8_t *uu____7 = serialized; size_t uu____8 = pointer; size_t uu____9 = pointer; Eurydice_slice_copy( @@ -5966,6 +6041,21 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_d6( uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), uint8_t), implicit_rejection_value, uint8_t); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- SERIALIZED_KEY_LEN= 2400 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_d6( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_d6( + private_key, public_key, implicit_rejection_value, out); memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); } @@ -6007,13 +6097,13 @@ libcrux_ml_kem_ind_cca_generate_keypair_f8(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_d9 private_key = - libcrux_ml_kem_types_from_7f_28(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_28(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_d9 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1184U]; memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_74( - uu____2, libcrux_ml_kem_types_from_5a_d0(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_d0(copy_of_public_key)); } /** @@ -6107,20 +6197,13 @@ libcrux_ml_kem_variant_Kyber with const generics static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_620( libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { - Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( - Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), - (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); Eurydice_slice ind_cpa_secret_key = uu____0.fst; - Eurydice_slice secret_key0 = uu____0.snd; - Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( - secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key = uu____1.fst; - Eurydice_slice secret_key = uu____1.snd; - Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( - secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, - Eurydice_slice_uint8_t_x2); - Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; - Eurydice_slice implicit_rejection_value = uu____2.snd; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; uint8_t decrypted[32U]; libcrux_ml_kem_ind_cpa_decrypt_42(ind_cpa_secret_key, ciphertext->value, decrypted); @@ -6135,29 +6218,29 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_620( uint8_t hashed[64U]; libcrux_ml_kem_hash_functions_portable_G_f1_e0( Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); - Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, Eurydice_slice_uint8_t_x2); - Eurydice_slice shared_secret0 = uu____3.fst; - Eurydice_slice pseudorandomness = uu____3.snd; + Eurydice_slice shared_secret0 = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; uint8_t to_hash[1120U]; libcrux_ml_kem_utils_into_padded_array_15(implicit_rejection_value, to_hash); - Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_80(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret0[32U]; libcrux_ml_kem_hash_functions_portable_PRF_f1_41( Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), implicit_rejection_shared_secret0); - Eurydice_slice uu____5 = ind_cpa_public_key; + Eurydice_slice uu____3 = ind_cpa_public_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_decrypted[32U]; memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); uint8_t expected_ciphertext[1088U]; - libcrux_ml_kem_ind_cpa_encrypt_2a(uu____5, copy_of_decrypted, + libcrux_ml_kem_ind_cpa_encrypt_2a(uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t implicit_rejection_shared_secret[32U]; libcrux_ml_kem_variant_kdf_33_d6( @@ -6168,7 +6251,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_decapsulate_620( libcrux_ml_kem_variant_kdf_33_d6(shared_secret0, ciphertext, shared_secret1); uint8_t shared_secret[32U]; libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( - libcrux_ml_kem_types_as_ref_00_80(ciphertext), + libcrux_ml_kem_types_as_ref_43_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), Eurydice_array_to_slice((size_t)32U, shared_secret1, uint8_t), Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, @@ -6297,7 +6380,7 @@ static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_encapsulate_ca0( uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = - libcrux_ml_kem_types_from_01_80(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_80(copy_of_ciphertext); uint8_t shared_secret_array[32U]; libcrux_ml_kem_variant_kdf_33_d6(shared_secret, &ciphertext0, shared_secret_array); @@ -6457,34 +6540,8 @@ libcrux_ml_kem_ind_cpa_generate_keypair_150( libcrux_ml_kem_ind_cpa_unpacked_default_8d_1b(); libcrux_ml_kem_ind_cpa_generate_keypair_unpacked_1c0( key_generation_seed, &private_key, &public_key); - uint8_t public_key_serialized[1184U]; - libcrux_ml_kem_ind_cpa_serialize_public_key_6c(/* pk := (Encode_12(tˆ - mod^{+}q) || ρ) */ - public_key.t_as_ntt, - Eurydice_array_to_slice( - (size_t)32U, - public_key.seed_for_A, - uint8_t), - public_key_serialized); - uint8_t secret_key_serialized[1152U]; - libcrux_ml_kem_ind_cpa_serialize_secret_key_89(/* sk := Encode_12(sˆ mod^{+}q) - */ - private_key.secret_as_ntt, - secret_key_serialized); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_secret_key_serialized[1152U]; - memcpy(copy_of_secret_key_serialized, secret_key_serialized, - (size_t)1152U * sizeof(uint8_t)); - /* Passing arrays by value in Rust generates a copy in C */ - uint8_t copy_of_public_key_serialized[1184U]; - memcpy(copy_of_public_key_serialized, public_key_serialized, - (size_t)1184U * sizeof(uint8_t)); - libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; - memcpy(lit.fst, copy_of_secret_key_serialized, - (size_t)1152U * sizeof(uint8_t)); - memcpy(lit.snd, copy_of_public_key_serialized, - (size_t)1184U * sizeof(uint8_t)); - return lit; + return libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_43(&public_key, + &private_key); } /** @@ -6525,13 +6582,13 @@ libcrux_ml_kem_ind_cca_generate_keypair_f80(uint8_t randomness[64U]) { memcpy(copy_of_secret_key_serialized, secret_key_serialized, (size_t)2400U * sizeof(uint8_t)); libcrux_ml_kem_types_MlKemPrivateKey_d9 private_key = - libcrux_ml_kem_types_from_7f_28(copy_of_secret_key_serialized); + libcrux_ml_kem_types_from_9a_28(copy_of_secret_key_serialized); libcrux_ml_kem_types_MlKemPrivateKey_d9 uu____2 = private_key; /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_public_key[1184U]; memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); return libcrux_ml_kem_types_from_3a_74( - uu____2, libcrux_ml_kem_types_from_5a_d0(copy_of_public_key)); + uu____2, libcrux_ml_kem_types_from_5f_d0(copy_of_public_key)); } /** @@ -6569,16 +6626,14 @@ libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair( } /** -A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key_only with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const generics - K= 3 - SECRET_KEY_SIZE= 2400 -- CIPHERTEXT_SIZE= 1088 */ -static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_37( - libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, - libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_only_d6( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { uint8_t t[32U]; libcrux_ml_kem_hash_functions_portable_H_f1_e0( Eurydice_array_to_subslice2(/* Eurydice can't access values directly on @@ -6595,6 +6650,20 @@ static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_37( (size_t)32U, t, &expected, uint8_t, uint8_t, bool); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CIPHERTEXT_SIZE= 1088 +*/ +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_37( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_d6(private_key); +} + /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key with const @@ -6623,6 +6692,30 @@ static inline bool libcrux_ml_kem_mlkem768_portable_validate_private_key( private_key, ciphertext); } +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key_only with +const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +*/ +static KRML_MUSTINLINE bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_only_41( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return libcrux_ml_kem_ind_cca_validate_private_key_only_d6(private_key); +} + +/** + Validate the private key only. + + Returns `true` if valid, and `false` otherwise. +*/ +static inline bool libcrux_ml_kem_mlkem768_portable_validate_private_key_only( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key) { + return libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_only_41( + private_key); +} + /** A monomorphic instance of libcrux_ml_kem.serialize.deserialize_ring_elements_reduced_out.closure with @@ -6712,6 +6805,38 @@ static inline bool libcrux_ml_kem_mlkem768_portable_validate_public_key( public_key->value); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.MlKemPublicKeyUnpacked +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0_s { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPublicKeyUnpacked_a0 ind_cpa_public_key; + uint8_t public_key_hash[32U]; +} libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0; + +typedef libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768PublicKeyUnpacked; + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.MlKemPrivateKeyUnpacked with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_a0_s { + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_a0 + ind_cpa_private_key; + uint8_t implicit_rejection_value[32U]; +} libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_a0; + +typedef struct + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked_s { + libcrux_ml_kem_ind_cca_unpacked_MlKemPrivateKeyUnpacked_a0 private_key; + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 public_key; +} libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked; + /** A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.decapsulate with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, @@ -6768,7 +6893,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_decapsulate_51( Eurydice_slice uu____2 = Eurydice_array_to_subslice_from( (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, size_t); - Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_00_80(ciphertext), + Eurydice_slice_copy(uu____2, libcrux_ml_kem_types_as_ref_43_80(ciphertext), uint8_t); uint8_t implicit_rejection_shared_secret[32U]; libcrux_ml_kem_hash_functions_portable_PRF_f1_41( @@ -6784,7 +6909,7 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_decapsulate_51( uu____3, copy_of_decrypted, pseudorandomness, expected_ciphertext); uint8_t selector = libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time( - libcrux_ml_kem_types_as_ref_00_80(ciphertext), + libcrux_ml_kem_types_as_ref_43_80(ciphertext), Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t)); uint8_t ret0[32U]; libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( @@ -6795,9 +6920,6 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_decapsulate_51( memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); } -/** - Unpacked decapsulate -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.decapsulate with const @@ -6819,7 +6941,7 @@ generics - ETA2_RANDOMNESS_SIZE= 128 - IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 */ -static inline void +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_decapsulate_35( libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { @@ -6898,7 +7020,7 @@ static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_unpacked_encapsulate_0c( uint8_t copy_of_ciphertext[1088U]; memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = - libcrux_ml_kem_types_from_01_80(copy_of_ciphertext); + libcrux_ml_kem_types_from_00_80(copy_of_ciphertext); /* Passing arrays by value in Rust generates a copy in C */ uint8_t copy_of_shared_secret_array[32U]; memcpy(copy_of_shared_secret_array, shared_secret_array, @@ -6909,9 +7031,6 @@ static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_unpacked_encapsulate_0c( return lit; } -/** - Unpacked encapsulate -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.encapsulate with const @@ -6930,7 +7049,7 @@ generics - ETA2= 2 - ETA2_RANDOMNESS_SIZE= 128 */ -static inline tuple_c2 +static KRML_MUSTINLINE tuple_c2 libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_encapsulate_cd( libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *public_key, uint8_t randomness[32U]) { @@ -7102,9 +7221,6 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_generate_keypair_f8( (size_t)32U * sizeof(uint8_t)); } -/** - Generate a key pair -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.generate_keypair with @@ -7117,7 +7233,7 @@ const generics - ETA1= 2 - ETA1_RANDOMNESS_SIZE= 128 */ -static inline void +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_generate_keypair_c6( uint8_t randomness[64U], libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *out) { @@ -7130,7 +7246,8 @@ libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_generate_keypair_c6( /** Generate ML-KEM 768 Key Pair in "unpacked" form. */ -static inline void libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair( +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut( uint8_t randomness[64U], libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair) { @@ -7245,6 +7362,21 @@ static KRML_MUSTINLINE .public_key = libcrux_ml_kem_ind_cca_unpacked_default_09_1b()}); } +/** + Generate ML-KEM 768 Key Pair in "unpacked" form. +*/ +static inline libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked +libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair( + uint8_t randomness[64U]) { + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked key_pair = + libcrux_ml_kem_ind_cca_unpacked_default_53_1b(); + uint8_t uu____0[64U]; + memcpy(uu____0, randomness, (size_t)64U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut(uu____0, + &key_pair); + return key_pair; +} + /** Create a new, empty unpacked key. */ @@ -7261,21 +7393,238 @@ libcrux_ml_kem_mlkem768_portable_unpacked_init_public_key(void) { return libcrux_ml_kem_ind_cca_unpacked_default_09_1b(); } +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.keys_from_private_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- BYTES_PER_RING_ELEMENT= 1152 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_keys_from_private_key_df( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + Eurydice_slice_uint8_t_x4 uu____0 = + libcrux_ml_kem_types_unpack_private_key_b4( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t)); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice ind_cpa_public_key = uu____0.snd; + Eurydice_slice ind_cpa_public_key_hash = uu____0.thd; + Eurydice_slice implicit_rejection_value = uu____0.f3; + Eurydice_slice uu____1 = Eurydice_array_to_slice( + (size_t)3U, + /* XXX: We need to copy_from_slice here because karamel can't handle the + assignment cf. https://github.com/FStarLang/karamel/pull/491 */ + key_pair->private_key.ind_cpa_private_key.secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_1d); + libcrux_ml_kem_polynomial_PolynomialRingElement_1d ret[3U]; + libcrux_ml_kem_ind_cpa_deserialize_secret_key_1b(ind_cpa_secret_key, ret); + Eurydice_slice_copy( + uu____1, + Eurydice_array_to_slice( + (size_t)3U, ret, libcrux_ml_kem_polynomial_PolynomialRingElement_1d), + libcrux_ml_kem_polynomial_PolynomialRingElement_1d); + libcrux_ml_kem_ind_cpa_build_unpacked_public_key_mut_3f( + ind_cpa_public_key, &key_pair->public_key.ind_cpa_public_key); + Eurydice_slice_copy( + Eurydice_array_to_slice((size_t)32U, key_pair->public_key.public_key_hash, + uint8_t), + ind_cpa_public_key_hash, uint8_t); + Eurydice_slice_copy( + Eurydice_array_to_slice( + (size_t)32U, key_pair->private_key.implicit_rejection_value, uint8_t), + implicit_rejection_value, uint8_t); + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)32U, key_pair->public_key.ind_cpa_public_key.seed_for_A, uint8_t); + Eurydice_slice_copy(uu____2, + Eurydice_slice_subslice_from( + ind_cpa_public_key, (size_t)1152U, uint8_t, size_t), + uint8_t); +} + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.keypair_from_private_key +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- BYTES_PER_RING_ELEMENT= 1152 +- T_AS_NTT_ENCODED_SIZE= 1152 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_keypair_from_private_key_ce( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + libcrux_ml_kem_ind_cca_unpacked_keys_from_private_key_df(private_key, + key_pair); +} + +/** + Get an unpacked key from a private key. +*/ +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_from_private_mut( + libcrux_ml_kem_types_MlKemPrivateKey_d9 *private_key, + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_keypair_from_private_key_ce( + private_key, key_pair); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]#4} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.serialized_private_key_mut_fc with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_fc_42( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self, + libcrux_ml_kem_types_MlKemPrivateKey_d9 *serialized) { + libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = + libcrux_ml_kem_ind_cpa_serialize_unpacked_secret_key_43( + &self->public_key.ind_cpa_public_key, + &self->private_key.ind_cpa_private_key); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t ind_cpa_public_key[1184U]; + memcpy(ind_cpa_public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_mut_d6( + Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t), + Eurydice_array_to_slice((size_t)1184U, ind_cpa_public_key, uint8_t), + Eurydice_array_to_slice( + (size_t)32U, self->private_key.implicit_rejection_value, uint8_t), + serialized->value); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]#4} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.unpacked.serialized_private_key_fc with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_fc_42( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self) { + libcrux_ml_kem_types_MlKemPrivateKey_d9 sk = + libcrux_ml_kem_types_default_24_28(); + libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_fc_42(self, &sk); + return sk; +} + +/** + Get the serialized private key. +*/ +static inline libcrux_ml_kem_types_MlKemPrivateKey_d9 +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_private_key( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_fc_42(key_pair); +} + +/** + Get the serialized private key. +*/ +static inline void +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_private_key_mut( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair, + libcrux_ml_kem_types_MlKemPrivateKey_d9 *serialized) { + libcrux_ml_kem_ind_cca_unpacked_serialized_private_key_mut_fc_42(key_pair, + serialized); +} + /** This function found in impl {libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@1]#3} */ /** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.serialized_30 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_ind_cca_unpacked_serialized_30_6c( + libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *self) { + uint8_t ret[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key_6c( + self->ind_cpa_public_key.t_as_ntt, + Eurydice_array_to_slice((size_t)32U, self->ind_cpa_public_key.seed_for_A, + uint8_t), + ret); + return libcrux_ml_kem_types_from_5f_d0(ret); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemKeyPairUnpacked[TraitClause@0, TraitClause@1]#4} +*/ +/** A monomorphic instance of -libcrux_ml_kem.ind_cca.unpacked.serialized_public_key_mut_30 with types +libcrux_ml_kem.ind_cca.unpacked.serialized_public_key_fc with types libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics - K= 3 - RANKED_BYTES_PER_RING_ELEMENT= 1152 - PUBLIC_KEY_SIZE= 1184 */ +static KRML_MUSTINLINE libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_fc_6c( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_30_6c(&self->public_key); +} + +static inline libcrux_ml_kem_types_MlKemPublicKey_30 +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_public_key( + libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked + *key_pair) { + return libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_fc_6c(key_pair); +} + +/** +This function found in impl +{libcrux_ml_kem::ind_cca::unpacked::MlKemPublicKeyUnpacked[TraitClause@0, TraitClause@1]#3} +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.unpacked.serialized_mut_30 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ static KRML_MUSTINLINE void -libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_30_6c( +libcrux_ml_kem_ind_cca_unpacked_serialized_mut_30_6c( libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *self, libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { libcrux_ml_kem_ind_cpa_serialize_public_key_mut_6c( @@ -7302,15 +7651,12 @@ static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_fc_6c( libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *self, libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { - libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_30_6c( - &self->public_key, serialized); + libcrux_ml_kem_ind_cca_unpacked_serialized_mut_30_6c(&self->public_key, + serialized); } -/** - Get the serialized public key. -*/ static inline void -libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_public_key( +libcrux_ml_kem_mlkem768_portable_unpacked_key_pair_serialized_public_key_mut( libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked *key_pair, libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_fc_6c(key_pair, @@ -7406,15 +7752,11 @@ static inline void libcrux_ml_kem_mlkem768_portable_unpacked_public_key( pk[0U] = uu____0; } -/** - Get the serialized public key. -*/ static inline void libcrux_ml_kem_mlkem768_portable_unpacked_serialized_public_key( libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 *public_key, libcrux_ml_kem_types_MlKemPublicKey_30 *serialized) { - libcrux_ml_kem_ind_cca_unpacked_serialized_public_key_mut_30_6c(public_key, - serialized); + libcrux_ml_kem_ind_cca_unpacked_serialized_mut_30_6c(public_key, serialized); } /** @@ -7460,9 +7802,6 @@ libcrux_ml_kem_ind_cca_unpacked_unpack_public_key_f9( (size_t)32U * sizeof(uint8_t)); } -/** - Get the unpacked public key. -*/ /** A monomorphic instance of libcrux_ml_kem.ind_cca.instantiations.portable.unpacked.unpack_public_key with @@ -7472,7 +7811,7 @@ const generics - RANKED_BYTES_PER_RING_ELEMENT= 1152 - PUBLIC_KEY_SIZE= 1184 */ -static inline void +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_instantiations_portable_unpacked_unpack_public_key_a5( libcrux_ml_kem_types_MlKemPublicKey_30 *public_key, libcrux_ml_kem_ind_cca_unpacked_MlKemPublicKeyUnpacked_a0 diff --git a/libcrux-ml-kem/cg/libcrux_mlkem768_portable_types.h b/libcrux-ml-kem/cg/libcrux_mlkem768_portable_types.h index 3133e6233..c2aa94056 100644 --- a/libcrux-ml-kem/cg/libcrux_mlkem768_portable_types.h +++ b/libcrux-ml-kem/cg/libcrux_mlkem768_portable_types.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d + * Libcrux: 38837f1aab3f2ae348a0cb53cf44d97652e2c977 */ #ifndef __libcrux_mlkem768_portable_types_H diff --git a/libcrux-ml-kem/cg/libcrux_sha3_avx2.h b/libcrux-ml-kem/cg/libcrux_sha3_avx2.h index cf22f9844..ec647eb4a 100644 --- a/libcrux-ml-kem/cg/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/cg/libcrux_sha3_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d + * Libcrux: 8fa4c2d98c5fd5a203b5a37a971a46f2296646d9 */ #ifndef __libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/cg/libcrux_sha3_portable.h b/libcrux-ml-kem/cg/libcrux_sha3_portable.h index 0b6f7b530..673688674 100644 --- a/libcrux-ml-kem/cg/libcrux_sha3_portable.h +++ b/libcrux-ml-kem/cg/libcrux_sha3_portable.h @@ -8,7 +8,7 @@ * Eurydice: 1fff1c51ae6e6c87eafd28ec9d5594f54bc91c0c * Karamel: c31a22c1e07d2118c07ee5cebb640d863e31a198 * F*: 2c32d6e230851bbceadac7a21fc418fa2bb7e4bc - * Libcrux: 7ed909f8033142d720fcbfe309243b9fa52d181d + * Libcrux: 8fa4c2d98c5fd5a203b5a37a971a46f2296646d9 */ #ifndef __libcrux_sha3_portable_H diff --git a/libcrux-ml-kem/cg/tests/mlkem768.cc b/libcrux-ml-kem/cg/tests/mlkem768.cc index 947171f58..d9178a7fa 100644 --- a/libcrux-ml-kem/cg/tests/mlkem768.cc +++ b/libcrux-ml-kem/cg/tests/mlkem768.cc @@ -106,7 +106,7 @@ TEST(MlKem768TestPortableUnpacked, ConsistencyTest) keygen_randomness[i] = 13; } libcrux_ml_kem_mlkem768_portable_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_portable_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair(keygen_randomness, &key_pair); + libcrux_ml_kem_mlkem768_portable_unpacked_generate_key_pair_mut(keygen_randomness, &key_pair); uint8_t encap_randomness[32]; for (int i = 0; i < 32; i++) @@ -266,7 +266,7 @@ TEST(MlKem768TestAvx2Unpacked, ConsistencyTest) keygen_randomness[i] = 13; } libcrux_ml_kem_mlkem768_avx2_unpacked_MlKem768KeyPairUnpacked key_pair = libcrux_ml_kem_mlkem768_avx2_unpacked_init_key_pair() ; - libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair(keygen_randomness, &key_pair); + libcrux_ml_kem_mlkem768_avx2_unpacked_generate_key_pair_mut(keygen_randomness, &key_pair); uint8_t encap_randomness[32]; for (int i = 0; i < 32; i++) diff --git a/libcrux-ml-kem/fuzz/.gitignore b/libcrux-ml-kem/fuzz/.gitignore new file mode 100644 index 000000000..1a45eee77 --- /dev/null +++ b/libcrux-ml-kem/fuzz/.gitignore @@ -0,0 +1,4 @@ +target +corpus +artifacts +coverage diff --git a/libcrux-ml-kem/fuzz/Cargo.toml b/libcrux-ml-kem/fuzz/Cargo.toml new file mode 100644 index 000000000..ccb5bed0d --- /dev/null +++ b/libcrux-ml-kem/fuzz/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "libcrux-ml-kem-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" + +[dependencies.libcrux-ml-kem] +path = ".." + +[[bin]] +name = "keygen" +path = "fuzz_targets/keygen.rs" +test = false +doc = false +bench = false + +[[bin]] +name = "encaps" +path = "fuzz_targets/encaps.rs" +test = false +doc = false +bench = false + +[[bin]] +name = "decaps" +path = "fuzz_targets/decaps.rs" +test = false +doc = false +bench = false diff --git a/libcrux-ml-kem/fuzz/fuzz_targets/decaps.rs b/libcrux-ml-kem/fuzz/fuzz_targets/decaps.rs new file mode 100644 index 000000000..f2aaa8a28 --- /dev/null +++ b/libcrux-ml-kem/fuzz/fuzz_targets/decaps.rs @@ -0,0 +1,25 @@ +#![no_main] + +use libcrux_ml_kem::{mlkem768, ENCAPS_SEED_SIZE, KEY_GENERATION_SEED_SIZE}; +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + if data.len() < KEY_GENERATION_SEED_SIZE + ENCAPS_SEED_SIZE { + // Not enough entropy + return; + } + + let mut randomness = [0u8; KEY_GENERATION_SEED_SIZE]; + randomness.copy_from_slice(&data[..KEY_GENERATION_SEED_SIZE]); + + let key_pair = mlkem768::generate_key_pair(randomness); + + let mut randomness = [0u8; ENCAPS_SEED_SIZE]; + randomness.copy_from_slice( + &data[KEY_GENERATION_SEED_SIZE..KEY_GENERATION_SEED_SIZE + ENCAPS_SEED_SIZE], + ); + + let (ct, _ss) = mlkem768::encapsulate(key_pair.public_key(), randomness); + + let _ = core::hint::black_box(mlkem768::decapsulate(key_pair.private_key(), &ct)); +}); diff --git a/libcrux-ml-kem/fuzz/fuzz_targets/encaps.rs b/libcrux-ml-kem/fuzz/fuzz_targets/encaps.rs new file mode 100644 index 000000000..84342631c --- /dev/null +++ b/libcrux-ml-kem/fuzz/fuzz_targets/encaps.rs @@ -0,0 +1,23 @@ +#![no_main] + +use libcrux_ml_kem::{mlkem768, ENCAPS_SEED_SIZE, KEY_GENERATION_SEED_SIZE}; +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + if data.len() < KEY_GENERATION_SEED_SIZE + ENCAPS_SEED_SIZE { + // Not enough entropy + return; + } + + let mut randomness = [0u8; KEY_GENERATION_SEED_SIZE]; + randomness.copy_from_slice(&data[..KEY_GENERATION_SEED_SIZE]); + + let key_pair = mlkem768::generate_key_pair(randomness); + + let mut randomness = [0u8; ENCAPS_SEED_SIZE]; + randomness.copy_from_slice( + &data[KEY_GENERATION_SEED_SIZE..KEY_GENERATION_SEED_SIZE + ENCAPS_SEED_SIZE], + ); + + let _ = core::hint::black_box(mlkem768::encapsulate(key_pair.public_key(), randomness)); +}); diff --git a/libcrux-ml-kem/fuzz/fuzz_targets/keygen.rs b/libcrux-ml-kem/fuzz/fuzz_targets/keygen.rs new file mode 100644 index 000000000..5af308d21 --- /dev/null +++ b/libcrux-ml-kem/fuzz/fuzz_targets/keygen.rs @@ -0,0 +1,14 @@ +#![no_main] + +use libcrux_ml_kem::{mlkem768, KEY_GENERATION_SEED_SIZE}; +use libfuzzer_sys::fuzz_target; + +fuzz_target!(|data: &[u8]| { + if data.len() < KEY_GENERATION_SEED_SIZE { + // We need enough entropy. + return; + } + let mut randomness = [0u8; KEY_GENERATION_SEED_SIZE]; + randomness.copy_from_slice(&data[..KEY_GENERATION_SEED_SIZE]); + let _ = core::hint::black_box(mlkem768::generate_key_pair(randomness)); +}); diff --git a/libcrux-ml-kem/hax.py b/libcrux-ml-kem/hax.py index d5f025639..8b78cdee4 100755 --- a/libcrux-ml-kem/hax.py +++ b/libcrux-ml-kem/hax.py @@ -40,8 +40,6 @@ def __call__(self, parser, args, values, option_string=None) -> None: "-i", include_str, "fstar", - "--z3rlimit", - "80", "--interfaces", interface_include, ] @@ -66,8 +64,6 @@ def __call__(self, parser, args, values, option_string=None) -> None: "-i", include_str, "fstar", - "--z3rlimit", - "80", "--interfaces", interface_include, ] @@ -98,12 +94,11 @@ def __call__(self, parser, args, values, option_string=None) -> None: "simd128,simd256,pre-verification", ";", "into", - "-vv", "-i", include_str, "fstar", "--z3rlimit", - "100", + "80", "--interfaces", interface_include, ] diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fst index 1bff53934..184d21930 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Constant_time_ops -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fsti index dc6fd2b46..981aa5aa1 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constant_time_ops.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Constant_time_ops -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti index 812c7717d..1c3fdf673 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Constants.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Constants -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti index fc7ae6c87..336b75faa 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Avx2.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Hash_functions.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -8,6 +8,9 @@ open FStar.Mul /// All other functions don\'t actually use any members. val t_Simd256Hash:Type0 +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K + val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True @@ -52,69 +55,3 @@ val shake128_squeeze_next_block (v_K: usize) (st: t_Simd256Hash) : Prims.Pure (t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K) Prims.l_True (fun _ -> Prims.l_True) - -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd256Hash v_K = - { - f_G_pre = (fun (input: t_Slice u8) -> true); - f_G_post = (fun (input: t_Slice u8) (out: t_Array u8 (sz 64)) -> out == Spec.Utils.v_G input); - f_G = (fun (input: t_Slice u8) -> v_G input); - f_H_pre = (fun (input: t_Slice u8) -> true); - f_H_post = (fun (input: t_Slice u8) (out: t_Array u8 (sz 32)) -> out == Spec.Utils.v_H input); - f_H = (fun (input: t_Slice u8) -> v_H input); - f_PRF_pre = (fun (v_LEN: usize) (input: t_Slice u8) -> v v_LEN < pow2 32); - f_PRF_post - = - (fun (v_LEN: usize) (input: t_Slice u8) (out: t_Array u8 v_LEN) -> - v v_LEN < pow2 32 ==> out == Spec.Utils.v_PRF v_LEN input); - f_PRF = (fun (v_LEN: usize) (input: t_Slice u8) -> v_PRF v_LEN input); - f_PRFxN_pre - = - (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> - v v_LEN < pow2 32 /\ (v v_K == 2 \/ v v_K == 3 \/ v v_K == 4)); - f_PRFxN_post - = - (fun - (v_LEN: usize) - (input: t_Array (t_Array u8 (sz 33)) v_K) - (out: t_Array (t_Array u8 v_LEN) v_K) - -> - (v v_LEN < pow2 32 /\ (v v_K == 2 \/ v v_K == 3 \/ v v_K == 4)) ==> - out == Spec.Utils.v_PRFxN v_K v_LEN input); - f_PRFxN - = - (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> v_PRFxN v_K v_LEN input); - f_shake128_init_absorb_final_pre = (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> true); - f_shake128_init_absorb_final_post - = - (fun (input: t_Array (t_Array u8 (sz 34)) v_K) (out: t_Simd256Hash) -> true); - f_shake128_init_absorb_final - = - (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> shake128_init_absorb_final v_K input); - f_shake128_squeeze_first_three_blocks_pre = (fun (self: t_Simd256Hash) -> true); - f_shake128_squeeze_first_three_blocks_post - = - (fun (self: t_Simd256Hash) (out1: (t_Simd256Hash & t_Array (t_Array u8 (sz 504)) v_K)) -> true); - f_shake128_squeeze_first_three_blocks - = - (fun (self: t_Simd256Hash) -> - let tmp0, out:(t_Simd256Hash & t_Array (t_Array u8 (sz 504)) v_K) = - shake128_squeeze_first_three_blocks v_K self - in - let self:t_Simd256Hash = tmp0 in - let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in - self, hax_temp_output <: (t_Simd256Hash & t_Array (t_Array u8 (sz 504)) v_K)); - f_shake128_squeeze_next_block_pre = (fun (self: t_Simd256Hash) -> true); - f_shake128_squeeze_next_block_post - = - (fun (self: t_Simd256Hash) (out1: (t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K)) -> true); - f_shake128_squeeze_next_block - = - fun (self: t_Simd256Hash) -> - let tmp0, out:(t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K) = - shake128_squeeze_next_block v_K self - in - let self:t_Simd256Hash = tmp0 in - let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in - self, hax_temp_output <: (t_Simd256Hash & t_Array (t_Array u8 (sz 168)) v_K) - } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti index 8232d0b3d..7b7869c77 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Neon.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Hash_functions.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -8,6 +8,9 @@ open FStar.Mul /// All other functions don\'t actually use any members. val t_Simd128Hash:Type0 +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K + val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True @@ -52,69 +55,3 @@ val shake128_squeeze_next_block (v_K: usize) (st: t_Simd128Hash) : Prims.Pure (t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K) Prims.l_True (fun _ -> Prims.l_True) - -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash t_Simd128Hash v_K = - { - f_G_pre = (fun (input: t_Slice u8) -> true); - f_G_post = (fun (input: t_Slice u8) (out: t_Array u8 (sz 64)) -> out == Spec.Utils.v_G input); - f_G = (fun (input: t_Slice u8) -> v_G input); - f_H_pre = (fun (input: t_Slice u8) -> true); - f_H_post = (fun (input: t_Slice u8) (out: t_Array u8 (sz 32)) -> out == Spec.Utils.v_H input); - f_H = (fun (input: t_Slice u8) -> v_H input); - f_PRF_pre = (fun (v_LEN: usize) (input: t_Slice u8) -> v v_LEN < pow2 32); - f_PRF_post - = - (fun (v_LEN: usize) (input: t_Slice u8) (out: t_Array u8 v_LEN) -> - v v_LEN < pow2 32 ==> out == Spec.Utils.v_PRF v_LEN input); - f_PRF = (fun (v_LEN: usize) (input: t_Slice u8) -> v_PRF v_LEN input); - f_PRFxN_pre - = - (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> - v v_LEN < pow2 32 /\ (v v_K == 2 \/ v v_K == 3 \/ v v_K == 4)); - f_PRFxN_post - = - (fun - (v_LEN: usize) - (input: t_Array (t_Array u8 (sz 33)) v_K) - (out: t_Array (t_Array u8 v_LEN) v_K) - -> - (v v_LEN < pow2 32 /\ (v v_K == 2 \/ v v_K == 3 \/ v v_K == 4)) ==> - out == Spec.Utils.v_PRFxN v_K v_LEN input); - f_PRFxN - = - (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> v_PRFxN v_K v_LEN input); - f_shake128_init_absorb_final_pre = (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> true); - f_shake128_init_absorb_final_post - = - (fun (input: t_Array (t_Array u8 (sz 34)) v_K) (out: t_Simd128Hash) -> true); - f_shake128_init_absorb_final - = - (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> shake128_init_absorb_final v_K input); - f_shake128_squeeze_first_three_blocks_pre = (fun (self: t_Simd128Hash) -> true); - f_shake128_squeeze_first_three_blocks_post - = - (fun (self: t_Simd128Hash) (out1: (t_Simd128Hash & t_Array (t_Array u8 (sz 504)) v_K)) -> true); - f_shake128_squeeze_first_three_blocks - = - (fun (self: t_Simd128Hash) -> - let tmp0, out:(t_Simd128Hash & t_Array (t_Array u8 (sz 504)) v_K) = - shake128_squeeze_first_three_blocks v_K self - in - let self:t_Simd128Hash = tmp0 in - let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in - self, hax_temp_output <: (t_Simd128Hash & t_Array (t_Array u8 (sz 504)) v_K)); - f_shake128_squeeze_next_block_pre = (fun (self: t_Simd128Hash) -> true); - f_shake128_squeeze_next_block_post - = - (fun (self: t_Simd128Hash) (out1: (t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K)) -> true); - f_shake128_squeeze_next_block - = - fun (self: t_Simd128Hash) -> - let tmp0, out:(t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K) = - shake128_squeeze_next_block v_K self - in - let self:t_Simd128Hash = tmp0 in - let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in - self, hax_temp_output <: (t_Simd128Hash & t_Array (t_Array u8 (sz 168)) v_K) - } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Portable.fsti index 33e10a142..37255d0af 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Portable.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.Portable.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Hash_functions.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -8,6 +8,9 @@ open FStar.Mul /// All other functions don\'t actually use any members. val t_PortableHash (v_K: usize) : Type0 +[@@ FStar.Tactics.Typeclasses.tcinstance] +val impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K) v_K + val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True @@ -52,77 +55,3 @@ val shake128_squeeze_next_block (v_K: usize) (st: t_PortableHash v_K) : Prims.Pure (t_PortableHash v_K & t_Array (t_Array u8 (sz 168)) v_K) Prims.l_True (fun _ -> Prims.l_True) - -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl (v_K: usize) : Libcrux_ml_kem.Hash_functions.t_Hash (t_PortableHash v_K) v_K = - { - f_G_pre = (fun (input: t_Slice u8) -> true); - f_G_post = (fun (input: t_Slice u8) (out: t_Array u8 (sz 64)) -> out == Spec.Utils.v_G input); - f_G = (fun (input: t_Slice u8) -> v_G input); - f_H_pre = (fun (input: t_Slice u8) -> true); - f_H_post = (fun (input: t_Slice u8) (out: t_Array u8 (sz 32)) -> out == Spec.Utils.v_H input); - f_H = (fun (input: t_Slice u8) -> v_H input); - f_PRF_pre = (fun (v_LEN: usize) (input: t_Slice u8) -> v v_LEN < pow2 32); - f_PRF_post - = - (fun (v_LEN: usize) (input: t_Slice u8) (out: t_Array u8 v_LEN) -> - v v_LEN < pow2 32 ==> out == Spec.Utils.v_PRF v_LEN input); - f_PRF = (fun (v_LEN: usize) (input: t_Slice u8) -> v_PRF v_LEN input); - f_PRFxN_pre - = - (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> - v v_LEN < pow2 32 /\ (v v_K == 2 \/ v v_K == 3 \/ v v_K == 4)); - f_PRFxN_post - = - (fun - (v_LEN: usize) - (input: t_Array (t_Array u8 (sz 33)) v_K) - (out: t_Array (t_Array u8 v_LEN) v_K) - -> - (v v_LEN < pow2 32 /\ (v v_K == 2 \/ v v_K == 3 \/ v v_K == 4)) ==> - out == Spec.Utils.v_PRFxN v_K v_LEN input); - f_PRFxN - = - (fun (v_LEN: usize) (input: t_Array (t_Array u8 (sz 33)) v_K) -> v_PRFxN v_K v_LEN input); - f_shake128_init_absorb_final_pre = (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> true); - f_shake128_init_absorb_final_post - = - (fun (input: t_Array (t_Array u8 (sz 34)) v_K) (out: t_PortableHash v_K) -> true); - f_shake128_init_absorb_final - = - (fun (input: t_Array (t_Array u8 (sz 34)) v_K) -> shake128_init_absorb_final v_K input); - f_shake128_squeeze_first_three_blocks_pre = (fun (self: t_PortableHash v_K) -> true); - f_shake128_squeeze_first_three_blocks_post - = - (fun - (self: t_PortableHash v_K) - (out1: (t_PortableHash v_K & t_Array (t_Array u8 (sz 504)) v_K)) - -> - true); - f_shake128_squeeze_first_three_blocks - = - (fun (self: t_PortableHash v_K) -> - let tmp0, out:(t_PortableHash v_K & t_Array (t_Array u8 (sz 504)) v_K) = - shake128_squeeze_first_three_blocks v_K self - in - let self:t_PortableHash v_K = tmp0 in - let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in - self, hax_temp_output <: (t_PortableHash v_K & t_Array (t_Array u8 (sz 504)) v_K)); - f_shake128_squeeze_next_block_pre = (fun (self: t_PortableHash v_K) -> true); - f_shake128_squeeze_next_block_post - = - (fun - (self: t_PortableHash v_K) - (out1: (t_PortableHash v_K & t_Array (t_Array u8 (sz 168)) v_K)) - -> - true); - f_shake128_squeeze_next_block - = - fun (self: t_PortableHash v_K) -> - let tmp0, out:(t_PortableHash v_K & t_Array (t_Array u8 (sz 168)) v_K) = - shake128_squeeze_next_block v_K self - in - let self:t_PortableHash v_K = tmp0 in - let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in - self, hax_temp_output <: (t_PortableHash v_K & t_Array (t_Array u8 (sz 168)) v_K) - } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.fsti index f734de676..05c34b4bc 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Hash_functions.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Hash_functions -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.fst new file mode 100644 index 000000000..ec082d69c --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.fst @@ -0,0 +1,191 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Hash_functions.Avx2 in + let open Libcrux_ml_kem.Variant in + let open Libcrux_ml_kem.Vector.Avx2 in + let open Libcrux_ml_kem.Vector.Traits in + () + +let decapsulate_avx2 + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + = + Libcrux_ml_kem.Ind_cca.Unpacked.decapsulate v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE + v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector #Libcrux_ml_kem.Hash_functions.Avx2.t_Simd256Hash + key_pair ciphertext + +let decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + = + decapsulate_avx2 v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE + v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE key_pair ciphertext + +let encapsulate_avx2 + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Unpacked.encapsulate v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE + v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + #Libcrux_ml_kem.Hash_functions.Avx2.t_Simd256Hash public_key randomness + +let encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + = + encapsulate_avx2 v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE + v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN + v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE public_key randomness + +let generate_keypair_avx2 + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + (out: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let hax_temp_output, out:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.generate_keypair v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector #Libcrux_ml_kem.Hash_functions.Avx2.t_Simd256Hash + #Libcrux_ml_kem.Variant.t_MlKem randomness out + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + out + +let generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + (out: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let hax_temp_output, out:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) = + (), + generate_keypair_avx2 v_K + v_CPA_PRIVATE_KEY_SIZE + v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT + v_ETA1 + v_ETA1_RANDOMNESS_SIZE + randomness + out + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + out + +let keypair_from_private_key + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Libcrux_ml_kem.Ind_cca.Unpacked.keys_from_private_key v_K + v_SECRET_KEY_SIZE + v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT + v_T_AS_NTT_ENCODED_SIZE + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + private_key + key_pair + in + key_pair + +let unpack_public_key_avx2 + (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.unpack_public_key v_K + v_T_AS_NTT_ENCODED_SIZE + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + #Libcrux_ml_kem.Hash_functions.Avx2.t_Simd256Hash + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + unpacked_public_key + +let unpack_public_key + (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) = + (), + unpack_public_key_avx2 v_K + v_T_AS_NTT_ENCODED_SIZE + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.fsti new file mode 100644 index 000000000..b55a38fd3 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.fsti @@ -0,0 +1,182 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Hash_functions.Avx2 in + let open Libcrux_ml_kem.Variant in + let open Libcrux_ml_kem.Vector.Avx2 in + let open Libcrux_ml_kem.Vector.Traits in + () + +val decapsulate_avx2 + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + : Prims.Pure (t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Unpacked decapsulate +val decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + : Prims.Pure (t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE v_K) + (fun _ -> Prims.l_True) + +val encapsulate_avx2 + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Unpacked encapsulate +val encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K) + (fun _ -> Prims.l_True) + +val generate_keypair_avx2 + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + (out: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Generate a key pair +val generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + (out: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Take a serialized private key and generate an unpacked key pair from it. +val keypair_from_private_key + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpack_public_key_avx2 + (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpack_public_key + (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fst index c9a34f640..c6fa41647 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Instantiations.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -31,6 +31,15 @@ let validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) = validate_private_key_avx2 v_K v_SECRET_KEY_SIZE v_CIPHERTEXT_SIZE private_key ciphertext +let validate_private_key_only + (v_K v_SECRET_KEY_SIZE: usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + = + Libcrux_ml_kem.Ind_cca.validate_private_key_only v_K + v_SECRET_KEY_SIZE + #Libcrux_ml_kem.Hash_functions.Avx2.t_Simd256Hash + private_key + let decapsulate_avx2 (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fsti index 39fede866..d31791ba7 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Instantiations.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -17,27 +17,74 @@ val validate_private_key_avx2 (v_K v_SECRET_KEY_SIZE v_CIPHERTEXT_SIZE: usize) (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + : Prims.Pure bool + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K) + (fun _ -> Prims.l_True) val validate_private_key (v_K v_SECRET_KEY_SIZE v_CIPHERTEXT_SIZE: usize) (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + : Prims.Pure bool + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Private key validation +val validate_private_key_only + (v_K v_SECRET_KEY_SIZE: usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + : Prims.Pure bool + (requires Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K + ) + (fun _ -> Prims.l_True) val decapsulate_avx2 (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize) (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + : Prims.Pure (t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K /\ + v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE v_K) + (fun _ -> Prims.l_True) val decapsulate (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize) (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + : Prims.Pure (t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K /\ + v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE v_K) + (fun _ -> Prims.l_True) val encapsulate_avx2 (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: @@ -45,7 +92,17 @@ val encapsulate_avx2 (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) (randomness: t_Array u8 (sz 32)) : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - Prims.l_True + (requires + Spec.MLKEM.is_rank v_K /\ v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K) (fun _ -> Prims.l_True) val encapsulate @@ -54,7 +111,17 @@ val encapsulate (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) (randomness: t_Array u8 (sz 32)) : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - Prims.l_True + (requires + Spec.MLKEM.is_rank v_K /\ v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K) (fun _ -> Prims.l_True) /// Portable generate key pair. @@ -63,7 +130,13 @@ val generate_keypair_avx2 usize) (randomness: t_Array u8 (sz 64)) : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - Prims.l_True + (requires + Spec.MLKEM.is_rank v_K /\ v_CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K) (fun _ -> Prims.l_True) val generate_keypair @@ -71,15 +144,31 @@ val generate_keypair usize) (randomness: t_Array u8 (sz 64)) : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - Prims.l_True + (requires + Spec.MLKEM.is_rank v_K /\ v_CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K) (fun _ -> Prims.l_True) val validate_public_key_avx2 (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) - : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + : Prims.Pure bool + (requires + Spec.MLKEM.is_rank v_K /\ + v_RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CCA_PUBLIC_KEY_SIZE v_K) + (fun _ -> Prims.l_True) val validate_public_key (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) - : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + : Prims.Pure bool + (requires + Spec.MLKEM.is_rank v_K /\ + v_RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CCA_PUBLIC_KEY_SIZE v_K) + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.fst new file mode 100644 index 000000000..591097306 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.fst @@ -0,0 +1,115 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Hash_functions.Neon in + let open Libcrux_ml_kem.Variant in + let open Libcrux_ml_kem.Vector.Neon in + let open Libcrux_ml_kem.Vector.Traits in + () + +let decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + = + Libcrux_ml_kem.Ind_cca.Unpacked.decapsulate v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE + v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + #Libcrux_ml_kem.Hash_functions.Neon.t_Simd128Hash key_pair ciphertext + +let encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Unpacked.encapsulate v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE + v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + #Libcrux_ml_kem.Hash_functions.Neon.t_Simd128Hash public_key randomness + +let generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + (out: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let hax_temp_output, out:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.generate_keypair v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + #Libcrux_ml_kem.Hash_functions.Neon.t_Simd128Hash #Libcrux_ml_kem.Variant.t_MlKem randomness + out + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + in + out + +let keypair_from_private_key + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Libcrux_ml_kem.Ind_cca.Unpacked.keys_from_private_key v_K + v_SECRET_KEY_SIZE + v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT + v_T_AS_NTT_ENCODED_SIZE + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + private_key + key_pair + in + key_pair + +let unpack_public_key + (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.unpack_public_key v_K + v_T_AS_NTT_ENCODED_SIZE + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + #Libcrux_ml_kem.Hash_functions.Neon.t_Simd128Hash + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.fsti new file mode 100644 index 000000000..05e8e5cd5 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.fsti @@ -0,0 +1,115 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Hash_functions.Neon in + let open Libcrux_ml_kem.Variant in + let open Libcrux_ml_kem.Vector.Neon in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Unpacked decapsulate +val decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + : Prims.Pure (t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K /\ + v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Unpacked encapsulate +val encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Generate a key pair +val generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + (out: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Take a serialized private key and generate an unpacked key pair from it. +val keypair_from_private_key + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpack_public_key + (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.fst index dca261dd4..30ff60795 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Instantiations.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -25,6 +25,15 @@ let validate_private_key private_key ciphertext +let validate_private_key_only + (v_K v_SECRET_KEY_SIZE: usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + = + Libcrux_ml_kem.Ind_cca.validate_private_key_only v_K + v_SECRET_KEY_SIZE + #Libcrux_ml_kem.Hash_functions.Neon.t_Simd128Hash + private_key + let decapsulate (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.fsti index e244a6ece..fd97941df 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Neon.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Instantiations.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,7 +13,7 @@ let _ = let open Libcrux_ml_kem.Vector.Traits in () -/// Portable private key validation +/// Private key validation val validate_private_key (v_K v_SECRET_KEY_SIZE v_CIPHERTEXT_SIZE: usize) (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) @@ -24,6 +24,15 @@ val validate_private_key v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K) (fun _ -> Prims.l_True) +/// Private key validation +val validate_private_key_only + (v_K v_SECRET_KEY_SIZE: usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + : Prims.Pure bool + (requires Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K + ) + (fun _ -> Prims.l_True) + /// Portable decapsulate val decapsulate (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: @@ -81,7 +90,7 @@ val generate_keypair v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K) (fun _ -> Prims.l_True) -/// Portable public key validation +/// Public key validation val validate_public_key (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.fst new file mode 100644 index 000000000..b9f62cbc3 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.fst @@ -0,0 +1,115 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Hash_functions.Portable in + let open Libcrux_ml_kem.Variant in + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Traits in + () + +let decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + = + Libcrux_ml_kem.Ind_cca.Unpacked.decapsulate v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE + v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) key_pair ciphertext + +let encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Unpacked.encapsulate v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE + v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR + v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 + v_ETA2_RANDOMNESS_SIZE #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) public_key randomness + +let generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + (out: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let hax_temp_output, out:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.generate_keypair v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) #Libcrux_ml_kem.Variant.t_MlKem + randomness out + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + in + out + +let keypair_from_private_key + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Libcrux_ml_kem.Ind_cca.Unpacked.keys_from_private_key v_K + v_SECRET_KEY_SIZE + v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT + v_T_AS_NTT_ENCODED_SIZE + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + private_key + key_pair + in + key_pair + +let unpack_public_key + (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.unpack_public_key v_K + v_T_AS_NTT_ENCODED_SIZE + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.fsti new file mode 100644 index 000000000..f406d6a8f --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.fsti @@ -0,0 +1,115 @@ +module Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Hash_functions.Portable in + let open Libcrux_ml_kem.Variant in + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Unpacked decapsulate +val decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + : Prims.Pure (t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K /\ + v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Unpacked encapsulate +val encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + (requires + Spec.MLKEM.is_rank v_K /\ v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + v_C1_SIZE == Spec.MLKEM.v_C1_SIZE v_K /\ v_C2_SIZE == Spec.MLKEM.v_C2_SIZE v_K /\ + v_VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR v_K /\ + v_VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + v_VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE v_K /\ v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v_ETA2 == Spec.MLKEM.v_ETA2 v_K /\ + v_ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Generate a key pair +val generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) + (out: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (requires + Spec.MLKEM.is_rank v_K /\ v_CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_ETA1 == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Take a serialized private key and generate an unpacked key pair from it. +val keypair_from_private_key + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpack_public_key + (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked v_K + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (requires + Spec.MLKEM.is_rank v_K /\ v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fst index 333f8fbbd..414098242 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Instantiations.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -25,6 +25,15 @@ let validate_private_key private_key ciphertext +let validate_private_key_only + (v_K v_SECRET_KEY_SIZE: usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + = + Libcrux_ml_kem.Ind_cca.validate_private_key_only v_K + v_SECRET_KEY_SIZE + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) + private_key + let decapsulate (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fsti index b62f5b8f2..19dc4859d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Instantiations.Portable.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Instantiations.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,7 +13,7 @@ let _ = let open Libcrux_ml_kem.Vector.Traits in () -/// Portable private key validation +/// Private key validation val validate_private_key (v_K v_SECRET_KEY_SIZE v_CIPHERTEXT_SIZE: usize) (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) @@ -24,6 +24,15 @@ val validate_private_key v_CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE v_K) (fun _ -> Prims.l_True) +/// Private key validation +val validate_private_key_only + (v_K v_SECRET_KEY_SIZE: usize) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + : Prims.Pure bool + (requires Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K + ) + (fun _ -> Prims.l_True) + /// Portable decapsulate val decapsulate (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: @@ -81,7 +90,7 @@ val generate_keypair v_ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K) (fun _ -> Prims.l_True) -/// Portable public key validation +/// Public key validation val validate_public_key (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fst index 2fbb2ea3d..ca7056f6c 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Multiplexing -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fsti index 4e231ea63..4fc70d000 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Multiplexing.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Multiplexing -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Unpacked.fst index 90b5d0f43..5e641a876 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Unpacked.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Unpacked.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Unpacked -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -7,6 +7,7 @@ let _ = (* This module has implicit dependencies, here we make them explicit. *) (* The implicit dependencies arise from typeclasses instances. *) let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Hash_functions.Portable in let open Libcrux_ml_kem.Ind_cpa.Unpacked in let open Libcrux_ml_kem.Polynomial in let open Libcrux_ml_kem.Types in @@ -32,18 +33,7 @@ let impl_4__public_key (self: t_MlKemKeyPairUnpacked v_K v_Vector) = self.f_public_key -let impl_4__serialized_private_key - (v_K: usize) - (#v_Vector: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i2: - Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) - (self: t_MlKemKeyPairUnpacked v_K v_Vector) - = - let _:Prims.unit = admit () in - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "not yet implemented" - <: - Rust_primitives.Hax.t_Never) +#push-options "--z3rlimit 200" let transpose_a (v_K: usize) @@ -138,6 +128,73 @@ let transpose_a in v_A +#pop-options + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl + (v_K: usize) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + : Core.Default.t_Default (t_MlKemPublicKeyUnpacked v_K v_Vector) = + { + f_default_pre = (fun (_: Prims.unit) -> true); + f_default_post = (fun (_: Prims.unit) (out: t_MlKemPublicKeyUnpacked v_K v_Vector) -> true); + f_default + = + fun (_: Prims.unit) -> + { + f_ind_cpa_public_key + = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K + v_Vector) + #FStar.Tactics.Typeclasses.solve + (); + f_public_key_hash = Rust_primitives.Hax.repeat 0uy (sz 32) + } + <: + t_MlKemPublicKeyUnpacked v_K v_Vector + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_1 + (v_K: usize) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + : Core.Default.t_Default (t_MlKemKeyPairUnpacked v_K v_Vector) = + { + f_default_pre = (fun (_: Prims.unit) -> true); + f_default_post = (fun (_: Prims.unit) (out: t_MlKemKeyPairUnpacked v_K v_Vector) -> true); + f_default + = + fun (_: Prims.unit) -> + { + f_private_key + = + { + f_ind_cpa_private_key + = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPrivateKeyUnpacked v_K + v_Vector) + #FStar.Tactics.Typeclasses.solve + (); + f_implicit_rejection_value = Rust_primitives.Hax.repeat 0uy (sz 32) + } + <: + t_MlKemPrivateKeyUnpacked v_K v_Vector; + f_public_key + = + Core.Default.f_default #(t_MlKemPublicKeyUnpacked v_K v_Vector) + #FStar.Tactics.Typeclasses.solve + () + } + <: + t_MlKemKeyPairUnpacked v_K v_Vector + } + let impl_4__new (v_K: usize) (#v_Vector: Type0) @@ -148,6 +205,175 @@ let impl_4__new = Core.Default.f_default #(t_MlKemKeyPairUnpacked v_K v_Vector) #FStar.Tactics.Typeclasses.solve () +let keys_from_private_key + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (key_pair: t_MlKemKeyPairUnpacked v_K v_Vector) + = + let ind_cpa_secret_key, ind_cpa_public_key, ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice + u8 & + t_Slice u8 & + t_Slice u8 & + t_Slice u8) = + Libcrux_ml_kem.Types.unpack_private_key v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE + (private_key.Libcrux_ml_kem.Types.f_value <: t_Slice u8) + in + let key_pair:t_MlKemKeyPairUnpacked v_K v_Vector = + { + key_pair with + f_private_key + = + { + key_pair.f_private_key with + f_ind_cpa_private_key + = + { + key_pair.f_private_key.f_ind_cpa_private_key with + Libcrux_ml_kem.Ind_cpa.Unpacked.f_secret_as_ntt + = + Core.Slice.impl__copy_from_slice #(Libcrux_ml_kem.Polynomial.t_PolynomialRingElement + v_Vector) + key_pair.f_private_key.f_ind_cpa_private_key + .Libcrux_ml_kem.Ind_cpa.Unpacked.f_secret_as_ntt + (Libcrux_ml_kem.Ind_cpa.deserialize_secret_key v_K #v_Vector ind_cpa_secret_key + <: + t_Slice (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector)) + } + <: + Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPrivateKeyUnpacked v_K v_Vector + } + <: + t_MlKemPrivateKeyUnpacked v_K v_Vector + } + <: + t_MlKemKeyPairUnpacked v_K v_Vector + in + let key_pair:t_MlKemKeyPairUnpacked v_K v_Vector = + { + key_pair with + f_public_key + = + { + key_pair.f_public_key with + f_ind_cpa_public_key + = + Libcrux_ml_kem.Ind_cpa.build_unpacked_public_key_mut v_K + v_T_AS_NTT_ENCODED_SIZE + #v_Vector + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) + ind_cpa_public_key + key_pair.f_public_key.f_ind_cpa_public_key + } + <: + t_MlKemPublicKeyUnpacked v_K v_Vector + } + <: + t_MlKemKeyPairUnpacked v_K v_Vector + in + let key_pair:t_MlKemKeyPairUnpacked v_K v_Vector = + { + key_pair with + f_public_key + = + { + key_pair.f_public_key with + f_public_key_hash + = + Core.Slice.impl__copy_from_slice #u8 + key_pair.f_public_key.f_public_key_hash + ind_cpa_public_key_hash + } + <: + t_MlKemPublicKeyUnpacked v_K v_Vector + } + <: + t_MlKemKeyPairUnpacked v_K v_Vector + in + let key_pair:t_MlKemKeyPairUnpacked v_K v_Vector = + { + key_pair with + f_private_key + = + { + key_pair.f_private_key with + f_implicit_rejection_value + = + Core.Slice.impl__copy_from_slice #u8 + key_pair.f_private_key.f_implicit_rejection_value + implicit_rejection_value + } + <: + t_MlKemPrivateKeyUnpacked v_K v_Vector + } + <: + t_MlKemKeyPairUnpacked v_K v_Vector + in + let key_pair:t_MlKemKeyPairUnpacked v_K v_Vector = + { + key_pair with + f_public_key + = + { + key_pair.f_public_key with + f_ind_cpa_public_key + = + { + key_pair.f_public_key.f_ind_cpa_public_key with + Libcrux_ml_kem.Ind_cpa.Unpacked.f_seed_for_A + = + Core.Slice.impl__copy_from_slice #u8 + key_pair.f_public_key.f_ind_cpa_public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_seed_for_A + (ind_cpa_public_key.[ { Core.Ops.Range.f_start = v_T_AS_NTT_ENCODED_SIZE } + <: + Core.Ops.Range.t_RangeFrom usize ] + <: + t_Slice u8) + } + <: + Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector + } + <: + t_MlKemPublicKeyUnpacked v_K v_Vector + } + <: + t_MlKemKeyPairUnpacked v_K v_Vector + in + key_pair + +let impl_4__from_private_key + (v_K: usize) + (#v_Vector: Type0) + (v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + = + let out:t_MlKemKeyPairUnpacked v_K v_Vector = + Core.Default.f_default #(t_MlKemKeyPairUnpacked v_K v_Vector) + #FStar.Tactics.Typeclasses.solve + () + in + let out:t_MlKemKeyPairUnpacked v_K v_Vector = + keys_from_private_key v_K + v_SECRET_KEY_SIZE + v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT + v_T_AS_NTT_ENCODED_SIZE + #v_Vector + private_key + out + in + out + let unpack_public_key (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) (#v_Hasher #v_Vector: Type0) @@ -333,7 +559,7 @@ let encapsulate <: (Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) -let impl_3__serialized_public_key_mut +let impl_3__serialized_mut (v_K: usize) (#v_Vector: Type0) (v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) @@ -374,7 +600,7 @@ let impl_4__serialized_public_key_mut let hax_temp_output, serialized:(Prims.unit & Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) = (), - impl_3__serialized_public_key_mut v_K + impl_3__serialized_mut v_K #v_Vector v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE @@ -385,7 +611,7 @@ let impl_4__serialized_public_key_mut in serialized -let impl_3__serialized_public_key +let impl_3__serialized (v_K: usize) (#v_Vector: Type0) (v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) @@ -394,8 +620,8 @@ let impl_3__serialized_public_key Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self: t_MlKemPublicKeyUnpacked v_K v_Vector) = - Core.Convert.f_into #(t_Array u8 v_PUBLIC_KEY_SIZE) - #(Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + Core.Convert.f_from #(Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + #(t_Array u8 v_PUBLIC_KEY_SIZE) #FStar.Tactics.Typeclasses.solve (Libcrux_ml_kem.Ind_cpa.serialize_public_key v_K v_RANKED_BYTES_PER_RING_ELEMENT @@ -415,13 +641,13 @@ let impl_4__serialized_public_key Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) (self: t_MlKemKeyPairUnpacked v_K v_Vector) = - impl_3__serialized_public_key v_K + impl_3__serialized v_K #v_Vector v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE self.f_public_key -#push-options "--z3rlimit 200 --ext context_pruning" +#push-options "--z3rlimit 800 --ext context_pruning" let generate_keypair (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: @@ -599,6 +825,72 @@ let generate_keypair #pop-options +let impl_4__serialized_private_key_mut + (v_K: usize) + (#v_Vector: Type0) + (v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (self: t_MlKemKeyPairUnpacked v_K v_Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) + = + let ind_cpa_private_key, ind_cpa_public_key:(t_Array u8 v_CPA_PRIVATE_KEY_SIZE & + t_Array u8 v_PUBLIC_KEY_SIZE) = + Libcrux_ml_kem.Ind_cpa.serialize_unpacked_secret_key v_K + v_CPA_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_RANKED_BYTES_PER_RING_ELEMENT + #v_Vector + self.f_public_key.f_ind_cpa_public_key + self.f_private_key.f_ind_cpa_private_key + in + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE = + { + serialized with + Libcrux_ml_kem.Types.f_value + = + Libcrux_ml_kem.Ind_cca.serialize_kem_secret_key_mut v_K + v_PRIVATE_KEY_SIZE + #(Libcrux_ml_kem.Hash_functions.Portable.t_PortableHash v_K) + (ind_cpa_private_key <: t_Slice u8) + (ind_cpa_public_key <: t_Slice u8) + (self.f_private_key.f_implicit_rejection_value <: t_Slice u8) + serialized.Libcrux_ml_kem.Types.f_value + } + <: + Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE + in + serialized + +let impl_4__serialized_private_key + (v_K: usize) + (#v_Vector: Type0) + (v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT: + usize) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (self: t_MlKemKeyPairUnpacked v_K v_Vector) + = + let sk:Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE = + Core.Default.f_default #(Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) + #FStar.Tactics.Typeclasses.solve + () + in + let sk:Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE = + impl_4__serialized_private_key_mut v_K + #v_Vector + v_CPA_PRIVATE_KEY_SIZE + v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_RANKED_BYTES_PER_RING_ELEMENT + self + sk + in + sk + #push-options "--z3rlimit 200 --ext context_pruning --z3refresh" let decapsulate diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Unpacked.fsti index 6bccf5010..85ebcd273 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Unpacked.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.Unpacked.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca.Unpacked -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -7,6 +7,7 @@ let _ = (* This module has implicit dependencies, here we make them explicit. *) (* The implicit dependencies arise from typeclasses instances. *) let open Libcrux_ml_kem.Hash_functions in + let open Libcrux_ml_kem.Hash_functions.Portable in let open Libcrux_ml_kem.Ind_cpa.Unpacked in let open Libcrux_ml_kem.Polynomial in let open Libcrux_ml_kem.Types in @@ -54,14 +55,6 @@ val impl_4__public_key (self: t_MlKemKeyPairUnpacked v_K v_Vector) : Prims.Pure (t_MlKemPublicKeyUnpacked v_K v_Vector) Prims.l_True (fun _ -> Prims.l_True) -/// Get the serialized private key. -val impl_4__serialized_private_key - (v_K: usize) - (#v_Vector: Type0) - {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} - (self: t_MlKemKeyPairUnpacked v_K v_Vector) - : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_K) Prims.l_True (fun _ -> Prims.l_True) - val transpose_a (v_K: usize) (#v_Vector: Type0) @@ -84,69 +77,18 @@ val transpose_a Seq.index (Seq.index result i) j == Seq.index (Seq.index ind_cpa_a j) i)) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl +val impl (v_K: usize) (#v_Vector: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i1: - Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) - : Core.Default.t_Default (t_MlKemPublicKeyUnpacked v_K v_Vector) = - { - f_default_pre = (fun (_: Prims.unit) -> true); - f_default_post = (fun (_: Prims.unit) (out: t_MlKemPublicKeyUnpacked v_K v_Vector) -> true); - f_default - = - fun (_: Prims.unit) -> - { - f_ind_cpa_public_key - = - Core.Default.f_default #(Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K - v_Vector) - #FStar.Tactics.Typeclasses.solve - (); - f_public_key_hash = Rust_primitives.Hax.repeat 0uy (sz 32) - } - <: - t_MlKemPublicKeyUnpacked v_K v_Vector - } + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + : Core.Default.t_Default (t_MlKemPublicKeyUnpacked v_K v_Vector) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_1 +val impl_1 (v_K: usize) (#v_Vector: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i1: - Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) - : Core.Default.t_Default (t_MlKemKeyPairUnpacked v_K v_Vector) = - { - f_default_pre = (fun (_: Prims.unit) -> true); - f_default_post = (fun (_: Prims.unit) (out: t_MlKemKeyPairUnpacked v_K v_Vector) -> true); - f_default - = - fun (_: Prims.unit) -> - { - f_private_key - = - { - f_ind_cpa_private_key - = - Core.Default.f_default #(Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPrivateKeyUnpacked v_K - v_Vector) - #FStar.Tactics.Typeclasses.solve - (); - f_implicit_rejection_value = Rust_primitives.Hax.repeat 0uy (sz 32) - } - <: - t_MlKemPrivateKeyUnpacked v_K v_Vector; - f_public_key - = - Core.Default.f_default #(t_MlKemPublicKeyUnpacked v_K v_Vector) - #FStar.Tactics.Typeclasses.solve - () - } - <: - t_MlKemKeyPairUnpacked v_K v_Vector - } + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + : Core.Default.t_Default (t_MlKemKeyPairUnpacked v_K v_Vector) /// Create a new empty unpacked key pair. val impl_4__new: @@ -156,6 +98,40 @@ val impl_4__new: Prims.unit -> Prims.Pure (t_MlKemKeyPairUnpacked v_K v_Vector) Prims.l_True (fun _ -> Prims.l_True) +/// Take a serialized private key and generate an unpacked key pair from it. +val keys_from_private_key + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (key_pair: t_MlKemKeyPairUnpacked v_K v_Vector) + : Prims.Pure (t_MlKemKeyPairUnpacked v_K v_Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) + +/// Take a serialized private key and generate an unpacked key pair from it. +val impl_4__from_private_key + (v_K: usize) + (#v_Vector: Type0) + (v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_T_AS_NTT_ENCODED_SIZE: + usize) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + : Prims.Pure (t_MlKemKeyPairUnpacked v_K v_Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K) + (fun _ -> Prims.l_True) + /// Generate an unpacked key from a serialized key. val unpack_public_key (v_K v_T_AS_NTT_ENCODED_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) @@ -227,7 +203,7 @@ val encapsulate ciphertext_result.f_value == ciphertext /\ shared_secret_array == shared_secret) /// Get the serialized public key. -val impl_3__serialized_public_key_mut +val impl_3__serialized_mut (v_K: usize) (#v_Vector: Type0) (v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) @@ -289,7 +265,7 @@ val impl_4__serialized_public_key_mut self.f_public_key.f_ind_cpa_public_key.f_seed_for_A) /// Get the serialized public key. -val impl_3__serialized_public_key +val impl_3__serialized (v_K: usize) (#v_Vector: Type0) (v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) @@ -373,6 +349,39 @@ val generate_keypair m_A /\ out_future.f_public_key.f_public_key_hash == public_key_hash /\ out_future.f_private_key.f_implicit_rejection_value == implicit_rejection_value) +/// Get the serialized private key. +val impl_4__serialized_private_key_mut + (v_K: usize) + (#v_Vector: Type0) + (v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT: + usize) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (self: t_MlKemKeyPairUnpacked v_K v_Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) + (requires + Spec.MLKEM.is_rank v_K /\ v_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K) + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val impl_4__serialized_private_key + (v_K: usize) + (#v_Vector: Type0) + (v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT: + usize) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (self: t_MlKemKeyPairUnpacked v_K v_Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) + (requires + Spec.MLKEM.is_rank v_K /\ v_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + v_CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + v_RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K) + (fun _ -> Prims.l_True) + val decapsulate (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fst index 84a0cd81c..a6ffee609 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -12,14 +12,15 @@ let _ = let open Libcrux_ml_kem.Vector.Traits in () -let validate_private_key - (v_K v_SECRET_KEY_SIZE v_CIPHERTEXT_SIZE: usize) +#push-options "--z3rlimit 300" + +let validate_private_key_only + (v_K v_SECRET_KEY_SIZE: usize) (#v_Hasher: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) - (v__ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) = let t:t_Array u8 (sz 32) = Libcrux_ml_kem.Hash_functions.f_H #v_Hasher @@ -44,20 +45,36 @@ let validate_private_key in t =. expected +#pop-options + +#push-options "--z3rlimit 300" + +let validate_private_key + (v_K v_SECRET_KEY_SIZE v_CIPHERTEXT_SIZE: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (v__ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + = validate_private_key_only v_K v_SECRET_KEY_SIZE #v_Hasher private_key + +#pop-options + #push-options "--z3rlimit 150" -let serialize_kem_secret_key +let serialize_kem_secret_key_mut (v_K v_SERIALIZED_KEY_LEN: usize) (#v_Hasher: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) (private_key public_key implicit_rejection_value: t_Slice u8) + (serialized: t_Array u8 v_SERIALIZED_KEY_LEN) = - let out:t_Array u8 v_SERIALIZED_KEY_LEN = Rust_primitives.Hax.repeat 0uy v_SERIALIZED_KEY_LEN in let pointer:usize = sz 0 in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + let serialized:t_Array u8 v_SERIALIZED_KEY_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = pointer +! (Core.Slice.impl__len #u8 private_key <: usize) <: usize @@ -65,7 +82,7 @@ let serialize_kem_secret_key <: Core.Ops.Range.t_Range usize) (Core.Slice.impl__copy_from_slice #u8 - (out.[ { + (serialized.[ { Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = @@ -80,8 +97,8 @@ let serialize_kem_secret_key t_Slice u8) in let pointer:usize = pointer +! (Core.Slice.impl__len #u8 private_key <: usize) in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + let serialized:t_Array u8 v_SERIALIZED_KEY_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = pointer +! (Core.Slice.impl__len #u8 public_key <: usize) <: usize @@ -89,7 +106,7 @@ let serialize_kem_secret_key <: Core.Ops.Range.t_Range usize) (Core.Slice.impl__copy_from_slice #u8 - (out.[ { + (serialized.[ { Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = @@ -104,8 +121,8 @@ let serialize_kem_secret_key t_Slice u8) in let pointer:usize = pointer +! (Core.Slice.impl__len #u8 public_key <: usize) in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + let serialized:t_Array u8 v_SERIALIZED_KEY_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = pointer +! Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE <: usize @@ -113,7 +130,7 @@ let serialize_kem_secret_key <: Core.Ops.Range.t_Range usize) (Core.Slice.impl__copy_from_slice #u8 - (out.[ { + (serialized.[ { Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = pointer +! Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE <: usize } @@ -131,8 +148,8 @@ let serialize_kem_secret_key t_Slice u8) in let pointer:usize = pointer +! Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + let serialized:t_Array u8 v_SERIALIZED_KEY_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range serialized ({ Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end @@ -142,7 +159,7 @@ let serialize_kem_secret_key <: Core.Ops.Range.t_Range usize) (Core.Slice.impl__copy_from_slice #u8 - (out.[ { + (serialized.[ { Core.Ops.Range.f_start = pointer; Core.Ops.Range.f_end = @@ -158,16 +175,16 @@ let serialize_kem_secret_key in let _:Prims.unit = let open Spec.Utils in - assert ((Seq.slice out 0 (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K))) + assert ((Seq.slice serialized 0 (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K))) `Seq.equal` private_key); - assert ((Seq.slice out + assert ((Seq.slice serialized (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K)) (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K +! Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K))) `Seq.equal` public_key); - assert ((Seq.slice out + assert ((Seq.slice serialized (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K +! Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K)) (v #usize_inttype @@ -175,7 +192,7 @@ let serialize_kem_secret_key Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE))) `Seq.equal` (Libcrux_ml_kem.Hash_functions.f_H #v_Hasher #v_K public_key)); - assert (Seq.slice out + assert (Seq.slice serialized (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K +! Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K +! Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE)) @@ -184,18 +201,42 @@ let serialize_kem_secret_key Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE +! Spec.MLKEM.v_SHARED_SECRET_SIZE)) == implicit_rejection_value); - lemma_slice_append_4 out + lemma_slice_append_4 serialized private_key public_key (Libcrux_ml_kem.Hash_functions.f_H #v_Hasher #v_K public_key) implicit_rejection_value in - out + serialized #pop-options #push-options "--z3rlimit 150" +let serialize_kem_secret_key + (v_K v_SERIALIZED_KEY_LEN: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (private_key public_key implicit_rejection_value: t_Slice u8) + = + let out:t_Array u8 v_SERIALIZED_KEY_LEN = Rust_primitives.Hax.repeat 0uy v_SERIALIZED_KEY_LEN in + let out:t_Array u8 v_SERIALIZED_KEY_LEN = + serialize_kem_secret_key_mut v_K + v_SERIALIZED_KEY_LEN + #v_Hasher + private_key + public_key + implicit_rejection_value + out + in + out + +#pop-options + +#push-options "--z3rlimit 300" + let encapsulate (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: usize) @@ -316,6 +357,8 @@ let validate_public_key in public_key =. public_key_serialized +#push-options "--z3rlimit 300" + let generate_keypair (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) @@ -375,6 +418,8 @@ let generate_keypair <: Libcrux_ml_kem.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) +#pop-options + #push-options "--z3rlimit 500" let decapsulate @@ -395,16 +440,14 @@ let decapsulate assert (v v_CIPHERTEXT_SIZE == v v_IMPLICIT_REJECTION_HASH_INPUT_SIZE - v Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE) in - let ind_cpa_secret_key, secret_key:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at #u8 + let ind_cpa_secret_key, ind_cpa_public_key, ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice + u8 & + t_Slice u8 & + t_Slice u8 & + t_Slice u8) = + Libcrux_ml_kem.Types.unpack_private_key v_CPA_SECRET_KEY_SIZE + v_PUBLIC_KEY_SIZE (private_key.Libcrux_ml_kem.Types.f_value <: t_Slice u8) - v_CPA_SECRET_KEY_SIZE - in - let ind_cpa_public_key, secret_key:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at #u8 secret_key v_PUBLIC_KEY_SIZE - in - let ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at #u8 secret_key Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE in let _:Prims.unit = assert (ind_cpa_secret_key == slice private_key.f_value (sz 0) v_CPA_SECRET_KEY_SIZE); diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fsti index cc03d69ee..057295e89 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cca.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cca -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -20,6 +20,18 @@ let v_KEY_GENERATION_SEED_SIZE: usize = Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE +! Libcrux_ml_kem.Constants.v_SHARED_SECRET_SIZE +/// Validate an ML-KEM private key. +/// This implements the Hash check in 7.3 3. +val validate_private_key_only + (v_K v_SECRET_KEY_SIZE: usize) + (#v_Hasher: Type0) + {| i1: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + : Prims.Pure bool + (requires Spec.MLKEM.is_rank v_K /\ v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K + ) + (fun _ -> Prims.l_True) + /// Validate an ML-KEM private key. /// This implements the Hash check in 7.3 3. /// Note that the size checks in 7.2 1 and 2 are covered by the `SECRET_KEY_SIZE` @@ -37,6 +49,26 @@ val validate_private_key (fun _ -> Prims.l_True) /// Serialize the secret key. +val serialize_kem_secret_key_mut + (v_K v_SERIALIZED_KEY_LEN: usize) + (#v_Hasher: Type0) + {| i1: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} + (private_key public_key implicit_rejection_value: t_Slice u8) + (serialized: t_Array u8 v_SERIALIZED_KEY_LEN) + : Prims.Pure (t_Array u8 v_SERIALIZED_KEY_LEN) + (requires + Spec.MLKEM.is_rank v_K /\ v_SERIALIZED_KEY_LEN == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\ + Core.Slice.impl__len #u8 private_key == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\ + Core.Slice.impl__len #u8 public_key == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\ + Core.Slice.impl__len #u8 implicit_rejection_value == Spec.MLKEM.v_SHARED_SECRET_SIZE) + (ensures + fun serialized_future -> + let serialized_future:t_Array u8 v_SERIALIZED_KEY_LEN = serialized_future in + serialized_future == + Seq.append private_key + (Seq.append public_key (Seq.append (Spec.Utils.v_H public_key) implicit_rejection_value) + )) + val serialize_kem_secret_key (v_K v_SERIALIZED_KEY_LEN: usize) (#v_Hasher: Type0) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.Unpacked.fst new file mode 100644 index 000000000..ef0c39424 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.Unpacked.fst @@ -0,0 +1,74 @@ +module Libcrux_ml_kem.Ind_cpa.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Traits in + () + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl + (v_K: usize) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + : Core.Default.t_Default (t_IndCpaPrivateKeyUnpacked v_K v_Vector) = + { + f_default_pre = (fun (_: Prims.unit) -> true); + f_default_post = (fun (_: Prims.unit) (out: t_IndCpaPrivateKeyUnpacked v_K v_Vector) -> true); + f_default + = + fun (_: Prims.unit) -> + { + f_secret_as_ntt + = + Rust_primitives.Hax.repeat (Libcrux_ml_kem.Polynomial.impl_2__ZERO #v_Vector () + <: + Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K + } + <: + t_IndCpaPrivateKeyUnpacked v_K v_Vector + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_1 + (v_K: usize) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + : Core.Default.t_Default (t_IndCpaPublicKeyUnpacked v_K v_Vector) = + { + f_default_pre = (fun (_: Prims.unit) -> true); + f_default_post = (fun (_: Prims.unit) (out: t_IndCpaPublicKeyUnpacked v_K v_Vector) -> true); + f_default + = + fun (_: Prims.unit) -> + { + f_t_as_ntt + = + Rust_primitives.Hax.repeat (Libcrux_ml_kem.Polynomial.impl_2__ZERO #v_Vector () + <: + Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K; + f_seed_for_A = Rust_primitives.Hax.repeat 0uy (sz 32); + f_A + = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat (Libcrux_ml_kem.Polynomial.impl_2__ZERO + #v_Vector + () + <: + Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) + v_K + <: + t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + v_K + } + <: + t_IndCpaPublicKeyUnpacked v_K v_Vector + } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.Unpacked.fsti index b7e0c4efc..d627f74c8 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.Unpacked.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.Unpacked.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cpa.Unpacked -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -24,65 +24,15 @@ type t_IndCpaPublicKeyUnpacked } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl +val impl (v_K: usize) (#v_Vector: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i1: - Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) - : Core.Default.t_Default (t_IndCpaPrivateKeyUnpacked v_K v_Vector) = - { - f_default_pre = (fun (_: Prims.unit) -> true); - f_default_post = (fun (_: Prims.unit) (out: t_IndCpaPrivateKeyUnpacked v_K v_Vector) -> true); - f_default - = - fun (_: Prims.unit) -> - { - f_secret_as_ntt - = - Rust_primitives.Hax.repeat (Libcrux_ml_kem.Polynomial.impl_2__ZERO #v_Vector () - <: - Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) - v_K - } - <: - t_IndCpaPrivateKeyUnpacked v_K v_Vector - } + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + : Core.Default.t_Default (t_IndCpaPrivateKeyUnpacked v_K v_Vector) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_1 +val impl_1 (v_K: usize) (#v_Vector: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i1: - Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) - : Core.Default.t_Default (t_IndCpaPublicKeyUnpacked v_K v_Vector) = - { - f_default_pre = (fun (_: Prims.unit) -> true); - f_default_post = (fun (_: Prims.unit) (out: t_IndCpaPublicKeyUnpacked v_K v_Vector) -> true); - f_default - = - fun (_: Prims.unit) -> - { - f_t_as_ntt - = - Rust_primitives.Hax.repeat (Libcrux_ml_kem.Polynomial.impl_2__ZERO #v_Vector () - <: - Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) - v_K; - f_seed_for_A = Rust_primitives.Hax.repeat 0uy (sz 32); - f_A - = - Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat (Libcrux_ml_kem.Polynomial.impl_2__ZERO - #v_Vector - () - <: - Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) - v_K - <: - t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) - v_K - } - <: - t_IndCpaPublicKeyUnpacked v_K v_Vector - } + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + : Core.Default.t_Default (t_IndCpaPublicKeyUnpacked v_K v_Vector) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fst index 29146d11c..073e16e7d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cpa -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -80,7 +80,90 @@ let deserialize_secret_key #pop-options -#push-options "--max_fuel 10 --z3rlimit 1000 --ext context_pruning --z3refresh --split_queries always" +let build_unpacked_public_key_mut + (v_K v_T_AS_NTT_ENCODED_SIZE: usize) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (public_key: t_Slice u8) + (unpacked_public_key: Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector) + = + let unpacked_public_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = + { + unpacked_public_key with + Libcrux_ml_kem.Ind_cpa.Unpacked.f_t_as_ntt + = + Libcrux_ml_kem.Serialize.deserialize_ring_elements_reduced v_K + #v_Vector + (public_key.[ { Core.Ops.Range.f_end = v_T_AS_NTT_ENCODED_SIZE } + <: + Core.Ops.Range.t_RangeTo usize ] + <: + t_Slice u8) + unpacked_public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_t_as_ntt + } + <: + Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector + in + let seed:t_Slice u8 = + public_key.[ { Core.Ops.Range.f_start = v_T_AS_NTT_ENCODED_SIZE } + <: + Core.Ops.Range.t_RangeFrom usize ] + in + let _:Prims.unit = + Lib.Sequence.eq_intro #u8 + #32 + seed + (Seq.slice (Libcrux_ml_kem.Utils.into_padded_array (sz 34) seed) 0 32) + in + let unpacked_public_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = + { + unpacked_public_key with + Libcrux_ml_kem.Ind_cpa.Unpacked.f_A + = + Libcrux_ml_kem.Matrix.sample_matrix_A v_K + #v_Vector + #v_Hasher + unpacked_public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_A + (Libcrux_ml_kem.Utils.into_padded_array (sz 34) seed <: t_Array u8 (sz 34)) + false + } + <: + Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector + in + unpacked_public_key + +let build_unpacked_public_key + (v_K v_T_AS_NTT_ENCODED_SIZE: usize) + (#v_Vector #v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (public_key: t_Slice u8) + = + let unpacked_public_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector) + #FStar.Tactics.Typeclasses.solve + () + in + let unpacked_public_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = + build_unpacked_public_key_mut v_K + v_T_AS_NTT_ENCODED_SIZE + #v_Vector + #v_Hasher + public_key + unpacked_public_key + in + unpacked_public_key + +#push-options "--max_fuel 15 --z3rlimit 1500 --ext context_pruning --z3refresh --split_queries always" let sample_ring_element_cbd (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) @@ -105,40 +188,11 @@ let sample_ring_element_cbd in let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = Rust_primitives.Hax.repeat prf_input v_K in let v__domain_separator_init:u8 = domain_separator in - let v__prf_inputs_init:t_Array (t_Array u8 (sz 33)) v_K = prf_inputs in - let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = - Rust_primitives.Hax.Folds.fold_range (sz 0) - v_K - (fun temp_0_ i -> - let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = temp_0_ in - let i:usize = i in - v domain_separator == v v__domain_separator_init + v i /\ - (v i < v v_K ==> - (forall (j: nat). - (j >= v i /\ j < v v_K) ==> prf_inputs.[ sz j ] == v__prf_inputs_init.[ sz j ])) /\ - (forall (j: nat). - j < v i ==> - v (Seq.index (Seq.index prf_inputs j) 32) == v v__domain_separator_init + j /\ - Seq.slice (Seq.index prf_inputs j) 0 32 == - Seq.slice (Seq.index v__prf_inputs_init j) 0 32)) - (domain_separator, prf_inputs <: (u8 & t_Array (t_Array u8 (sz 33)) v_K)) - (fun temp_0_ i -> - let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = temp_0_ in - let i:usize = i in - let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize prf_inputs - i - (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (prf_inputs.[ i ] - <: - t_Array u8 (sz 33)) - (sz 32) - domain_separator - <: - t_Array u8 (sz 33)) - in - let domain_separator:u8 = domain_separator +! 1uy in - domain_separator, prf_inputs <: (u8 & t_Array (t_Array u8 (sz 33)) v_K)) + let tmp0, out:(t_Array (t_Array u8 (sz 33)) v_K & u8) = + Libcrux_ml_kem.Utils.prf_input_inc v_K prf_inputs domain_separator in + let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = tmp0 in + let domain_separator:u8 = out in let _:Prims.unit = let lemma_aux (i: nat{i < v v_K}) : Lemma @@ -212,7 +266,60 @@ let sample_ring_element_cbd #pop-options -#push-options "--max_fuel 10 --z3rlimit 1000 --ext context_pruning --z3refresh --split_queries always" +let sample_vector_cbd_then_ntt_helper_1 + (v_K: usize) + (prf_inputs: t_Array (t_Array u8 (sz 33)) v_K) + (prf_input: t_Array u8 (sz 33)) + (domain_separator: u8) : Lemma + (requires Spec.MLKEM.is_rank v_K /\ v domain_separator < 2 * v v_K /\ + (forall (i: nat). i < v v_K ==> + v (Seq.index (Seq.index prf_inputs i) 32) == v domain_separator + i /\ + Seq.slice (Seq.index prf_inputs i) 0 32 == Seq.slice prf_input 0 32)) + (ensures prf_inputs == createi v_K + (Spec.MLKEM.sample_vector_cbd1_prf_input #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator)))) + = + let lemma_aux (i: nat{i < v v_K}) : Lemma + (prf_inputs.[ sz i ] == (Seq.append (Seq.slice prf_input 0 32) (Seq.create 1 + (mk_int #u8_inttype (v (domain_separator +! (mk_int #u8_inttype i))))))) = + Lib.Sequence.eq_intro #u8 #33 prf_inputs.[ sz i ] + (Seq.append (Seq.slice prf_input 0 32) + (Seq.create 1 (mk_int #u8_inttype (v domain_separator + i)))) + in + Classical.forall_intro lemma_aux; + Lib.Sequence.eq_intro #(t_Array u8 (sz 33)) #(v v_K) prf_inputs + (createi v_K (Spec.MLKEM.sample_vector_cbd1_prf_input #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator)))) + +let sample_vector_cbd_then_ntt_helper_2 + (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (re_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (prf_input: t_Array u8 (sz 33)) + (domain_separator: u8) : Lemma + (requires Spec.MLKEM.is_rank v_K /\ v_ETA == Spec.MLKEM.v_ETA1 v_K /\ + v_ETA_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\ + v domain_separator < 2 * v v_K /\ + (let prf_outputs = Spec.MLKEM.v_PRFxN v_K v_ETA_RANDOMNESS_SIZE + (createi v_K (Spec.MLKEM.sample_vector_cbd1_prf_input #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator)))) in + forall (i: nat). i < v v_K ==> + Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector re_as_ntt.[ sz i ] == + Spec.MLKEM.poly_ntt (Spec.MLKEM.sample_poly_cbd v_ETA prf_outputs.[ sz i ]))) + (ensures Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector re_as_ntt == + (Spec.MLKEM.sample_vector_cbd_then_ntt #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator)))) + = + reveal_opaque (`%Spec.MLKEM.sample_vector_cbd_then_ntt) (Spec.MLKEM.sample_vector_cbd_then_ntt #v_K); + Lib.Sequence.eq_intro #(Spec.MLKEM.polynomial) #(v v_K) + (Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector re_as_ntt) + (Spec.MLKEM.sample_vector_cbd_then_ntt #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator))) + +#push-options "--max_fuel 15 --z3rlimit 1500 --ext context_pruning --z3refresh --split_queries always" let sample_vector_cbd_then_ntt (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) @@ -229,61 +336,13 @@ let sample_vector_cbd_then_ntt = let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = Rust_primitives.Hax.repeat prf_input v_K in let v__domain_separator_init:u8 = domain_separator in - let v__prf_inputs_init:t_Array (t_Array u8 (sz 33)) v_K = prf_inputs in - let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = - Rust_primitives.Hax.Folds.fold_range (sz 0) - v_K - (fun temp_0_ i -> - let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = temp_0_ in - let i:usize = i in - v domain_separator == v v__domain_separator_init + v i /\ - (v i < v v_K ==> - (forall (j: nat). - (j >= v i /\ j < v v_K) ==> prf_inputs.[ sz j ] == v__prf_inputs_init.[ sz j ])) /\ - (forall (j: nat). - j < v i ==> - v (Seq.index (Seq.index prf_inputs j) 32) == v v__domain_separator_init + j /\ - Seq.slice (Seq.index prf_inputs j) 0 32 == - Seq.slice (Seq.index v__prf_inputs_init j) 0 32)) - (domain_separator, prf_inputs <: (u8 & t_Array (t_Array u8 (sz 33)) v_K)) - (fun temp_0_ i -> - let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = temp_0_ in - let i:usize = i in - let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize prf_inputs - i - (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (prf_inputs.[ i ] - <: - t_Array u8 (sz 33)) - (sz 32) - domain_separator - <: - t_Array u8 (sz 33)) - in - let domain_separator:u8 = domain_separator +! 1uy in - domain_separator, prf_inputs <: (u8 & t_Array (t_Array u8 (sz 33)) v_K)) + let tmp0, out:(t_Array (t_Array u8 (sz 33)) v_K & u8) = + Libcrux_ml_kem.Utils.prf_input_inc v_K prf_inputs domain_separator in + let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = tmp0 in + let domain_separator:u8 = out in let _:Prims.unit = - let lemma_aux (i: nat{i < v v_K}) - : Lemma - (prf_inputs.[ sz i ] == - (Seq.append (Seq.slice prf_input 0 32) - (Seq.create 1 - (mk_int #u8_inttype (v (v__domain_separator_init +! (mk_int #u8_inttype i))))))) = - Lib.Sequence.eq_intro #u8 - #33 - prf_inputs.[ sz i ] - (Seq.append (Seq.slice prf_input 0 32) - (Seq.create 1 (mk_int #u8_inttype (v v__domain_separator_init + i)))) - in - Classical.forall_intro lemma_aux; - Lib.Sequence.eq_intro #(t_Array u8 (sz 33)) - #(v v_K) - prf_inputs - (createi v_K - (Spec.MLKEM.sample_vector_cbd1_prf_input #v_K - (Seq.slice prf_input 0 32) - (sz (v v__domain_separator_init)))) + sample_vector_cbd_then_ntt_helper_1 v_K prf_inputs prf_input v__domain_separator_init in let (prf_outputs: t_Array (t_Array u8 v_ETA_RANDOMNESS_SIZE) v_K):t_Array (t_Array u8 v_ETA_RANDOMNESS_SIZE) v_K = @@ -304,7 +363,8 @@ let sample_vector_cbd_then_ntt forall (j: nat). j < v i ==> Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector re_as_ntt.[ sz j ] == - Spec.MLKEM.poly_ntt (Spec.MLKEM.sample_poly_cbd v_ETA prf_outputs.[ sz j ])) + Spec.MLKEM.poly_ntt (Spec.MLKEM.sample_poly_cbd v_ETA prf_outputs.[ sz j ]) /\ + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range #v_Vector re_as_ntt.[ sz j ]) re_as_ntt (fun re_as_ntt i -> let re_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = @@ -331,12 +391,13 @@ let sample_vector_cbd_then_ntt re_as_ntt) in let _:Prims.unit = - Lib.Sequence.eq_intro #(Spec.MLKEM.polynomial) - #(v v_K) - (Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector re_as_ntt) - (Spec.MLKEM.sample_vector_cbd_then_ntt #v_K - (Seq.slice prf_input 0 32) - (sz (v v__domain_separator_init))) + sample_vector_cbd_then_ntt_helper_2 v_K + v_ETA + v_ETA_RANDOMNESS_SIZE + #v_Vector + re_as_ntt + prf_input + v__domain_separator_init in let hax_temp_output:u8 = domain_separator in re_as_ntt, hax_temp_output @@ -526,7 +587,7 @@ let generate_keypair_unpacked #pop-options -#push-options "--z3rlimit 200 --ext context_pruning --z3refresh" +#push-options "--z3rlimit 800 --ext context_pruning --z3refresh" let compress_then_serialize_u (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) @@ -738,7 +799,8 @@ let encrypt_unpacked let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from ciphertext ({ Core.Ops.Range.f_start = v_C1_LEN } <: Core.Ops.Range.t_RangeFrom usize) - (Libcrux_ml_kem.Serialize.compress_then_serialize_ring_element_v v_V_COMPRESSION_FACTOR + (Libcrux_ml_kem.Serialize.compress_then_serialize_ring_element_v v_K + v_V_COMPRESSION_FACTOR v_C2_LEN #v_Vector v @@ -757,6 +819,8 @@ let encrypt_unpacked #pop-options +#push-options "--z3rlimit 500 --ext context_pruning" + let encrypt (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: usize) @@ -773,58 +837,15 @@ let encrypt = let _:Prims.unit = reveal_opaque (`%Spec.MLKEM.ind_cpa_encrypt) Spec.MLKEM.ind_cpa_encrypt in let unpacked_public_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = - Core.Default.f_default #(Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector) - #FStar.Tactics.Typeclasses.solve - () - in - let unpacked_public_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = - { - unpacked_public_key with - Libcrux_ml_kem.Ind_cpa.Unpacked.f_t_as_ntt - = - Libcrux_ml_kem.Serialize.deserialize_ring_elements_reduced v_K - #v_Vector - (public_key.[ { Core.Ops.Range.f_end = v_T_AS_NTT_ENCODED_SIZE } - <: - Core.Ops.Range.t_RangeTo usize ] - <: - t_Slice u8) - unpacked_public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_t_as_ntt - } - <: - Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector - in - let seed:t_Slice u8 = - public_key.[ { Core.Ops.Range.f_start = v_T_AS_NTT_ENCODED_SIZE } - <: - Core.Ops.Range.t_RangeFrom usize ] - in - let _:Prims.unit = - Lib.Sequence.eq_intro #u8 - #32 - seed - (Seq.slice (Libcrux_ml_kem.Utils.into_padded_array (Rust_primitives.mk_usize 34) seed) 0 32) - in - let unpacked_public_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = - { - unpacked_public_key with - Libcrux_ml_kem.Ind_cpa.Unpacked.f_A - = - Libcrux_ml_kem.Matrix.sample_matrix_A v_K - #v_Vector - #v_Hasher - unpacked_public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_A - (Libcrux_ml_kem.Utils.into_padded_array (sz 34) seed <: t_Array u8 (sz 34)) - false - } - <: - Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector + build_unpacked_public_key v_K v_T_AS_NTT_ENCODED_SIZE #v_Vector #v_Hasher public_key in encrypt_unpacked v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE #v_Vector #v_Hasher unpacked_public_key message randomness -#push-options "--ext context_pruning" +#pop-options + +#push-options "--z3rlimit 800 --ext context_pruning" let deserialize_then_decompress_u (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) @@ -836,7 +857,7 @@ let deserialize_then_decompress_u = let _:Prims.unit = assert (v ((Libcrux_ml_kem.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! v_U_COMPRESSION_FACTOR) /! - Rust_primitives.mk_usize 8) == + sz 8) == v (Spec.MLKEM.v_C1_BLOCK_SIZE v_K)) in let u_as_ntt:t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K = @@ -924,7 +945,8 @@ let decrypt_unpacked deserialize_then_decompress_u v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR #v_Vector ciphertext in let v:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = - Libcrux_ml_kem.Serialize.deserialize_then_decompress_ring_element_v v_V_COMPRESSION_FACTOR + Libcrux_ml_kem.Serialize.deserialize_then_decompress_ring_element_v v_K + v_V_COMPRESSION_FACTOR #v_Vector (ciphertext.[ { Core.Ops.Range.f_start = v_VECTOR_U_ENCODED_SIZE } <: @@ -1060,6 +1082,7 @@ let serialize_secret_key #v_Vector key) == Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector key); + reveal_opaque (`%Spec.MLKEM.vector_encode_12) (Spec.MLKEM.vector_encode_12 #v_K); Lib.Sequence.eq_intro #u8 #(v v_OUT_LEN) out @@ -1148,6 +1171,37 @@ let serialize_public_key in public_key_serialized +#push-options "--admit_smt_queries true" + +let serialize_unpacked_secret_key + (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT: usize) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (public_key: Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector) + (private_key: Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPrivateKeyUnpacked v_K v_Vector) + = + let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = + serialize_public_key v_K + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE + #v_Vector + public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_t_as_ntt + (public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_seed_for_A <: t_Slice u8) + in + let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = + serialize_secret_key v_K + v_PRIVATE_KEY_SIZE + #v_Vector + private_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_secret_as_ntt + in + secret_key_serialized, public_key_serialized + <: + (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) + +#pop-options + let generate_keypair (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) @@ -1187,20 +1241,10 @@ let generate_keypair let private_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPrivateKeyUnpacked v_K v_Vector = tmp0 in let public_key:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = tmp1 in let _:Prims.unit = () in - let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = - serialize_public_key v_K - v_RANKED_BYTES_PER_RING_ELEMENT - v_PUBLIC_KEY_SIZE - #v_Vector - public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_t_as_ntt - (public_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_seed_for_A <: t_Slice u8) - in - let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = - serialize_secret_key v_K - v_PRIVATE_KEY_SIZE - #v_Vector - private_key.Libcrux_ml_kem.Ind_cpa.Unpacked.f_secret_as_ntt - in - secret_key_serialized, public_key_serialized - <: - (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) + serialize_unpacked_secret_key v_K + v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_RANKED_BYTES_PER_RING_ELEMENT + #v_Vector + public_key + private_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fsti index 32c317b57..70c350031 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ind_cpa.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ind_cpa -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -30,6 +30,56 @@ val deserialize_secret_key Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector res == Spec.MLKEM.vector_decode_12 #v_K secret_key) +val build_unpacked_public_key_mut + (v_K v_T_AS_NTT_ENCODED_SIZE: usize) + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} + (public_key: t_Slice u8) + (unpacked_public_key: Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector) + : Prims.Pure (Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + length public_key == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K) + (ensures + fun unpacked_public_key_future -> + let unpacked_public_key_future:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked + v_K v_Vector = + unpacked_public_key_future + in + let t_as_ntt_bytes, seed_for_A = split public_key v_T_AS_NTT_ENCODED_SIZE in + let t_as_ntt = Spec.MLKEM.vector_decode_12 #v_K t_as_ntt_bytes in + let matrix_A_as_ntt, valid = Spec.MLKEM.sample_matrix_A_ntt #v_K seed_for_A in + (Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K + #v_Vector + unpacked_public_key_future.f_t_as_ntt == + t_as_ntt /\ valid ==> + Libcrux_ml_kem.Polynomial.to_spec_matrix_t #v_K #v_Vector unpacked_public_key_future.f_A == + Spec.MLKEM.matrix_transpose matrix_A_as_ntt)) + +val build_unpacked_public_key + (v_K v_T_AS_NTT_ENCODED_SIZE: usize) + (#v_Vector #v_Hasher: Type0) + {| i2: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + {| i3: Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K |} + (public_key: t_Slice u8) + : Prims.Pure (Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector) + (requires + Spec.MLKEM.is_rank v_K /\ v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K /\ + length public_key == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K) + (ensures + fun result -> + let result:Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector = + result + in + let t_as_ntt_bytes, seed_for_A = split public_key v_T_AS_NTT_ENCODED_SIZE in + let t_as_ntt = Spec.MLKEM.vector_decode_12 #v_K t_as_ntt_bytes in + let matrix_A_as_ntt, valid = Spec.MLKEM.sample_matrix_A_ntt #v_K seed_for_A in + (Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector result.f_t_as_ntt == t_as_ntt /\ + valid ==> + Libcrux_ml_kem.Polynomial.to_spec_matrix_t #v_K #v_Vector result.f_A == + Spec.MLKEM.matrix_transpose matrix_A_as_ntt)) + /// Sample a vector of ring elements from a centered binomial distribution. val sample_ring_element_cbd (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) @@ -82,8 +132,8 @@ val sample_vector_cbd_then_ntt (sz (v domain_separator)) /\ (forall (i: nat). i < v v_K ==> - Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index re_as_ntt_future - i))) + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range #v_Vector + (Seq.index re_as_ntt_future i))) val sample_vector_cbd_then_ntt_out (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) @@ -446,6 +496,17 @@ val serialize_public_key (Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector tt_as_ntt)) seed_for_a) +/// Serialize the secret key from the unpacked key pair generation. +val serialize_unpacked_secret_key + (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT: usize) + (#v_Vector: Type0) + {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} + (public_key: Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPublicKeyUnpacked v_K v_Vector) + (private_key: Libcrux_ml_kem.Ind_cpa.Unpacked.t_IndCpaPrivateKeyUnpacked v_K v_Vector) + : Prims.Pure (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) + Prims.l_True + (fun _ -> Prims.l_True) + val generate_keypair (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fst index 7293e04c6..aeccf049f 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Invert_ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -29,6 +29,8 @@ let inv_ntt_layer_int_vec_step_reduce let b:v_Vector = Libcrux_ml_kem.Vector.Traits.montgomery_multiply_fe #v_Vector a_minus_b zeta_r in a, b <: (v_Vector & v_Vector) +#push-options "--z3rlimit 200 --ext context_pruning" + let invert_ntt_at_layer_1_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -107,6 +109,10 @@ let invert_ntt_at_layer_1_ let hax_temp_output:Prims.unit = () <: Prims.unit in zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) +#pop-options + +#push-options "--z3rlimit 200 --ext context_pruning" + let invert_ntt_at_layer_2_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -182,6 +188,10 @@ let invert_ntt_at_layer_2_ let hax_temp_output:Prims.unit = () <: Prims.unit in zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) +#pop-options + +#push-options "--z3rlimit 200 --ext context_pruning" + let invert_ntt_at_layer_3_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -255,6 +265,8 @@ let invert_ntt_at_layer_3_ let hax_temp_output:Prims.unit = () <: Prims.unit in zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) +#pop-options + #push-options "--admit_smt_queries true" let invert_ntt_at_layer_4_plus diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fsti index d83521180..99f466207 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Invert_ntt.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Invert_ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fst index 0fe17e19e..92a2c589d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Matrix -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fsti index 7c0e78e63..8c4c95e96 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Matrix.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Matrix -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.Unpacked.fst new file mode 100644 index 000000000..e37975ff3 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.Unpacked.fst @@ -0,0 +1,200 @@ +module Libcrux_ml_kem.Mlkem1024.Avx2.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Avx2 in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 4) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 4) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 4) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1536) + (sz 1568) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 4) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1536) + (sz 1568) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 4) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1536) + (sz 1568) + public_key + serialized + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.decapsulate (sz 4) (sz 3168) (sz 1536) + (sz 1568) (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) + (sz 128) (sz 1600) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.encapsulate (sz 4) (sz 1568) (sz 1568) + (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key + randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let hax_temp_output, key_pair:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.generate_keypair (sz 4) + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + (sz 2) + (sz 128) + randomness + key_pair + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.keypair_from_private_key (sz 4) + (sz 3168) + (sz 1536) + (sz 1568) + (sz 1536) + (sz 1536) + private_key + key_pair + in + key_pair + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.unpack_public_key (sz 4) + (sz 1536) + (sz 1536) + (sz 1568) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.Unpacked.fsti new file mode 100644 index 000000000..72df96050 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.Unpacked.fsti @@ -0,0 +1,159 @@ +module Libcrux_ml_kem.Mlkem1024.Avx2.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Avx2 in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 1024 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem1024KeyPairUnpacked`] +/// and an [`MlKem1024Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 1024 (unpacked) +/// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem1024PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +/// TODO: The F* prefix opens required modules, it should go away when the following issue is resolved: +/// +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair in "unpacked" form +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fst index 1ed6cc3c1..c9b450487 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem1024.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,9 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.validate_private_key_only (sz 4) (sz 3168) private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fsti index 4f57bcb17..763fc3d71 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Avx2.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem1024.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 1024 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.Unpacked.fst new file mode 100644 index 000000000..92cd21b33 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.Unpacked.fst @@ -0,0 +1,200 @@ +module Libcrux_ml_kem.Mlkem1024.Neon.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Neon in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 4) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 4) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 4) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1536) + (sz 1568) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 4) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1536) + (sz 1568) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 4) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1536) + (sz 1568) + public_key + serialized + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.decapsulate (sz 4) (sz 3168) (sz 1536) + (sz 1568) (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) + (sz 128) (sz 1600) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.encapsulate (sz 4) (sz 1568) (sz 1568) + (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key + randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let hax_temp_output, key_pair:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.generate_keypair (sz 4) + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + (sz 2) + (sz 128) + randomness + key_pair + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.keypair_from_private_key (sz 4) + (sz 3168) + (sz 1536) + (sz 1568) + (sz 1536) + (sz 1536) + private_key + key_pair + in + key_pair + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.unpack_public_key (sz 4) + (sz 1536) + (sz 1536) + (sz 1568) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.Unpacked.fsti new file mode 100644 index 000000000..3b4eb1833 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.Unpacked.fsti @@ -0,0 +1,171 @@ +module Libcrux_ml_kem.Mlkem1024.Neon.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Neon in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 1024 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem1024KeyPairUnpacked`] +/// and an [`MlKem1024Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 1024 (unpacked) +/// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem1024PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +/// TODO: The F* prefix opens required modules, it should go away when the following issue is resolved: +/// +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair in "unpacked" form +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.fst index 8cab7c870..f664c07b3 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem1024.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,9 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.validate_private_key_only (sz 4) (sz 3168) private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.fsti index d71f032a7..097585875 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Neon.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem1024.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 1024 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.Unpacked.fst new file mode 100644 index 000000000..c0f9ff42d --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.Unpacked.fst @@ -0,0 +1,200 @@ +module Libcrux_ml_kem.Mlkem1024.Portable.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 4) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 4) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 4) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1536) + (sz 1568) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 4) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1536) + (sz 1568) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 4) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1536) + (sz 1568) + public_key + serialized + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.decapsulate (sz 4) (sz 3168) (sz 1536) + (sz 1568) (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) + (sz 128) (sz 1600) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.encapsulate (sz 4) (sz 1568) (sz 1568) + (sz 1536) (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key + randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let hax_temp_output, key_pair:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.generate_keypair (sz 4) + (sz 1536) + (sz 3168) + (sz 1568) + (sz 1536) + (sz 2) + (sz 128) + randomness + key_pair + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.keypair_from_private_key (sz 4) + (sz 3168) + (sz 1536) + (sz 1568) + (sz 1536) + (sz 1536) + private_key + key_pair + in + key_pair + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.unpack_public_key (sz 4) + (sz 1536) + (sz 1536) + (sz 1568) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.Unpacked.fsti new file mode 100644 index 000000000..6370203e4 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.Unpacked.fsti @@ -0,0 +1,171 @@ +module Libcrux_ml_kem.Mlkem1024.Portable.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (requires + forall (i: nat). + i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 1024 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem1024KeyPairUnpacked`] +/// and an [`MlKem1024Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 1024 (unpacked) +/// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem1024PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +/// TODO: The F* prefix opens required modules, it should go away when the following issue is resolved: +/// +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair in "unpacked" form +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 4) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fst index 60a05dcc1..c093cfc37 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem1024.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,11 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.validate_private_key_only (sz 4) + (sz 3168) + private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fsti index 9ce6a597e..cb06fc90f 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Portable.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem1024.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 3168)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 1024 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Rand.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Rand.fst new file mode 100644 index 000000000..69f4ab0fc --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Rand.fst @@ -0,0 +1,51 @@ +module Libcrux_ml_kem.Mlkem1024.Rand +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Rand_core in + () + +let encapsulate + (#impl_277843321_: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Rand_core.t_RngCore impl_277843321_) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Rand_core.t_CryptoRng impl_277843321_) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (rng: impl_277843321_) + = + let randomness:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let tmp0, tmp1:(impl_277843321_ & t_Array u8 (sz 32)) = + Rand_core.f_fill_bytes #impl_277843321_ #FStar.Tactics.Typeclasses.solve rng randomness + in + let rng:impl_277843321_ = tmp0 in + let randomness:t_Array u8 (sz 32) = tmp1 in + let _:Prims.unit = () in + let hax_temp_output:(Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568) & t_Array u8 (sz 32)) = + Libcrux_ml_kem.Mlkem1024.encapsulate public_key randomness + in + rng, hax_temp_output + <: + (impl_277843321_ & (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568) & t_Array u8 (sz 32))) + +let generate_key_pair + (#impl_277843321_: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Rand_core.t_RngCore impl_277843321_) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Rand_core.t_CryptoRng impl_277843321_) + (rng: impl_277843321_) + = + let randomness:t_Array u8 (sz 64) = Rust_primitives.Hax.repeat 0uy (sz 64) in + let tmp0, tmp1:(impl_277843321_ & t_Array u8 (sz 64)) = + Rand_core.f_fill_bytes #impl_277843321_ #FStar.Tactics.Typeclasses.solve rng randomness + in + let rng:impl_277843321_ = tmp0 in + let randomness:t_Array u8 (sz 64) = tmp1 in + let _:Prims.unit = () in + let hax_temp_output:Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 3168) (sz 1568) = + Libcrux_ml_kem.Mlkem1024.generate_key_pair randomness + in + rng, hax_temp_output + <: + (impl_277843321_ & Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 3168) (sz 1568)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Rand.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Rand.fsti new file mode 100644 index 000000000..b2175b095 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.Rand.fsti @@ -0,0 +1,39 @@ +module Libcrux_ml_kem.Mlkem1024.Rand +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Rand_core in + () + +/// Encapsulate ML-KEM 1024 +/// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem1024PublicKey`]. +/// The random number generator `rng` needs to implement `RngCore` and +/// `CryptoRng` to sample the required randomness internally. +val encapsulate + (#impl_277843321_: Type0) + {| i1: Rand_core.t_RngCore impl_277843321_ |} + {| i2: Rand_core.t_CryptoRng impl_277843321_ |} + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1568)) + (rng: impl_277843321_) + : Prims.Pure + (impl_277843321_ & (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1568) & t_Array u8 (sz 32))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 1024 Key Pair +/// The random number generator `rng` needs to implement `RngCore` and +/// `CryptoRng` to sample the required randomness internally. +/// This function returns an [`MlKem1024KeyPair`]. +val generate_key_pair + (#impl_277843321_: Type0) + {| i1: Rand_core.t_RngCore impl_277843321_ |} + {| i2: Rand_core.t_CryptoRng impl_277843321_ |} + (rng: impl_277843321_) + : Prims.Pure (impl_277843321_ & Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 3168) (sz 1568)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fst index c06297797..c296a0efc 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem1024 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fsti index fa7a134dd..007e5c86f 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem1024.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem1024 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.Unpacked.fst new file mode 100644 index 000000000..a63bcaf11 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.Unpacked.fst @@ -0,0 +1,196 @@ +module Libcrux_ml_kem.Mlkem512.Avx2.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Avx2 in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 2) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 2) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 2) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 768) + (sz 800) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 2) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 768) + (sz 800) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + = + let hax_temp_output, serialized:(Prims.unit & Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 2) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 768) + (sz 800) + public_key + serialized + <: + (Prims.unit & Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.decapsulate (sz 2) (sz 1632) (sz 768) (sz 800) + (sz 768) (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) + (sz 800) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.encapsulate (sz 2) (sz 768) (sz 800) (sz 768) + (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.generate_keypair (sz 2) + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + (sz 3) + (sz 192) + randomness + key_pair + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.keypair_from_private_key (sz 2) + (sz 1632) + (sz 768) + (sz 800) + (sz 768) + (sz 768) + private_key + key_pair + in + key_pair + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.unpack_public_key (sz 2) + (sz 768) + (sz 768) + (sz 800) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.Unpacked.fsti new file mode 100644 index 000000000..21aeb9213 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.Unpacked.fsti @@ -0,0 +1,157 @@ +module Libcrux_ml_kem.Mlkem512.Avx2.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Avx2 in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 512 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem512KeyPairUnpacked`] +/// and an [`MlKem512Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 512 (unpacked) +/// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem512PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair in "unpacked" form +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fst index d84c15890..81867e6a4 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem512.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,9 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.validate_private_key_only (sz 2) (sz 1632) private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fsti index 79530147b..b138131fe 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Avx2.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem512.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 512 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.Unpacked.fst new file mode 100644 index 000000000..1142a8c11 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.Unpacked.fst @@ -0,0 +1,196 @@ +module Libcrux_ml_kem.Mlkem512.Neon.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Neon in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 2) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 2) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 2) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 768) + (sz 800) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 2) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 768) + (sz 800) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + = + let hax_temp_output, serialized:(Prims.unit & Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 2) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 768) + (sz 800) + public_key + serialized + <: + (Prims.unit & Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.decapsulate (sz 2) (sz 1632) (sz 768) (sz 800) + (sz 768) (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) + (sz 800) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.encapsulate (sz 2) (sz 768) (sz 800) (sz 768) + (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.generate_keypair (sz 2) + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + (sz 3) + (sz 192) + randomness + key_pair + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.keypair_from_private_key (sz 2) + (sz 1632) + (sz 768) + (sz 800) + (sz 768) + (sz 768) + private_key + key_pair + in + key_pair + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.unpack_public_key (sz 2) + (sz 768) + (sz 768) + (sz 800) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.Unpacked.fsti new file mode 100644 index 000000000..d6eab98a0 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.Unpacked.fsti @@ -0,0 +1,169 @@ +module Libcrux_ml_kem.Mlkem512.Neon.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Neon in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 512 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem512KeyPairUnpacked`] +/// and an [`MlKem512Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 512 (unpacked) +/// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem512PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair in "unpacked" form +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.fst index 58b2f0dc4..077af75fe 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem512.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,9 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.validate_private_key_only (sz 2) (sz 1632) private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.fsti index 3d846ac51..6886ec966 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Neon.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem512.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 512 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.Unpacked.fst new file mode 100644 index 000000000..ac9e84801 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.Unpacked.fst @@ -0,0 +1,197 @@ +module Libcrux_ml_kem.Mlkem512.Portable.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 2) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 2) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 2) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 768) + (sz 800) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 2) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 768) + (sz 800) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + = + let hax_temp_output, serialized:(Prims.unit & Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) = + (), + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 2) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 768) + (sz 800) + public_key + serialized + <: + (Prims.unit & Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.decapsulate (sz 2) (sz 1632) (sz 768) + (sz 800) (sz 768) (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) + (sz 128) (sz 800) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.encapsulate (sz 2) (sz 768) (sz 800) + (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key + randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.generate_keypair (sz 2) + (sz 768) + (sz 1632) + (sz 800) + (sz 768) + (sz 3) + (sz 192) + randomness + key_pair + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.keypair_from_private_key (sz 2) + (sz 1632) + (sz 768) + (sz 800) + (sz 768) + (sz 768) + private_key + key_pair + in + key_pair + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.unpack_public_key (sz 2) + (sz 768) + (sz 768) + (sz 800) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.Unpacked.fsti new file mode 100644 index 000000000..7f06b0b9c --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.Unpacked.fsti @@ -0,0 +1,169 @@ +module Libcrux_ml_kem.Mlkem512.Portable.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (requires + forall (i: nat). + i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 512 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem512KeyPairUnpacked`] +/// and an [`MlKem512Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 512 (unpacked) +/// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem512PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair in "unpacked" form +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 2) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fst index 97dccb937..4c6c96ff8 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem512.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,11 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.validate_private_key_only (sz 2) + (sz 1632) + private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fsti index eee7fb43d..64d59c955 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Portable.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem512.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 1632)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 512 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Rand.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Rand.fst new file mode 100644 index 000000000..adca30249 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Rand.fst @@ -0,0 +1,49 @@ +module Libcrux_ml_kem.Mlkem512.Rand +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Rand_core in + () + +let encapsulate + (#impl_277843321_: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Rand_core.t_RngCore impl_277843321_) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Rand_core.t_CryptoRng impl_277843321_) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (rng: impl_277843321_) + = + let randomness:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let tmp0, tmp1:(impl_277843321_ & t_Array u8 (sz 32)) = + Rand_core.f_fill_bytes #impl_277843321_ #FStar.Tactics.Typeclasses.solve rng randomness + in + let rng:impl_277843321_ = tmp0 in + let randomness:t_Array u8 (sz 32) = tmp1 in + let _:Prims.unit = () in + let hax_temp_output:(Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768) & t_Array u8 (sz 32)) = + Libcrux_ml_kem.Mlkem512.encapsulate public_key randomness + in + rng, hax_temp_output + <: + (impl_277843321_ & (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768) & t_Array u8 (sz 32))) + +let generate_key_pair + (#impl_277843321_: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Rand_core.t_RngCore impl_277843321_) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Rand_core.t_CryptoRng impl_277843321_) + (rng: impl_277843321_) + = + let randomness:t_Array u8 (sz 64) = Rust_primitives.Hax.repeat 0uy (sz 64) in + let tmp0, tmp1:(impl_277843321_ & t_Array u8 (sz 64)) = + Rand_core.f_fill_bytes #impl_277843321_ #FStar.Tactics.Typeclasses.solve rng randomness + in + let rng:impl_277843321_ = tmp0 in + let randomness:t_Array u8 (sz 64) = tmp1 in + let _:Prims.unit = () in + let hax_temp_output:Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 1632) (sz 800) = + Libcrux_ml_kem.Mlkem512.generate_key_pair randomness + in + rng, hax_temp_output <: (impl_277843321_ & Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 1632) (sz 800)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Rand.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Rand.fsti new file mode 100644 index 000000000..31ef494ee --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.Rand.fsti @@ -0,0 +1,39 @@ +module Libcrux_ml_kem.Mlkem512.Rand +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Rand_core in + () + +/// Encapsulate ML-KEM 512 +/// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem512PublicKey`]. +/// The random number generator `rng` needs to implement `RngCore` and +/// `CryptoRng` to sample the required randomness internally. +val encapsulate + (#impl_277843321_: Type0) + {| i1: Rand_core.t_RngCore impl_277843321_ |} + {| i2: Rand_core.t_CryptoRng impl_277843321_ |} + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 800)) + (rng: impl_277843321_) + : Prims.Pure + (impl_277843321_ & (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 768) & t_Array u8 (sz 32))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 512 Key Pair +/// The random number generator `rng` needs to implement `RngCore` and +/// `CryptoRng` to sample the required randomness internally. +/// This function returns an [`MlKem512KeyPair`]. +val generate_key_pair + (#impl_277843321_: Type0) + {| i1: Rand_core.t_RngCore impl_277843321_ |} + {| i2: Rand_core.t_CryptoRng impl_277843321_ |} + (rng: impl_277843321_) + : Prims.Pure (impl_277843321_ & Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 1632) (sz 800)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fst index db5293cf8..ec76cf211 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem512 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fsti index 40a174dcb..28d905063 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem512.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem512 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.Unpacked.fst new file mode 100644 index 000000000..7788eac55 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.Unpacked.fst @@ -0,0 +1,216 @@ +module Libcrux_ml_kem.Mlkem768.Avx2.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Avx2 in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 3) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 3) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 3) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1152) + (sz 1184) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 3) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1152) + (sz 1184) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 3) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + (sz 1152) + (sz 1184) + public_key + serialized + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.decapsulate (sz 3) (sz 2400) (sz 1152) + (sz 1184) (sz 1088) (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) + (sz 128) (sz 1120) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.encapsulate (sz 3) (sz 1088) (sz 1184) + (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key + randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.generate_keypair (sz 3) + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + (sz 2) + (sz 128) + randomness + key_pair + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.keypair_from_private_key (sz 3) + (sz 2400) + (sz 1152) + (sz 1184) + (sz 1152) + (sz 1152) + private_key + key_pair + in + key_pair + +let public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (pk: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let pk:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector = + Core.Clone.f_clone #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__public_key (sz 3) + #Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector + key_pair + <: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + pk + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.Unpacked.unpack_public_key (sz 3) + (sz 1152) + (sz 1152) + (sz 1184) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.Unpacked.fsti new file mode 100644 index 000000000..26bf0ffd6 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.Unpacked.fsti @@ -0,0 +1,170 @@ +module Libcrux_ml_kem.Mlkem768.Avx2.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Avx2 in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + (forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair + .f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i))) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 768 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem768KeyPairUnpacked`] +/// and an [`MlKem768Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 768 (unpacked) +/// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem768PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair in "unpacked" form. +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + (pk: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Avx2.t_SIMD256Vector) Prims.l_True (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fst index 3ec064b3f..ec517abff 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem768.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,9 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Avx2.validate_private_key_only (sz 3) (sz 2400) private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fsti index 0b2855263..32d3615e9 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Avx2.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem768.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 768 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem768PrivateKey`] and an [`MlKem768Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.Unpacked.fst new file mode 100644 index 000000000..541f0ab82 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.Unpacked.fst @@ -0,0 +1,217 @@ +module Libcrux_ml_kem.Mlkem768.Neon.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Neon in + let open Libcrux_ml_kem.Vector.Neon.Vector_type in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 3) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 3) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 3) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1152) + (sz 1184) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 3) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1152) + (sz 1184) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 3) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + (sz 1152) + (sz 1184) + public_key + serialized + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.decapsulate (sz 3) (sz 2400) (sz 1152) + (sz 1184) (sz 1088) (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) + (sz 128) (sz 1120) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.encapsulate (sz 3) (sz 1088) (sz 1184) + (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key + randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.generate_keypair (sz 3) + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + (sz 2) + (sz 128) + randomness + key_pair + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.keypair_from_private_key (sz 3) + (sz 2400) + (sz 1152) + (sz 1184) + (sz 1152) + (sz 1152) + private_key + key_pair + in + key_pair + +let public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (pk: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let pk:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + Core.Clone.f_clone #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__public_key (sz 3) + #Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector + key_pair + <: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + in + pk + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.Unpacked.unpack_public_key (sz 3) + (sz 1152) + (sz 1152) + (sz 1184) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.Unpacked.fsti new file mode 100644 index 000000000..3fbc5e15c --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.Unpacked.fsti @@ -0,0 +1,185 @@ +module Libcrux_ml_kem.Mlkem768.Neon.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Neon in + let open Libcrux_ml_kem.Vector.Neon.Vector_type in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + (forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair + .f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i))) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 768 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem768KeyPairUnpacked`] +/// and an [`MlKem768Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 768 (unpacked) +/// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem768PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair in "unpacked" form. +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (pk: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.fst index 4608a3923..d6ffc47a4 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem768.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,9 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Neon.validate_private_key_only (sz 3) (sz 2400) private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.fsti index 1b4e3414d..00fc18c11 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Neon.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem768.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 768 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem768PrivateKey`] and an [`MlKem768Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.Unpacked.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.Unpacked.fst new file mode 100644 index 000000000..4588ae4aa --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.Unpacked.fst @@ -0,0 +1,217 @@ +module Libcrux_ml_kem.Mlkem768.Portable.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Portable.Vector_type in + let open Libcrux_ml_kem.Vector.Traits in + () + +let key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key (sz 3) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + key_pair + +let key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_private_key_mut (sz 3) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + key_pair + serialized + in + serialized + +let key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key (sz 3) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1152) + (sz 1184) + key_pair + +let key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__serialized_public_key_mut (sz 3) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1152) + (sz 1184) + key_pair + serialized + in + serialized + +let serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + = + let serialized:Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184) = + Libcrux_ml_kem.Ind_cca.Unpacked.impl_3__serialized_mut (sz 3) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + (sz 1152) + (sz 1184) + public_key + serialized + in + serialized + +let decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.decapsulate (sz 3) (sz 2400) (sz 1152) + (sz 1184) (sz 1088) (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) + (sz 128) (sz 1120) private_key ciphertext + +let encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (randomness: t_Array u8 (sz 32)) + = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.encapsulate (sz 3) (sz 1088) (sz 1184) + (sz 1152) (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key + randomness + +let generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.generate_keypair (sz 3) + (sz 1152) + (sz 2400) + (sz 1184) + (sz 1152) + (sz 2) + (sz 128) + randomness + key_pair + in + key_pair + +let generate_key_pair (randomness: t_Array u8 (sz 64)) = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + in + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + generate_key_pair_mut randomness key_pair + in + key_pair + +let init_key_pair (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + +let init_public_key (_: Prims.unit) = + Core.Default.f_default #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + () + +let key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let key_pair:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.keypair_from_private_key (sz 3) + (sz 2400) + (sz 1152) + (sz 1184) + (sz 1152) + (sz 1152) + private_key + key_pair + in + key_pair + +let public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (pk: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let pk:Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + Core.Clone.f_clone #(Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + #FStar.Tactics.Typeclasses.solve + (Libcrux_ml_kem.Ind_cca.Unpacked.impl_4__public_key (sz 3) + #Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector + key_pair + <: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + in + pk + +let unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + = + let hax_temp_output, unpacked_public_key:(Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) = + (), + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.Unpacked.unpack_public_key (sz 3) + (sz 1152) + (sz 1152) + (sz 1184) + public_key + unpacked_public_key + <: + (Prims.unit & + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + in + unpacked_public_key diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.Unpacked.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.Unpacked.fsti new file mode 100644 index 000000000..e4f2a98e1 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.Unpacked.fsti @@ -0,0 +1,185 @@ +module Libcrux_ml_kem.Mlkem768.Portable.Unpacked +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Ind_cca.Unpacked in + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Portable.Vector_type in + let open Libcrux_ml_kem.Vector.Traits in + () + +/// Get the serialized private key. +val key_pair_serialized_private_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized private key. +val key_pair_serialized_private_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair.f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val key_pair_serialized_public_key_mut + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + (forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index key_pair + .f_public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i))) + (fun _ -> Prims.l_True) + +/// Get the serialized public key. +val serialized_public_key + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (serialized: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (requires + forall (i: nat). + i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index public_key + .f_ind_cpa_public_key + .f_t_as_ntt + i)) + (fun _ -> Prims.l_True) + +/// Decapsulate ML-KEM 768 (unpacked) +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an unpacked key pair of type [`MlKem768KeyPairUnpacked`] +/// and an [`MlKem768Ciphertext`]. +val decapsulate + (private_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Vector.Portable in + let open Libcrux_ml_kem.Vector.Neon in + () + +/// Encapsulate ML-KEM 768 (unpacked) +/// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an unpacked public key of type [`MlKem768PublicKeyUnpacked`], +/// the SHA3-256 hash of this public key, and [`SHARED_SECRET_SIZE`] bytes of `randomness`. +val encapsulate + (public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair in "unpacked" form. +val generate_key_pair_mut + (randomness: t_Array u8 (sz 64)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair in "unpacked" form. +val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked key. +val init_key_pair: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Create a new, empty unpacked public key. +val init_public_key: Prims.unit + -> Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get an unpacked key from a private key. +val key_pair_from_private_mut + (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val public_key + (key_pair: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemKeyPairUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (pk: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Get the unpacked public key. +val unpacked_public_key + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (unpacked_public_key: + Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + : Prims.Pure + (Libcrux_ml_kem.Ind_cca.Unpacked.t_MlKemPublicKeyUnpacked (sz 3) + Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fst index d98e44837..ef78b1c7e 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem768.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -13,6 +13,11 @@ let validate_private_key private_key ciphertext +let validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) = + Libcrux_ml_kem.Ind_cca.Instantiations.Portable.validate_private_key_only (sz 3) + (sz 2400) + private_key + let decapsulate (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fsti index c14954e5d..d503ab893 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Portable.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem768.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -10,6 +10,11 @@ val validate_private_key (ciphertext: Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088)) : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +/// Validate the private key only. +/// Returns `true` if valid, and `false` otherwise. +val validate_private_key_only (private_key: Libcrux_ml_kem.Types.t_MlKemPrivateKey (sz 2400)) + : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) + /// Decapsulate ML-KEM 768 /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem768PrivateKey`] and an [`MlKem768Ciphertext`]. diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Rand.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Rand.fst new file mode 100644 index 000000000..80ac366d4 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Rand.fst @@ -0,0 +1,51 @@ +module Libcrux_ml_kem.Mlkem768.Rand +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Rand_core in + () + +let encapsulate + (#impl_277843321_: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Rand_core.t_RngCore impl_277843321_) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Rand_core.t_CryptoRng impl_277843321_) + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (rng: impl_277843321_) + = + let randomness:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let tmp0, tmp1:(impl_277843321_ & t_Array u8 (sz 32)) = + Rand_core.f_fill_bytes #impl_277843321_ #FStar.Tactics.Typeclasses.solve rng randomness + in + let rng:impl_277843321_ = tmp0 in + let randomness:t_Array u8 (sz 32) = tmp1 in + let _:Prims.unit = () in + let hax_temp_output:(Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) = + Libcrux_ml_kem.Mlkem768.encapsulate public_key randomness + in + rng, hax_temp_output + <: + (impl_277843321_ & (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32))) + +let generate_key_pair + (#impl_277843321_: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: Rand_core.t_RngCore impl_277843321_) + (#[FStar.Tactics.Typeclasses.tcresolve ()] i2: Rand_core.t_CryptoRng impl_277843321_) + (rng: impl_277843321_) + = + let randomness:t_Array u8 (sz 64) = Rust_primitives.Hax.repeat 0uy (sz 64) in + let tmp0, tmp1:(impl_277843321_ & t_Array u8 (sz 64)) = + Rand_core.f_fill_bytes #impl_277843321_ #FStar.Tactics.Typeclasses.solve rng randomness + in + let rng:impl_277843321_ = tmp0 in + let randomness:t_Array u8 (sz 64) = tmp1 in + let _:Prims.unit = () in + let hax_temp_output:Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 2400) (sz 1184) = + Libcrux_ml_kem.Mlkem768.generate_key_pair randomness + in + rng, hax_temp_output + <: + (impl_277843321_ & Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 2400) (sz 1184)) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Rand.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Rand.fsti new file mode 100644 index 000000000..fb034e0f5 --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.Rand.fsti @@ -0,0 +1,39 @@ +module Libcrux_ml_kem.Mlkem768.Rand +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Rand_core in + () + +/// Encapsulate ML-KEM 768 +/// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem768PublicKey`]. +/// The random number generator `rng` needs to implement `RngCore` and +/// `CryptoRng` to sample the required randomness internally. +val encapsulate + (#impl_277843321_: Type0) + {| i1: Rand_core.t_RngCore impl_277843321_ |} + {| i2: Rand_core.t_CryptoRng impl_277843321_ |} + (public_key: Libcrux_ml_kem.Types.t_MlKemPublicKey (sz 1184)) + (rng: impl_277843321_) + : Prims.Pure + (impl_277843321_ & (Libcrux_ml_kem.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32))) + Prims.l_True + (fun _ -> Prims.l_True) + +/// Generate ML-KEM 768 Key Pair +/// The random number generator `rng` needs to implement `RngCore` and +/// `CryptoRng` to sample the required randomness internally. +/// This function returns an [`MlKem768KeyPair`]. +val generate_key_pair + (#impl_277843321_: Type0) + {| i1: Rand_core.t_RngCore impl_277843321_ |} + {| i2: Rand_core.t_CryptoRng impl_277843321_ |} + (rng: impl_277843321_) + : Prims.Pure (impl_277843321_ & Libcrux_ml_kem.Types.t_MlKemKeyPair (sz 2400) (sz 1184)) + Prims.l_True + (fun _ -> Prims.l_True) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fst index 235881a7e..7a9f4607c 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem768 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fsti index 34bfea335..d1d7c217f 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Mlkem768.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Mlkem768 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fst index d974fbef3..2c5a30cb2 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -26,6 +26,8 @@ let ntt_layer_int_vec_step in a, b <: (v_Vector & v_Vector) +#push-options "--z3rlimit 200 --ext context_pruning" + let ntt_at_layer_1_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -104,6 +106,10 @@ let ntt_at_layer_1_ let hax_temp_output:Prims.unit = () <: Prims.unit in zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) +#pop-options + +#push-options "--z3rlimit 200 --ext context_pruning" + let ntt_at_layer_2_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -180,6 +186,10 @@ let ntt_at_layer_2_ let hax_temp_output:Prims.unit = () <: Prims.unit in zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) +#pop-options + +#push-options "--z3rlimit 200 --ext context_pruning" + let ntt_at_layer_3_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -254,6 +264,8 @@ let ntt_at_layer_3_ let hax_temp_output:Prims.unit = () <: Prims.unit in zeta_i, re <: (usize & Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) +#pop-options + #push-options "--admit_smt_queries true" let ntt_at_layer_4_plus diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fsti index 8cf047654..75973c8fb 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Ntt.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -168,7 +168,8 @@ val ntt_binomially_sampled_ring_element fun re_future -> let re_future:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = re_future in Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector re_future == - Spec.MLKEM.poly_ntt (Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector re)) + Spec.MLKEM.poly_ntt (Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector re) /\ + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range #v_Vector re_future) val ntt_vector_u (v_VECTOR_U_COMPRESSION_FACTOR: usize) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fst index 257bb1029..4dcc55b91 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Polynomial -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fsti index 7956d29e4..6ad4d7a0b 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Polynomial.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Polynomial -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fst index 13f72a5df..c50a5c96b 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Sampling -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fsti index 701fc9640..ecaa33053 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Sampling.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Sampling -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fst index ca0e4382e..3066440c8 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Serialize -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -21,6 +21,8 @@ let to_unsigned_field_modulus let _:Prims.unit = admit () (* Panic freedom *) in result +#push-options "--admit_smt_queries true" + let deserialize_then_decompress_11_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -72,6 +74,8 @@ let deserialize_then_decompress_11_ in re +#pop-options + let deserialize_then_decompress_4_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -123,6 +127,8 @@ let deserialize_then_decompress_4_ in re +#push-options "--admit_smt_queries true" + let deserialize_then_decompress_5_ (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -186,6 +192,8 @@ let deserialize_then_decompress_5_ in re +#pop-options + let deserialize_then_decompress_message (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] @@ -241,7 +249,7 @@ let deserialize_then_decompress_message result let deserialize_then_decompress_ring_element_v - (v_COMPRESSION_FACTOR: usize) + (v_K v_COMPRESSION_FACTOR: usize) (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: @@ -777,7 +785,7 @@ let compress_then_serialize_ring_element_u result let compress_then_serialize_ring_element_v - (v_COMPRESSION_FACTOR v_OUT_LEN: usize) + (v_K v_COMPRESSION_FACTOR v_OUT_LEN: usize) (#v_Vector: Type0) (#[FStar.Tactics.Typeclasses.tcresolve ()] i1: diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fsti index 415926dbf..f8382da2d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Serialize.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Serialize -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -75,19 +75,20 @@ val deserialize_then_decompress_message Spec.MLKEM.decode_then_decompress_message serialized) val deserialize_then_decompress_ring_element_v - (v_COMPRESSION_FACTOR: usize) + (v_K v_COMPRESSION_FACTOR: usize) (#v_Vector: Type0) {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (serialized: t_Slice u8) : Prims.Pure (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (requires - (v_COMPRESSION_FACTOR =. sz 4 || v_COMPRESSION_FACTOR =. sz 5) && - (Core.Slice.impl__len #u8 serialized <: usize) =. (sz 32 *! v_COMPRESSION_FACTOR <: usize)) + Spec.MLKEM.is_rank v_K /\ + v_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + Seq.length serialized == 32 * v v_COMPRESSION_FACTOR) (ensures fun result -> let result:Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector = result in Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector result == - Spec.MLKEM.decode_then_decompress_v v_COMPRESSION_FACTOR serialized) + Spec.MLKEM.decode_then_decompress_v #v_K serialized) /// Only use with public values. /// This MUST NOT be used with secret inputs, like its caller `deserialize_ring_elements_reduced`. @@ -224,22 +225,23 @@ val compress_then_serialize_ring_element_u (Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector re)) val compress_then_serialize_ring_element_v - (v_COMPRESSION_FACTOR v_OUT_LEN: usize) + (v_K v_COMPRESSION_FACTOR v_OUT_LEN: usize) (#v_Vector: Type0) {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} (re: Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) (out: t_Slice u8) : Prims.Pure (t_Slice u8) (requires - (v v_COMPRESSION_FACTOR == 4 \/ v v_COMPRESSION_FACTOR == 5) /\ - v v_OUT_LEN == 32 * v v_COMPRESSION_FACTOR /\ Seq.length out == v v_OUT_LEN /\ + Spec.MLKEM.is_rank v_K /\ + v_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\ + Seq.length out == v v_OUT_LEN /\ v v_OUT_LEN == 32 * v v_COMPRESSION_FACTOR /\ coefficients_field_modulus_range re) (ensures fun out_future -> let out_future:t_Slice u8 = out_future in Core.Slice.impl__len #u8 out_future == Core.Slice.impl__len #u8 out /\ out_future == - Spec.MLKEM.compress_then_encode_v v_COMPRESSION_FACTOR + Spec.MLKEM.compress_then_encode_v #v_K (Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector re)) val deserialize_then_decompress_10_ diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fst index 75ff693ea..65d0d2c8f 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Types -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -11,6 +11,7 @@ let impl_20__len (v_SIZE: usize) (_: Prims.unit) = v_SIZE let impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) = self.f_value + let impl_13__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) = self.f_value let impl_20__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) = self.f_value @@ -70,3 +71,51 @@ let impl_21__sk (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) = impl_13__as_slice v_PRIVATE_KEY_SIZE self.f_sk + +let unpack_private_key (v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) (private_key: t_Slice u8) = + let ind_cpa_secret_key, secret_key:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 private_key v_CPA_SECRET_KEY_SIZE + in + let ind_cpa_public_key, secret_key:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 secret_key v_PUBLIC_KEY_SIZE + in + let ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at #u8 secret_key Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE + in + ind_cpa_secret_key, ind_cpa_public_key, ind_cpa_public_key_hash, implicit_rejection_value + <: + (t_Slice u8 & t_Slice u8 & t_Slice u8 & t_Slice u8) + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl (v_SIZE: usize) : Core.Default.t_Default (t_MlKemCiphertext v_SIZE) = + { + f_default_pre = (fun (_: Prims.unit) -> true); + f_default_post = (fun (_: Prims.unit) (out: t_MlKemCiphertext v_SIZE) -> true); + f_default + = + fun (_: Prims.unit) -> + { f_value = Rust_primitives.Hax.repeat 0uy v_SIZE } <: t_MlKemCiphertext v_SIZE + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_7 (v_SIZE: usize) : Core.Default.t_Default (t_MlKemPrivateKey v_SIZE) = + { + f_default_pre = (fun (_: Prims.unit) -> true); + f_default_post = (fun (_: Prims.unit) (out: t_MlKemPrivateKey v_SIZE) -> true); + f_default + = + fun (_: Prims.unit) -> + { f_value = Rust_primitives.Hax.repeat 0uy v_SIZE } <: t_MlKemPrivateKey v_SIZE + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_14 (v_SIZE: usize) : Core.Default.t_Default (t_MlKemPublicKey v_SIZE) = + { + f_default_pre = (fun (_: Prims.unit) -> true); + f_default_post = (fun (_: Prims.unit) (out: t_MlKemPublicKey v_SIZE) -> true); + f_default + = + fun (_: Prims.unit) -> + { f_value = Rust_primitives.Hax.repeat 0uy v_SIZE } <: t_MlKemPublicKey v_SIZE + } + diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fsti index ca59dbe5c..e463a273b 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Types.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Types -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -19,15 +19,7 @@ val impl_20__len: v_SIZE: usize -> Prims.unit type t_MlKemCiphertext (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_2 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_Array u8 v_SIZE) = - { - f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); - f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemCiphertext v_SIZE) -> true); - f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemCiphertext v_SIZE - } - -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_3 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_Array u8 v_SIZE) = +let impl_1 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_Array u8 v_SIZE) = { f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemCiphertext v_SIZE) -> true); @@ -40,13 +32,23 @@ let impl_3 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_A } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_4 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemCiphertext v_SIZE) = +let impl_2 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemCiphertext v_SIZE) = { f_from_pre = (fun (value: t_MlKemCiphertext v_SIZE) -> true); f_from_post = (fun (value: t_MlKemCiphertext v_SIZE) (out: t_Array u8 v_SIZE) -> true); f_from = fun (value: t_MlKemCiphertext v_SIZE) -> value.f_value } +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_5 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_Array u8 v_SIZE) = + { + f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); + f_from_post + = + (fun (value: t_Array u8 v_SIZE) (result: t_MlKemCiphertext v_SIZE) -> result.f_value = value); + f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemCiphertext v_SIZE + } + /// A reference to the raw byte slice. val impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : Prims.Pure (t_Array u8 v_SIZE) @@ -60,15 +62,7 @@ val impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) type t_MlKemPrivateKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_9 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_Array u8 v_SIZE) = - { - f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); - f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPrivateKey v_SIZE) -> true); - f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemPrivateKey v_SIZE - } - -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_10 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_Array u8 v_SIZE) = +let impl_8 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_Array u8 v_SIZE) = { f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPrivateKey v_SIZE) -> true); @@ -81,13 +75,23 @@ let impl_10 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_ } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_11 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPrivateKey v_SIZE) = +let impl_9 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPrivateKey v_SIZE) = { f_from_pre = (fun (value: t_MlKemPrivateKey v_SIZE) -> true); f_from_post = (fun (value: t_MlKemPrivateKey v_SIZE) (out: t_Array u8 v_SIZE) -> true); f_from = fun (value: t_MlKemPrivateKey v_SIZE) -> value.f_value } +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_12 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_Array u8 v_SIZE) = + { + f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); + f_from_post + = + (fun (value: t_Array u8 v_SIZE) (result: t_MlKemPrivateKey v_SIZE) -> result.f_value = value); + f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemPrivateKey v_SIZE + } + /// A reference to the raw byte slice. val impl_13__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : Prims.Pure (t_Array u8 v_SIZE) @@ -101,15 +105,25 @@ val impl_13__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) type t_MlKemPublicKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_16 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_Array u8 v_SIZE) = +let impl_16 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPublicKey v_SIZE) = + { + f_from_pre = (fun (value: t_MlKemPublicKey v_SIZE) -> true); + f_from_post = (fun (value: t_MlKemPublicKey v_SIZE) (out: t_Array u8 v_SIZE) -> true); + f_from = fun (value: t_MlKemPublicKey v_SIZE) -> value.f_value + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_19 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_Array u8 v_SIZE) = { f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); - f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPublicKey v_SIZE) -> true); + f_from_post + = + (fun (value: t_Array u8 v_SIZE) (result: t_MlKemPublicKey v_SIZE) -> result.f_value = value); f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemPublicKey v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_17 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_Array u8 v_SIZE) = +let impl_15 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_Array u8 v_SIZE) = { f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPublicKey v_SIZE) -> true); @@ -121,14 +135,6 @@ let impl_17 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_A t_MlKemPublicKey v_SIZE } -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_18 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPublicKey v_SIZE) = - { - f_from_pre = (fun (value: t_MlKemPublicKey v_SIZE) -> true); - f_from_post = (fun (value: t_MlKemPublicKey v_SIZE) (out: t_Array u8 v_SIZE) -> true); - f_from = fun (value: t_MlKemPublicKey v_SIZE) -> value.f_value - } - /// A reference to the raw byte slice. val impl_20__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : Prims.Pure (t_Array u8 v_SIZE) @@ -197,65 +203,48 @@ val impl_21__sk (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) : Prims.Pure (t_Array u8 v_PRIVATE_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl (v_SIZE: usize) : Core.Default.t_Default (t_MlKemCiphertext v_SIZE) = - { - f_default_pre = (fun (_: Prims.unit) -> true); - f_default_post = (fun (_: Prims.unit) (out: t_MlKemCiphertext v_SIZE) -> true); - f_default - = - fun (_: Prims.unit) -> - { f_value = Rust_primitives.Hax.repeat 0uy v_SIZE } <: t_MlKemCiphertext v_SIZE - } - -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_7 (v_SIZE: usize) : Core.Default.t_Default (t_MlKemPrivateKey v_SIZE) = - { - f_default_pre = (fun (_: Prims.unit) -> true); - f_default_post = (fun (_: Prims.unit) (out: t_MlKemPrivateKey v_SIZE) -> true); - f_default - = - fun (_: Prims.unit) -> - { f_value = Rust_primitives.Hax.repeat 0uy v_SIZE } <: t_MlKemPrivateKey v_SIZE - } - -[@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_14 (v_SIZE: usize) : Core.Default.t_Default (t_MlKemPublicKey v_SIZE) = - { - f_default_pre = (fun (_: Prims.unit) -> true); - f_default_post = (fun (_: Prims.unit) (out: t_MlKemPublicKey v_SIZE) -> true); - f_default - = - fun (_: Prims.unit) -> - { f_value = Rust_primitives.Hax.repeat 0uy v_SIZE } <: t_MlKemPublicKey v_SIZE - } +/// Unpack an incoming private key into it\'s different parts. +/// We have this here in types to extract into a common core for C. +val unpack_private_key (v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) (private_key: t_Slice u8) + : Prims.Pure (t_Slice u8 & t_Slice u8 & t_Slice u8 & t_Slice u8) + (requires + Seq.length private_key >= + v v_CPA_SECRET_KEY_SIZE + v v_PUBLIC_KEY_SIZE + v Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE) + (ensures + fun result -> + let result:(t_Slice u8 & t_Slice u8 & t_Slice u8 & t_Slice u8) = result in + let ind_cpa_secret_key_s, rest = split private_key v_CPA_SECRET_KEY_SIZE in + let ind_cpa_public_key_s, rest = split rest v_PUBLIC_KEY_SIZE in + let ind_cpa_public_key_hash_s, implicit_rejection_value_s = + split rest Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE + in + let + ind_cpa_secret_key, ind_cpa_public_key, ind_cpa_public_key_hash, implicit_rejection_value + = + result + in + ind_cpa_secret_key_s == ind_cpa_secret_key /\ ind_cpa_public_key_s == ind_cpa_public_key /\ + ind_cpa_public_key_hash_s == ind_cpa_public_key_hash /\ + implicit_rejection_value_s == implicit_rejection_value /\ + Seq.length ind_cpa_secret_key == v v_CPA_SECRET_KEY_SIZE /\ + Seq.length ind_cpa_public_key == v v_PUBLIC_KEY_SIZE /\ + Seq.length ind_cpa_public_key_hash == v Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE /\ + Seq.length implicit_rejection_value == + Seq.length private_key - + (v v_CPA_SECRET_KEY_SIZE + v v_PUBLIC_KEY_SIZE + + v Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE)) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_1 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemCiphertext v_SIZE) (t_Slice u8) = - { - f_as_ref_pre = (fun (self: t_MlKemCiphertext v_SIZE) -> true); - f_as_ref_post = (fun (self: t_MlKemCiphertext v_SIZE) (out: t_Slice u8) -> true); - f_as_ref = fun (self: t_MlKemCiphertext v_SIZE) -> self.f_value <: t_Slice u8 - } +val impl (v_SIZE: usize) : Core.Default.t_Default (t_MlKemCiphertext v_SIZE) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_8 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = - { - f_as_ref_pre = (fun (self: t_MlKemPrivateKey v_SIZE) -> true); - f_as_ref_post = (fun (self: t_MlKemPrivateKey v_SIZE) (out: t_Slice u8) -> true); - f_as_ref = fun (self: t_MlKemPrivateKey v_SIZE) -> self.f_value <: t_Slice u8 - } +val impl_7 (v_SIZE: usize) : Core.Default.t_Default (t_MlKemPrivateKey v_SIZE) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_15 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemPublicKey v_SIZE) (t_Slice u8) = - { - f_as_ref_pre = (fun (self: t_MlKemPublicKey v_SIZE) -> true); - f_as_ref_post = (fun (self: t_MlKemPublicKey v_SIZE) (out: t_Slice u8) -> true); - f_as_ref = fun (self: t_MlKemPublicKey v_SIZE) -> self.f_value <: t_Slice u8 - } +val impl_14 (v_SIZE: usize) : Core.Default.t_Default (t_MlKemPublicKey v_SIZE) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = +let impl_3 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = { f_Error = Core.Array.t_TryFromSliceError; f_try_from_pre = (fun (value: t_Slice u8) -> true); @@ -286,7 +275,7 @@ let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) ( } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_12 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = +let impl_10 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = { f_Error = Core.Array.t_TryFromSliceError; f_try_from_pre = (fun (value: t_Slice u8) -> true); @@ -317,7 +306,7 @@ let impl_12 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_19 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPublicKey v_SIZE) (t_Slice u8) = +let impl_17 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPublicKey v_SIZE) (t_Slice u8) = { f_Error = Core.Array.t_TryFromSliceError; f_try_from_pre = (fun (value: t_Slice u8) -> true); @@ -346,3 +335,33 @@ let impl_19 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPublicKey v_SIZE) ( <: Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_4 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemCiphertext v_SIZE) (t_Slice u8) = + { + f_as_ref_pre = (fun (self: t_MlKemCiphertext v_SIZE) -> true); + f_as_ref_post + = + (fun (self___: t_MlKemCiphertext v_SIZE) (result: t_Slice u8) -> result = self___.f_value); + f_as_ref = fun (self: t_MlKemCiphertext v_SIZE) -> self.f_value <: t_Slice u8 + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_11 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = + { + f_as_ref_pre = (fun (self: t_MlKemPrivateKey v_SIZE) -> true); + f_as_ref_post + = + (fun (self___: t_MlKemPrivateKey v_SIZE) (result: t_Slice u8) -> result = self___.f_value); + f_as_ref = fun (self: t_MlKemPrivateKey v_SIZE) -> self.f_value <: t_Slice u8 + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_18 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemPublicKey v_SIZE) (t_Slice u8) = + { + f_as_ref_pre = (fun (self: t_MlKemPublicKey v_SIZE) -> true); + f_as_ref_post + = + (fun (self___: t_MlKemPublicKey v_SIZE) (result: t_Slice u8) -> result = self___.f_value); + f_as_ref = fun (self: t_MlKemPublicKey v_SIZE) -> self.f_value <: t_Slice u8 + } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fst index 2ee26ba5e..84b152b40 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fst @@ -1,8 +1,55 @@ module Libcrux_ml_kem.Utils -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul +#push-options "--z3rlimit 200" + +let prf_input_inc (v_K: usize) (prf_inputs: t_Array (t_Array u8 (sz 33)) v_K) (domain_separator: u8) = + let v__domain_separator_init:u8 = domain_separator in + let v__prf_inputs_init:t_Array (t_Array u8 (sz 33)) v_K = + Core.Clone.f_clone #(t_Array (t_Array u8 (sz 33)) v_K) + #FStar.Tactics.Typeclasses.solve + prf_inputs + in + let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = + Rust_primitives.Hax.Folds.fold_range (sz 0) + v_K + (fun temp_0_ i -> + let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = temp_0_ in + let i:usize = i in + v domain_separator == v v__domain_separator_init + v i /\ + (v i < v v_K ==> + (forall (j: nat). + (j >= v i /\ j < v v_K) ==> prf_inputs.[ sz j ] == v__prf_inputs_init.[ sz j ])) /\ + (forall (j: nat). + j < v i ==> + v (Seq.index (Seq.index prf_inputs j) 32) == v v__domain_separator_init + j /\ + Seq.slice (Seq.index prf_inputs j) 0 32 == + Seq.slice (Seq.index v__prf_inputs_init j) 0 32)) + (domain_separator, prf_inputs <: (u8 & t_Array (t_Array u8 (sz 33)) v_K)) + (fun temp_0_ i -> + let domain_separator, prf_inputs:(u8 & t_Array (t_Array u8 (sz 33)) v_K) = temp_0_ in + let i:usize = i in + let prf_inputs:t_Array (t_Array u8 (sz 33)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize prf_inputs + i + (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (prf_inputs.[ i ] + <: + t_Array u8 (sz 33)) + (sz 32) + domain_separator + <: + t_Array u8 (sz 33)) + in + let domain_separator:u8 = domain_separator +! 1uy in + domain_separator, prf_inputs <: (u8 & t_Array (t_Array u8 (sz 33)) v_K)) + in + let hax_temp_output:u8 = domain_separator in + prf_inputs, hax_temp_output <: (t_Array (t_Array u8 (sz 33)) v_K & u8) + +#pop-options + let into_padded_array (v_LEN: usize) (slice: t_Slice u8) = let out:t_Array u8 v_LEN = Rust_primitives.Hax.repeat 0uy v_LEN in let out:t_Array u8 v_LEN = diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fsti index c87b2d316..033a1e9d3 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Utils.fsti @@ -1,8 +1,21 @@ module Libcrux_ml_kem.Utils -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul +val prf_input_inc (v_K: usize) (prf_inputs: t_Array (t_Array u8 (sz 33)) v_K) (domain_separator: u8) + : Prims.Pure (t_Array (t_Array u8 (sz 33)) v_K & u8) + (requires range (v domain_separator + v v_K) u8_inttype) + (ensures + fun temp_0_ -> + let prf_inputs_future, ds:(t_Array (t_Array u8 (sz 33)) v_K & u8) = temp_0_ in + v ds == v domain_separator + v v_K /\ + (forall (i: nat). + i < v v_K ==> + v (Seq.index (Seq.index prf_inputs_future i) 32) == v domain_separator + i /\ + Seq.slice (Seq.index prf_inputs_future i) 0 32 == + Seq.slice (Seq.index prf_inputs i) 0 32)) + /// Pad the `slice` with `0`s at the end. val into_padded_array (v_LEN: usize) (slice: t_Slice u8) : Prims.Pure (t_Array u8 v_LEN) diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Variant.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Variant.fst new file mode 100644 index 000000000..90987de0b --- /dev/null +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Variant.fst @@ -0,0 +1,166 @@ +module Libcrux_ml_kem.Variant +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +open Core +open FStar.Mul + +let _ = + (* This module has implicit dependencies, here we make them explicit. *) + (* The implicit dependencies arise from typeclasses instances. *) + let open Libcrux_ml_kem.Hash_functions in + () + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: t_Variant t_MlKem = + { + f_kdf_pre + = + (fun + (v_K: usize) + (v_CIPHERTEXT_SIZE: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (shared_secret: t_Slice u8) + (_: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + -> + (Core.Slice.impl__len #u8 shared_secret <: usize) =. sz 32); + f_kdf_post + = + (fun + (v_K: usize) + (v_CIPHERTEXT_SIZE: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (shared_secret: t_Slice u8) + (_: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + (res: t_Array u8 (sz 32)) + -> + res == shared_secret); + f_kdf + = + (fun + (v_K: usize) + (v_CIPHERTEXT_SIZE: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i1: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (shared_secret: t_Slice u8) + (_: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) + -> + let out:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let out:t_Array u8 (sz 32) = Core.Slice.impl__copy_from_slice #u8 out shared_secret in + out); + f_entropy_preprocess_pre + = + (fun + (v_K: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (randomness: t_Slice u8) + -> + (Core.Slice.impl__len #u8 randomness <: usize) =. sz 32); + f_entropy_preprocess_post + = + (fun + (v_K: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (randomness: t_Slice u8) + (res: t_Array u8 (sz 32)) + -> + res == randomness); + f_entropy_preprocess + = + (fun + (v_K: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i3: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (randomness: t_Slice u8) + -> + let out:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in + let out:t_Array u8 (sz 32) = Core.Slice.impl__copy_from_slice #u8 out randomness in + out); + f_cpa_keygen_seed_pre + = + (fun + (v_K: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (key_generation_seed: t_Slice u8) + -> + (Core.Slice.impl__len #u8 key_generation_seed <: usize) =. sz 32); + f_cpa_keygen_seed_post + = + (fun + (v_K: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (key_generation_seed: t_Slice u8) + (res: t_Array u8 (sz 64)) + -> + Seq.length key_generation_seed == 32 ==> + res == Spec.Utils.v_G (Seq.append key_generation_seed (Seq.create 1 (cast v_K <: u8)))); + f_cpa_keygen_seed + = + fun + (v_K: usize) + (#v_Hasher: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i4: + Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) + (key_generation_seed: t_Slice u8) + -> + let seed:t_Array u8 (sz 33) = Rust_primitives.Hax.repeat 0uy (sz 33) in + let seed:t_Array u8 (sz 33) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range seed + ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice #u8 + (seed.[ { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end + = + Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE + } + <: + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) + key_generation_seed + <: + t_Slice u8) + in + let seed:t_Array u8 (sz 33) = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed + Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE + (cast (v_K <: usize) <: u8) + in + let _:Prims.unit = + Lib.Sequence.eq_intro #u8 + #33 + seed + (Seq.append key_generation_seed (Seq.create 1 (cast v_K <: u8))) + in + Libcrux_ml_kem.Hash_functions.f_G #v_Hasher + #v_K + #FStar.Tactics.Typeclasses.solve + (seed <: t_Slice u8) + } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Variant.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Variant.fsti index 0d74da846..590a79d4c 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Variant.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Variant.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Variant -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -98,157 +98,4 @@ class t_Variant (v_Self: Type0) = { } [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl: t_Variant t_MlKem = - { - f_kdf_pre - = - (fun - (v_K: usize) - (v_CIPHERTEXT_SIZE: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i1: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (shared_secret: t_Slice u8) - (_: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - -> - (Core.Slice.impl__len #u8 shared_secret <: usize) =. sz 32); - f_kdf_post - = - (fun - (v_K: usize) - (v_CIPHERTEXT_SIZE: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i1: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (shared_secret: t_Slice u8) - (_: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - (res: t_Array u8 (sz 32)) - -> - res == shared_secret); - f_kdf - = - (fun - (v_K: usize) - (v_CIPHERTEXT_SIZE: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i1: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (shared_secret: t_Slice u8) - (_: Libcrux_ml_kem.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - -> - let out:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in - let out:t_Array u8 (sz 32) = Core.Slice.impl__copy_from_slice #u8 out shared_secret in - out); - f_entropy_preprocess_pre - = - (fun - (v_K: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i3: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (randomness: t_Slice u8) - -> - (Core.Slice.impl__len #u8 randomness <: usize) =. sz 32); - f_entropy_preprocess_post - = - (fun - (v_K: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i3: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (randomness: t_Slice u8) - (res: t_Array u8 (sz 32)) - -> - res == randomness); - f_entropy_preprocess - = - (fun - (v_K: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i3: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (randomness: t_Slice u8) - -> - let out:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in - let out:t_Array u8 (sz 32) = Core.Slice.impl__copy_from_slice #u8 out randomness in - out); - f_cpa_keygen_seed_pre - = - (fun - (v_K: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i4: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (key_generation_seed: t_Slice u8) - -> - (Core.Slice.impl__len #u8 key_generation_seed <: usize) =. sz 32); - f_cpa_keygen_seed_post - = - (fun - (v_K: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i4: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (key_generation_seed: t_Slice u8) - (res: t_Array u8 (sz 64)) - -> - Seq.length key_generation_seed == 32 ==> - res == Spec.Utils.v_G (Seq.append key_generation_seed (Seq.create 1 (cast v_K <: u8)))); - f_cpa_keygen_seed - = - fun - (v_K: usize) - (#v_Hasher: Type0) - (#[FStar.Tactics.Typeclasses.tcresolve ()] - i4: - Libcrux_ml_kem.Hash_functions.t_Hash v_Hasher v_K) - (key_generation_seed: t_Slice u8) - -> - let seed:t_Array u8 (sz 33) = Rust_primitives.Hax.repeat 0uy (sz 33) in - let seed:t_Array u8 (sz 33) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range seed - ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - <: - Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice #u8 - (seed.[ { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end - = - Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE - } - <: - Core.Ops.Range.t_Range usize ] - <: - t_Slice u8) - key_generation_seed - <: - t_Slice u8) - in - let seed:t_Array u8 (sz 33) = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize seed - Libcrux_ml_kem.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE - (cast (v_K <: usize) <: u8) - in - let _:Prims.unit = - Lib.Sequence.eq_intro #u8 - #33 - seed - (Seq.append key_generation_seed (Seq.create 1 (cast v_K <: u8))) - in - Libcrux_ml_kem.Hash_functions.f_G #v_Hasher - #v_K - #FStar.Tactics.Typeclasses.solve - (seed <: t_Slice u8) - } +val impl:t_Variant t_MlKem diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst index 14c6d47e2..6f960e706 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti index 9bc156305..6cfb8659a 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Arithmetic.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fst index 87c17cd2a..849da1049 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Compress -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fsti index 7487aa930..267f93c47 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Compress.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Compress -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fst index 7fb1ccee4..504a87112 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fsti index b7f8a6c7d..e2cfc07ca 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Ntt.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fst index a36ffa505..b41e18824 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Sampling -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fsti index d75884373..767350ac5 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Sampling.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Sampling -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fst index d0c07fe84..b0c197583 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Serialize -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fsti index ee4012e41..f91497b5d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.Serialize.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2.Serialize -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fst index 8a9c2057c..29d63bae8 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -31,3 +31,572 @@ let vec_to_i16_array (v: t_SIMD256Vector) = let result:t_Array i16 (sz 16) = output in let _:Prims.unit = admit () (* Panic freedom *) in result + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: Libcrux_ml_kem.Vector.Traits.t_Repr t_SIMD256Vector = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + f_repr_pre = (fun (x: t_SIMD256Vector) -> true); + f_repr_post = (fun (x: t_SIMD256Vector) (out: t_Array i16 (sz 16)) -> true); + f_repr = fun (x: t_SIMD256Vector) -> vec_to_i16_array x + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_3: Libcrux_ml_kem.Vector.Traits.t_Operations t_SIMD256Vector = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + _super_8706949974463268012 = FStar.Tactics.Typeclasses.solve; + f_ZERO_pre = (fun (_: Prims.unit) -> true); + f_ZERO_post + = + (fun (_: Prims.unit) (out: t_SIMD256Vector) -> impl.f_repr out == Seq.create 16 0s); + f_ZERO = (fun (_: Prims.unit) -> vec_zero ()); + f_from_i16_array_pre + = + (fun (array: t_Slice i16) -> (Core.Slice.impl__len #i16 array <: usize) =. sz 16); + f_from_i16_array_post + = + (fun (array: t_Slice i16) (out: t_SIMD256Vector) -> impl.f_repr out == array); + f_from_i16_array = (fun (array: t_Slice i16) -> vec_from_i16_array array); + f_to_i16_array_pre = (fun (x: t_SIMD256Vector) -> true); + f_to_i16_array_post + = + (fun (x: t_SIMD256Vector) (out: t_Array i16 (sz 16)) -> out == impl.f_repr x); + f_to_i16_array = (fun (x: t_SIMD256Vector) -> vec_to_i16_array x); + f_add_pre + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> + forall i. + i < 16 ==> + Spec.Utils.is_intb (pow2 15 - 1) + (v (Seq.index (impl.f_repr lhs) i) + v (Seq.index (impl.f_repr rhs) i))); + f_add_post + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (result: t_SIMD256Vector) -> + forall i. + i < 16 ==> + (v (Seq.index (impl.f_repr result) i) == + v (Seq.index (impl.f_repr lhs) i) + v (Seq.index (impl.f_repr rhs) i))); + f_add + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.add lhs.f_elements rhs.f_elements } + <: + t_SIMD256Vector); + f_sub_pre + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> + forall i. + i < 16 ==> + Spec.Utils.is_intb (pow2 15 - 1) + (v (Seq.index (impl.f_repr lhs) i) - v (Seq.index (impl.f_repr rhs) i))); + f_sub_post + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (result: t_SIMD256Vector) -> + forall i. + i < 16 ==> + (v (Seq.index (impl.f_repr result) i) == + v (Seq.index (impl.f_repr lhs) i) - v (Seq.index (impl.f_repr rhs) i))); + f_sub + = + (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.sub lhs.f_elements rhs.f_elements } + <: + t_SIMD256Vector); + f_multiply_by_constant_pre + = + (fun (vec: t_SIMD256Vector) (c: i16) -> + forall i. + i < 16 ==> Spec.Utils.is_intb (pow2 15 - 1) (v (Seq.index (impl.f_repr vec) i) * v c)); + f_multiply_by_constant_post + = + (fun (vec: t_SIMD256Vector) (c: i16) (result: t_SIMD256Vector) -> + forall i. + i < 16 ==> + (v (Seq.index (impl.f_repr result) i) == v (Seq.index (impl.f_repr vec) i) * v c)); + f_multiply_by_constant + = + (fun (vec: t_SIMD256Vector) (c: i16) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.multiply_by_constant vec.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) -> + impl.f_repr out == Spec.Utils.map_array (fun x -> x &. constant) (impl.f_repr vector)); + f_bitwise_and_with_constant + = + (fun (vector: t_SIMD256Vector) (constant: i16) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.bitwise_and_with_constant vector.f_elements constant + } + <: + t_SIMD256Vector); + f_shift_right_pre + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> v_SHIFT_BY >=. 0l && v_SHIFT_BY <. 16l); + f_shift_right_post + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> + (v_SHIFT_BY >=. 0l /\ v_SHIFT_BY <. 16l) ==> + impl.f_repr out == Spec.Utils.map_array (fun x -> x >>! v_SHIFT_BY) (impl.f_repr vector)); + f_shift_right + = + (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.shift_right v_SHIFT_BY vector.f_elements + } + <: + t_SIMD256Vector); + f_cond_subtract_3329_pre + = + (fun (vector: t_SIMD256Vector) -> Spec.Utils.is_i16b_array (pow2 12 - 1) (impl.f_repr vector)); + f_cond_subtract_3329_post + = + (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> + impl.f_repr out == + Spec.Utils.map_array (fun x -> if x >=. 3329s then x -! 3329s else x) (impl.f_repr vector)); + f_cond_subtract_3329_ + = + (fun (vector: t_SIMD256Vector) -> + let _:Prims.unit = admit () in + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.cond_subtract_3329_ vector.f_elements } + <: + t_SIMD256Vector); + f_barrett_reduce_pre + = + (fun (vector: t_SIMD256Vector) -> Spec.Utils.is_i16b_array 28296 (impl.f_repr vector)); + f_barrett_reduce_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_barrett_reduce + = + (fun (vector: t_SIMD256Vector) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.barrett_reduce vector.f_elements } + <: + t_SIMD256Vector); + f_montgomery_multiply_by_constant_pre + = + (fun (vector: t_SIMD256Vector) (constant: i16) -> Spec.Utils.is_i16b 1664 constant); + f_montgomery_multiply_by_constant_post + = + (fun (vector: t_SIMD256Vector) (constant: i16) (out: t_SIMD256Vector) -> true); + f_montgomery_multiply_by_constant + = + (fun (vector: t_SIMD256Vector) (constant: i16) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_by_constant vector.f_elements + constant + } + <: + t_SIMD256Vector); + f_compress_1_pre + = + (fun (vector: t_SIMD256Vector) -> + forall (i: nat). + i < 16 ==> + v (Seq.index (impl.f_repr vector) i) >= 0 /\ v (Seq.index (impl.f_repr vector) i) < 3329); + f_compress_1_post + = + (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> + forall (i: nat). i < 16 ==> bounded (Seq.index (impl.f_repr out) i) 1); + f_compress_1_ + = + (fun (vector: t_SIMD256Vector) -> + let _:Prims.unit = admit () in + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Compress.compress_message_coefficient vector.f_elements + } + <: + t_SIMD256Vector); + f_compress_pre + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> + (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ + v v_COEFFICIENT_BITS == 11) /\ + (forall (i: nat). + i < 16 ==> + v (Seq.index (impl.f_repr vector) i) >= 0 /\ v (Seq.index (impl.f_repr vector) i) < 3329 + )); + f_compress_post + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> + (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ + v v_COEFFICIENT_BITS == 11) ==> + (forall (i: nat). i < 16 ==> bounded (Seq.index (impl.f_repr out) i) (v v_COEFFICIENT_BITS)) + ); + f_compress + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> + let _:Prims.unit = admit () in + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Compress.compress_ciphertext_coefficient v_COEFFICIENT_BITS + vector.f_elements + } + <: + t_SIMD256Vector); + f_decompress_ciphertext_coefficient_pre + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> + (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ + v v_COEFFICIENT_BITS == 11) /\ + (forall (i: nat). + i < 16 ==> + v (Seq.index (impl.f_repr vector) i) >= 0 /\ + v (Seq.index (impl.f_repr vector) i) < pow2 (v v_COEFFICIENT_BITS))); + f_decompress_ciphertext_coefficient_post + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); + f_decompress_ciphertext_coefficient + = + (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS + vector.f_elements + } + <: + t_SIMD256Vector); + f_ntt_layer_1_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ + Spec.Utils.is_i16b_array (11207 + 5 * 3328) (impl.f_repr vector)); + f_ntt_layer_1_step_post + = + (fun + (vector: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + Spec.Utils.is_i16b_array (11207 + 6 * 3328) (impl.f_repr out)); + f_ntt_layer_1_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> + let _:Prims.unit = admit () in + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_1_step vector.f_elements zeta0 zeta1 zeta2 zeta3 + } + <: + t_SIMD256Vector); + f_ntt_layer_2_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b_array (11207 + 4 * 3328) (impl.f_repr vector)); + f_ntt_layer_2_step_post + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> + Spec.Utils.is_i16b_array (11207 + 5 * 3328) (impl.f_repr out)); + f_ntt_layer_2_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> + let _:Prims.unit = admit () in + { + f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_2_step vector.f_elements zeta0 zeta1 + } + <: + t_SIMD256Vector); + f_ntt_layer_3_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta: i16) -> + Spec.Utils.is_i16b 1664 zeta /\ + Spec.Utils.is_i16b_array (11207 + 3 * 3328) (impl.f_repr vector)); + f_ntt_layer_3_step_post + = + (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> + Spec.Utils.is_i16b_array (11207 + 4 * 3328) (impl.f_repr out)); + f_ntt_layer_3_step + = + (fun (vector: t_SIMD256Vector) (zeta: i16) -> + let _:Prims.unit = admit () in + { f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_3_step vector.f_elements zeta } + <: + t_SIMD256Vector); + f_inv_ntt_layer_1_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ + Spec.Utils.is_i16b_array (4 * 3328) (impl.f_repr vector)); + f_inv_ntt_layer_1_step_post + = + (fun + (vector: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); + f_inv_ntt_layer_1_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> + let _:Prims.unit = admit () in + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_1_step vector.f_elements + zeta0 + zeta1 + zeta2 + zeta3 + } + <: + t_SIMD256Vector); + f_inv_ntt_layer_2_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b_array 3328 (impl.f_repr vector)); + f_inv_ntt_layer_2_step_post + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> + Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); + f_inv_ntt_layer_2_step + = + (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> + let _:Prims.unit = admit () in + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_2_step vector.f_elements zeta0 zeta1 + } + <: + t_SIMD256Vector); + f_inv_ntt_layer_3_step_pre + = + (fun (vector: t_SIMD256Vector) (zeta: i16) -> + Spec.Utils.is_i16b 1664 zeta /\ Spec.Utils.is_i16b_array 3328 (impl.f_repr vector)); + f_inv_ntt_layer_3_step_post + = + (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> + Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); + f_inv_ntt_layer_3_step + = + (fun (vector: t_SIMD256Vector) (zeta: i16) -> + let _:Prims.unit = admit () in + { f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_3_step vector.f_elements zeta } + <: + t_SIMD256Vector); + f_ntt_multiply_pre + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ + Spec.Utils.is_i16b_array 3328 (impl.f_repr lhs) /\ + Spec.Utils.is_i16b_array 3328 (impl.f_repr rhs)); + f_ntt_multiply_post + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: t_SIMD256Vector) + -> + Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); + f_ntt_multiply + = + (fun + (lhs: t_SIMD256Vector) + (rhs: t_SIMD256Vector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + let _:Prims.unit = admit () in + { + f_elements + = + Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_multiply lhs.f_elements + rhs.f_elements + zeta0 + zeta1 + zeta2 + zeta3 + } + <: + t_SIMD256Vector); + f_serialize_1_pre + = + (fun (vector: t_SIMD256Vector) -> Spec.MLKEM.serialize_pre 1 (impl.f_repr vector)); + f_serialize_1_post + = + (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 2)) -> + Spec.MLKEM.serialize_pre 1 (impl.f_repr vector) ==> + Spec.MLKEM.serialize_post 1 (impl.f_repr vector) out); + f_serialize_1_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_1_ vector.f_elements); + f_deserialize_1_pre + = + (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 2); + f_deserialize_1_post + = + (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> + sz (Seq.length bytes) =. sz 2 ==> Spec.MLKEM.deserialize_post 1 bytes (impl.f_repr out)); + f_deserialize_1_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_1_ bytes } + <: + t_SIMD256Vector); + f_serialize_4_pre + = + (fun (vector: t_SIMD256Vector) -> Spec.MLKEM.serialize_pre 4 (impl.f_repr vector)); + f_serialize_4_post + = + (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 8)) -> + Spec.MLKEM.serialize_pre 4 (impl.f_repr vector) ==> + Spec.MLKEM.serialize_post 4 (impl.f_repr vector) out); + f_serialize_4_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_4_ vector.f_elements); + f_deserialize_4_pre + = + (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 8); + f_deserialize_4_post + = + (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> + sz (Seq.length bytes) =. sz 8 ==> Spec.MLKEM.deserialize_post 4 bytes (impl.f_repr out)); + f_deserialize_4_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_4_ bytes } + <: + t_SIMD256Vector); + f_serialize_5_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_5_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 10)) -> true); + f_serialize_5_ + = + (fun (vector: t_SIMD256Vector) -> + let _:Prims.unit = admit () in + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_5_ vector.f_elements); + f_deserialize_5_pre + = + (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 10); + f_deserialize_5_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_5_ + = + (fun (bytes: t_Slice u8) -> + let _:Prims.unit = admit () in + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_5_ bytes } + <: + t_SIMD256Vector); + f_serialize_10_pre + = + (fun (vector: t_SIMD256Vector) -> Spec.MLKEM.serialize_pre 10 (impl.f_repr vector)); + f_serialize_10_post + = + (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 20)) -> + Spec.MLKEM.serialize_pre 10 (impl.f_repr vector) ==> + Spec.MLKEM.serialize_post 10 (impl.f_repr vector) out); + f_serialize_10_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_10_ vector.f_elements); + f_deserialize_10_pre + = + (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 20); + f_deserialize_10_post + = + (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> + sz (Seq.length bytes) =. sz 20 ==> Spec.MLKEM.deserialize_post 10 bytes (impl.f_repr out)); + f_deserialize_10_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_10_ bytes } + <: + t_SIMD256Vector); + f_serialize_11_pre = (fun (vector: t_SIMD256Vector) -> true); + f_serialize_11_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 22)) -> true); + f_serialize_11_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_11_ vector.f_elements); + f_deserialize_11_pre + = + (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 22); + f_deserialize_11_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); + f_deserialize_11_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_11_ bytes } + <: + t_SIMD256Vector); + f_serialize_12_pre + = + (fun (vector: t_SIMD256Vector) -> Spec.MLKEM.serialize_pre 12 (impl.f_repr vector)); + f_serialize_12_post + = + (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 24)) -> + Spec.MLKEM.serialize_pre 12 (impl.f_repr vector) ==> + Spec.MLKEM.serialize_post 12 (impl.f_repr vector) out); + f_serialize_12_ + = + (fun (vector: t_SIMD256Vector) -> + Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_12_ vector.f_elements); + f_deserialize_12_pre + = + (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 24); + f_deserialize_12_post + = + (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> + sz (Seq.length bytes) =. sz 24 ==> Spec.MLKEM.deserialize_post 12 bytes (impl.f_repr out)); + f_deserialize_12_ + = + (fun (bytes: t_Slice u8) -> + { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_12_ bytes } + <: + t_SIMD256Vector); + f_rej_sample_pre + = + (fun (input: t_Slice u8) (output: t_Slice i16) -> + (Core.Slice.impl__len #u8 input <: usize) =. sz 24 && + (Core.Slice.impl__len #i16 output <: usize) =. sz 16); + f_rej_sample_post + = + (fun (input: t_Slice u8) (output: t_Slice i16) (output_future, result: (t_Slice i16 & usize)) -> + Seq.length output_future == Seq.length output /\ v result <= 16); + f_rej_sample + = + fun (input: t_Slice u8) (output: t_Slice i16) -> + let tmp0, out:(t_Slice i16 & usize) = + Libcrux_ml_kem.Vector.Avx2.Sampling.rejection_sample input output + in + let output:t_Slice i16 = tmp0 in + let hax_temp_output:usize = out in + output, hax_temp_output <: (t_Slice i16 & usize) + } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fsti index b15ca262d..5d955b9ab 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Avx2.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Avx2 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -40,566 +40,7 @@ val vec_to_i16_array (v: t_SIMD256Vector) result == repr v) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl: Libcrux_ml_kem.Vector.Traits.t_Repr t_SIMD256Vector = - { - _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; - _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; - f_repr_pre = (fun (x: t_SIMD256Vector) -> true); - f_repr_post = (fun (x: t_SIMD256Vector) (out: t_Array i16 (sz 16)) -> true); - f_repr = fun (x: t_SIMD256Vector) -> vec_to_i16_array x - } +val impl:Libcrux_ml_kem.Vector.Traits.t_Repr t_SIMD256Vector [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_3: Libcrux_ml_kem.Vector.Traits.t_Operations t_SIMD256Vector = - { - _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; - _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; - _super_8706949974463268012 = FStar.Tactics.Typeclasses.solve; - f_ZERO_pre = (fun (_: Prims.unit) -> true); - f_ZERO_post - = - (fun (_: Prims.unit) (out: t_SIMD256Vector) -> impl.f_repr out == Seq.create 16 0s); - f_ZERO = (fun (_: Prims.unit) -> vec_zero ()); - f_from_i16_array_pre - = - (fun (array: t_Slice i16) -> (Core.Slice.impl__len #i16 array <: usize) =. sz 16); - f_from_i16_array_post - = - (fun (array: t_Slice i16) (out: t_SIMD256Vector) -> impl.f_repr out == array); - f_from_i16_array = (fun (array: t_Slice i16) -> vec_from_i16_array array); - f_to_i16_array_pre = (fun (x: t_SIMD256Vector) -> true); - f_to_i16_array_post - = - (fun (x: t_SIMD256Vector) (out: t_Array i16 (sz 16)) -> out == impl.f_repr x); - f_to_i16_array = (fun (x: t_SIMD256Vector) -> vec_to_i16_array x); - f_add_pre - = - (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> - forall i. - i < 16 ==> - Spec.Utils.is_intb (pow2 15 - 1) - (v (Seq.index (impl.f_repr lhs) i) + v (Seq.index (impl.f_repr rhs) i))); - f_add_post - = - (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (result: t_SIMD256Vector) -> - forall i. - i < 16 ==> - (v (Seq.index (impl.f_repr result) i) == - v (Seq.index (impl.f_repr lhs) i) + v (Seq.index (impl.f_repr rhs) i))); - f_add - = - (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.add lhs.f_elements rhs.f_elements } - <: - t_SIMD256Vector); - f_sub_pre - = - (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> - forall i. - i < 16 ==> - Spec.Utils.is_intb (pow2 15 - 1) - (v (Seq.index (impl.f_repr lhs) i) - v (Seq.index (impl.f_repr rhs) i))); - f_sub_post - = - (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) (result: t_SIMD256Vector) -> - forall i. - i < 16 ==> - (v (Seq.index (impl.f_repr result) i) == - v (Seq.index (impl.f_repr lhs) i) - v (Seq.index (impl.f_repr rhs) i))); - f_sub - = - (fun (lhs: t_SIMD256Vector) (rhs: t_SIMD256Vector) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.sub lhs.f_elements rhs.f_elements } - <: - t_SIMD256Vector); - f_multiply_by_constant_pre - = - (fun (vec: t_SIMD256Vector) (c: i16) -> - forall i. - i < 16 ==> Spec.Utils.is_intb (pow2 15 - 1) (v (Seq.index (impl.f_repr vec) i) * v c)); - f_multiply_by_constant_post - = - (fun (vec: t_SIMD256Vector) (c: i16) (result: t_SIMD256Vector) -> - forall i. - i < 16 ==> - (v (Seq.index (impl.f_repr result) i) == v (Seq.index (impl.f_repr vec) i) * v c)); - f_multiply_by_constant - = - (fun (vec: t_SIMD256Vector) (c: i16) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.multiply_by_constant vec.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) -> - impl.f_repr out == Spec.Utils.map_array (fun x -> x &. constant) (impl.f_repr vector)); - f_bitwise_and_with_constant - = - (fun (vector: t_SIMD256Vector) (constant: i16) -> - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Arithmetic.bitwise_and_with_constant vector.f_elements constant - } - <: - t_SIMD256Vector); - f_shift_right_pre - = - (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> v_SHIFT_BY >=. 0l && v_SHIFT_BY <. 16l); - f_shift_right_post - = - (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> - (v_SHIFT_BY >=. 0l /\ v_SHIFT_BY <. 16l) ==> - impl.f_repr out == Spec.Utils.map_array (fun x -> x >>! v_SHIFT_BY) (impl.f_repr vector)); - f_shift_right - = - (fun (v_SHIFT_BY: i32) (vector: t_SIMD256Vector) -> - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Arithmetic.shift_right v_SHIFT_BY vector.f_elements - } - <: - t_SIMD256Vector); - f_cond_subtract_3329_pre - = - (fun (vector: t_SIMD256Vector) -> Spec.Utils.is_i16b_array (pow2 12 - 1) (impl.f_repr vector)); - f_cond_subtract_3329_post - = - (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> - impl.f_repr out == - Spec.Utils.map_array (fun x -> if x >=. 3329s then x -! 3329s else x) (impl.f_repr vector)); - f_cond_subtract_3329_ - = - (fun (vector: t_SIMD256Vector) -> - let _:Prims.unit = admit () in - { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.cond_subtract_3329_ vector.f_elements } - <: - t_SIMD256Vector); - f_barrett_reduce_pre - = - (fun (vector: t_SIMD256Vector) -> Spec.Utils.is_i16b_array 28296 (impl.f_repr vector)); - f_barrett_reduce_post = (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_barrett_reduce - = - (fun (vector: t_SIMD256Vector) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Arithmetic.barrett_reduce vector.f_elements } - <: - t_SIMD256Vector); - f_montgomery_multiply_by_constant_pre - = - (fun (vector: t_SIMD256Vector) (constant: i16) -> Spec.Utils.is_i16b 1664 constant); - f_montgomery_multiply_by_constant_post - = - (fun (vector: t_SIMD256Vector) (constant: i16) (out: t_SIMD256Vector) -> true); - f_montgomery_multiply_by_constant - = - (fun (vector: t_SIMD256Vector) (constant: i16) -> - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Arithmetic.montgomery_multiply_by_constant vector.f_elements - constant - } - <: - t_SIMD256Vector); - f_compress_1_pre - = - (fun (vector: t_SIMD256Vector) -> - forall (i: nat). - i < 16 ==> - v (Seq.index (impl.f_repr vector) i) >= 0 /\ v (Seq.index (impl.f_repr vector) i) < 3329); - f_compress_1_post - = - (fun (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> - forall (i: nat). i < 16 ==> bounded (Seq.index (impl.f_repr out) i) 1); - f_compress_1_ - = - (fun (vector: t_SIMD256Vector) -> - let _:Prims.unit = admit () in - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Compress.compress_message_coefficient vector.f_elements - } - <: - t_SIMD256Vector); - f_compress_pre - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> - (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ - v v_COEFFICIENT_BITS == 11) /\ - (forall (i: nat). - i < 16 ==> - v (Seq.index (impl.f_repr vector) i) >= 0 /\ v (Seq.index (impl.f_repr vector) i) < 3329 - )); - f_compress_post - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> - (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ - v v_COEFFICIENT_BITS == 11) ==> - (forall (i: nat). i < 16 ==> bounded (Seq.index (impl.f_repr out) i) (v v_COEFFICIENT_BITS)) - ); - f_compress - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> - let _:Prims.unit = admit () in - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Compress.compress_ciphertext_coefficient v_COEFFICIENT_BITS - vector.f_elements - } - <: - t_SIMD256Vector); - f_decompress_ciphertext_coefficient_pre - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> - v_COEFFICIENT_BITS =. 4l || v_COEFFICIENT_BITS =. 5l || v_COEFFICIENT_BITS =. 10l || - v_COEFFICIENT_BITS =. 11l); - f_decompress_ciphertext_coefficient_post - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) (out: t_SIMD256Vector) -> true); - f_decompress_ciphertext_coefficient - = - (fun (v_COEFFICIENT_BITS: i32) (vector: t_SIMD256Vector) -> - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS - vector.f_elements - } - <: - t_SIMD256Vector); - f_ntt_layer_1_step_pre - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ - Spec.Utils.is_i16b_array (11207 + 5 * 3328) (impl.f_repr vector)); - f_ntt_layer_1_step_post - = - (fun - (vector: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: t_SIMD256Vector) - -> - Spec.Utils.is_i16b_array (11207 + 6 * 3328) (impl.f_repr out)); - f_ntt_layer_1_step - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> - let _:Prims.unit = admit () in - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_1_step vector.f_elements zeta0 zeta1 zeta2 zeta3 - } - <: - t_SIMD256Vector); - f_ntt_layer_2_step_pre - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b_array (11207 + 4 * 3328) (impl.f_repr vector)); - f_ntt_layer_2_step_post - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> - Spec.Utils.is_i16b_array (11207 + 5 * 3328) (impl.f_repr out)); - f_ntt_layer_2_step - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> - let _:Prims.unit = admit () in - { - f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_2_step vector.f_elements zeta0 zeta1 - } - <: - t_SIMD256Vector); - f_ntt_layer_3_step_pre - = - (fun (vector: t_SIMD256Vector) (zeta: i16) -> - Spec.Utils.is_i16b 1664 zeta /\ - Spec.Utils.is_i16b_array (11207 + 3 * 3328) (impl.f_repr vector)); - f_ntt_layer_3_step_post - = - (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> - Spec.Utils.is_i16b_array (11207 + 4 * 3328) (impl.f_repr out)); - f_ntt_layer_3_step - = - (fun (vector: t_SIMD256Vector) (zeta: i16) -> - let _:Prims.unit = admit () in - { f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_layer_3_step vector.f_elements zeta } - <: - t_SIMD256Vector); - f_inv_ntt_layer_1_step_pre - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ - Spec.Utils.is_i16b_array (4 * 3328) (impl.f_repr vector)); - f_inv_ntt_layer_1_step_post - = - (fun - (vector: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: t_SIMD256Vector) - -> - Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); - f_inv_ntt_layer_1_step - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (zeta2: i16) (zeta3: i16) -> - let _:Prims.unit = admit () in - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_1_step vector.f_elements - zeta0 - zeta1 - zeta2 - zeta3 - } - <: - t_SIMD256Vector); - f_inv_ntt_layer_2_step_pre - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b_array 3328 (impl.f_repr vector)); - f_inv_ntt_layer_2_step_post - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) (out: t_SIMD256Vector) -> - Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); - f_inv_ntt_layer_2_step - = - (fun (vector: t_SIMD256Vector) (zeta0: i16) (zeta1: i16) -> - let _:Prims.unit = admit () in - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_2_step vector.f_elements zeta0 zeta1 - } - <: - t_SIMD256Vector); - f_inv_ntt_layer_3_step_pre - = - (fun (vector: t_SIMD256Vector) (zeta: i16) -> - Spec.Utils.is_i16b 1664 zeta /\ Spec.Utils.is_i16b_array 3328 (impl.f_repr vector)); - f_inv_ntt_layer_3_step_post - = - (fun (vector: t_SIMD256Vector) (zeta: i16) (out: t_SIMD256Vector) -> - Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); - f_inv_ntt_layer_3_step - = - (fun (vector: t_SIMD256Vector) (zeta: i16) -> - let _:Prims.unit = admit () in - { f_elements = Libcrux_ml_kem.Vector.Avx2.Ntt.inv_ntt_layer_3_step vector.f_elements zeta } - <: - t_SIMD256Vector); - f_ntt_multiply_pre - = - (fun - (lhs: t_SIMD256Vector) - (rhs: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ - Spec.Utils.is_i16b_array 3328 (impl.f_repr lhs) /\ - Spec.Utils.is_i16b_array 3328 (impl.f_repr rhs)); - f_ntt_multiply_post - = - (fun - (lhs: t_SIMD256Vector) - (rhs: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: t_SIMD256Vector) - -> - Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); - f_ntt_multiply - = - (fun - (lhs: t_SIMD256Vector) - (rhs: t_SIMD256Vector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - let _:Prims.unit = admit () in - { - f_elements - = - Libcrux_ml_kem.Vector.Avx2.Ntt.ntt_multiply lhs.f_elements - rhs.f_elements - zeta0 - zeta1 - zeta2 - zeta3 - } - <: - t_SIMD256Vector); - f_serialize_1_pre - = - (fun (vector: t_SIMD256Vector) -> Spec.MLKEM.serialize_pre 1 (impl.f_repr vector)); - f_serialize_1_post - = - (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 2)) -> - Spec.MLKEM.serialize_pre 1 (impl.f_repr vector) ==> - Spec.MLKEM.serialize_post 1 (impl.f_repr vector) out); - f_serialize_1_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_1_ vector.f_elements); - f_deserialize_1_pre - = - (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 2); - f_deserialize_1_post - = - (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> - sz (Seq.length bytes) =. sz 2 ==> Spec.MLKEM.deserialize_post 1 bytes (impl.f_repr out)); - f_deserialize_1_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_1_ bytes } - <: - t_SIMD256Vector); - f_serialize_4_pre - = - (fun (vector: t_SIMD256Vector) -> Spec.MLKEM.serialize_pre 4 (impl.f_repr vector)); - f_serialize_4_post - = - (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 8)) -> - Spec.MLKEM.serialize_pre 4 (impl.f_repr vector) ==> - Spec.MLKEM.serialize_post 4 (impl.f_repr vector) out); - f_serialize_4_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_4_ vector.f_elements); - f_deserialize_4_pre - = - (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 8); - f_deserialize_4_post - = - (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> - sz (Seq.length bytes) =. sz 8 ==> Spec.MLKEM.deserialize_post 4 bytes (impl.f_repr out)); - f_deserialize_4_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_4_ bytes } - <: - t_SIMD256Vector); - f_serialize_5_pre = (fun (vector: t_SIMD256Vector) -> true); - f_serialize_5_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 10)) -> true); - f_serialize_5_ - = - (fun (vector: t_SIMD256Vector) -> - let _:Prims.unit = admit () in - Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_5_ vector.f_elements); - f_deserialize_5_pre - = - (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 10); - f_deserialize_5_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); - f_deserialize_5_ - = - (fun (bytes: t_Slice u8) -> - let _:Prims.unit = admit () in - { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_5_ bytes } - <: - t_SIMD256Vector); - f_serialize_10_pre - = - (fun (vector: t_SIMD256Vector) -> Spec.MLKEM.serialize_pre 10 (impl.f_repr vector)); - f_serialize_10_post - = - (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 20)) -> - Spec.MLKEM.serialize_pre 10 (impl.f_repr vector) ==> - Spec.MLKEM.serialize_post 10 (impl.f_repr vector) out); - f_serialize_10_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_10_ vector.f_elements); - f_deserialize_10_pre - = - (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 20); - f_deserialize_10_post - = - (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> - sz (Seq.length bytes) =. sz 20 ==> Spec.MLKEM.deserialize_post 10 bytes (impl.f_repr out)); - f_deserialize_10_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_10_ bytes } - <: - t_SIMD256Vector); - f_serialize_11_pre = (fun (vector: t_SIMD256Vector) -> true); - f_serialize_11_post = (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 22)) -> true); - f_serialize_11_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_11_ vector.f_elements); - f_deserialize_11_pre - = - (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 22); - f_deserialize_11_post = (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> true); - f_deserialize_11_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_11_ bytes } - <: - t_SIMD256Vector); - f_serialize_12_pre - = - (fun (vector: t_SIMD256Vector) -> Spec.MLKEM.serialize_pre 12 (impl.f_repr vector)); - f_serialize_12_post - = - (fun (vector: t_SIMD256Vector) (out: t_Array u8 (sz 24)) -> - Spec.MLKEM.serialize_pre 12 (impl.f_repr vector) ==> - Spec.MLKEM.serialize_post 12 (impl.f_repr vector) out); - f_serialize_12_ - = - (fun (vector: t_SIMD256Vector) -> - Libcrux_ml_kem.Vector.Avx2.Serialize.serialize_12_ vector.f_elements); - f_deserialize_12_pre - = - (fun (bytes: t_Slice u8) -> (Core.Slice.impl__len #u8 bytes <: usize) =. sz 24); - f_deserialize_12_post - = - (fun (bytes: t_Slice u8) (out: t_SIMD256Vector) -> - sz (Seq.length bytes) =. sz 24 ==> Spec.MLKEM.deserialize_post 12 bytes (impl.f_repr out)); - f_deserialize_12_ - = - (fun (bytes: t_Slice u8) -> - { f_elements = Libcrux_ml_kem.Vector.Avx2.Serialize.deserialize_12_ bytes } - <: - t_SIMD256Vector); - f_rej_sample_pre - = - (fun (input: t_Slice u8) (output: t_Slice i16) -> - (Core.Slice.impl__len #u8 input <: usize) =. sz 24 && - (Core.Slice.impl__len #i16 output <: usize) =. sz 16); - f_rej_sample_post - = - (fun (input: t_Slice u8) (output: t_Slice i16) (output_future, result: (t_Slice i16 & usize)) -> - Seq.length output_future == Seq.length output /\ v result <= 16); - f_rej_sample - = - fun (input: t_Slice u8) (output: t_Slice i16) -> - let tmp0, out:(t_Slice i16 & usize) = - Libcrux_ml_kem.Vector.Avx2.Sampling.rejection_sample input output - in - let output:t_Slice i16 = tmp0 in - let hax_temp_output:usize = out in - output, hax_temp_output <: (t_Slice i16 & usize) - } +val impl_3:Libcrux_ml_kem.Vector.Traits.t_Operations t_SIMD256Vector diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Arithmetic.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Arithmetic.fst index a36b00a94..1139236f7 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Arithmetic.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Arithmetic.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Arithmetic.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Arithmetic.fsti index b765f0915..91b5164fe 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Arithmetic.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Arithmetic.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Compress.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Compress.fst index c6f54fd1c..29ffc7ec4 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Compress.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Compress.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Compress -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Compress.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Compress.fsti index 0a2c883cb..55a0e76b6 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Compress.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Compress.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Compress -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Ntt.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Ntt.fst index d00b944c4..36abe54f2 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Ntt.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Ntt.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Ntt.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Ntt.fsti index a280dcc7a..8beabc8b6 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Ntt.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Ntt.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Serialize.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Serialize.fst index cadc20681..2bda9f7e7 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Serialize.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Serialize.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Serialize -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Serialize.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Serialize.fsti index 3de7409f7..7610cd889 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Serialize.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Serialize.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Serialize -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Vector_type.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Vector_type.fst index 116acadf7..9b4625de3 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Vector_type.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Vector_type.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Vector_type -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Vector_type.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Vector_type.fsti index c5dd6b6ab..2a950fdf6 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Vector_type.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.Vector_type.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon.Vector_type -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.fst index f41cefe46..7697d036c 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -47,3 +47,494 @@ let rej_sample (a: t_Slice u8) (result: t_Slice i16) = in let hax_temp_output:usize = sampled in result, hax_temp_output <: (t_Slice i16 & usize) + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl: Libcrux_ml_kem.Vector.Traits.t_Repr Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + f_repr_pre = (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_repr_post + = + (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array i16 (sz 16)) -> + true); + f_repr + = + fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Vector_type.to_i16_array x + } + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_1: Libcrux_ml_kem.Vector.Traits.t_Operations +Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + _super_8706949974463268012 = FStar.Tactics.Typeclasses.solve; + f_ZERO_pre = (fun (_: Prims.unit) -> true); + f_ZERO_post + = + (fun (_: Prims.unit) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + impl.f_repr out == Seq.create 16 0s); + f_ZERO = (fun (_: Prims.unit) -> Libcrux_ml_kem.Vector.Neon.Vector_type.v_ZERO ()); + f_from_i16_array_pre + = + (fun (array: t_Slice i16) -> (Core.Slice.impl__len #i16 array <: usize) =. sz 16); + f_from_i16_array_post + = + (fun (array: t_Slice i16) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + impl.f_repr out == array); + f_from_i16_array + = + (fun (array: t_Slice i16) -> Libcrux_ml_kem.Vector.Neon.Vector_type.from_i16_array array); + f_to_i16_array_pre = (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_to_i16_array_post + = + (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array i16 (sz 16)) -> + out == impl.f_repr x); + f_to_i16_array + = + (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Vector_type.to_i16_array x); + f_add_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_add_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_add + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + Libcrux_ml_kem.Vector.Neon.Arithmetic.add lhs rhs); + f_sub_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_sub_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_sub + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + Libcrux_ml_kem.Vector.Neon.Arithmetic.sub lhs rhs); + f_multiply_by_constant_pre + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> true); + f_multiply_by_constant_post + = + (fun + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (c: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_multiply_by_constant + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> + Libcrux_ml_kem.Vector.Neon.Arithmetic.multiply_by_constant v c); + f_bitwise_and_with_constant_pre + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> true); + f_bitwise_and_with_constant_post + = + (fun + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (c: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_bitwise_and_with_constant + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> + Libcrux_ml_kem.Vector.Neon.Arithmetic.bitwise_and_with_constant v c); + f_shift_right_pre + = + (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_shift_right_post + = + (fun + (v_SHIFT_BY: i32) + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_shift_right + = + (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Arithmetic.shift_right v_SHIFT_BY v); + f_cond_subtract_3329_pre + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_cond_subtract_3329_post + = + (fun + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_cond_subtract_3329_ + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Arithmetic.cond_subtract_3329_ v); + f_barrett_reduce_pre = (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_barrett_reduce_post + = + (fun + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_barrett_reduce + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Arithmetic.barrett_reduce v); + f_montgomery_multiply_by_constant_pre + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> true); + f_montgomery_multiply_by_constant_post + = + (fun + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (c: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_montgomery_multiply_by_constant + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> + Libcrux_ml_kem.Vector.Neon.Arithmetic.montgomery_multiply_by_constant v c); + f_compress_1_pre = (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_compress_1_post + = + (fun + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_compress_1_ + = + (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Compress.compress_1_ v); + f_compress_pre + = + (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + true); + f_compress_post + = + (fun + (v_COEFFICIENT_BITS: i32) + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_compress + = + (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Compress.compress v_COEFFICIENT_BITS v); + f_decompress_ciphertext_coefficient_pre + = + (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + true); + f_decompress_ciphertext_coefficient_post + = + (fun + (v_COEFFICIENT_BITS: i32) + (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_decompress_ciphertext_coefficient + = + (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS v); + f_ntt_layer_1_step_pre + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + -> + true); + f_ntt_layer_1_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_ntt_layer_1_step + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + -> + Libcrux_ml_kem.Vector.Neon.Ntt.ntt_layer_1_step a zeta1 zeta2 zeta3 zeta4); + f_ntt_layer_2_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta1: i16) (zeta2: i16) -> + true); + f_ntt_layer_2_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_ntt_layer_2_step + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta1: i16) (zeta2: i16) -> + Libcrux_ml_kem.Vector.Neon.Ntt.ntt_layer_2_step a zeta1 zeta2); + f_ntt_layer_3_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta: i16) -> true); + f_ntt_layer_3_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_ntt_layer_3_step + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta: i16) -> + Libcrux_ml_kem.Vector.Neon.Ntt.ntt_layer_3_step a zeta); + f_inv_ntt_layer_1_step_pre + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + -> + true); + f_inv_ntt_layer_1_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_inv_ntt_layer_1_step + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + -> + Libcrux_ml_kem.Vector.Neon.Ntt.inv_ntt_layer_1_step a zeta1 zeta2 zeta3 zeta4); + f_inv_ntt_layer_2_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta1: i16) (zeta2: i16) -> + true); + f_inv_ntt_layer_2_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_inv_ntt_layer_2_step + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta1: i16) (zeta2: i16) -> + Libcrux_ml_kem.Vector.Neon.Ntt.inv_ntt_layer_2_step a zeta1 zeta2); + f_inv_ntt_layer_3_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta: i16) -> true); + f_inv_ntt_layer_3_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_inv_ntt_layer_3_step + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta: i16) -> + Libcrux_ml_kem.Vector.Neon.Ntt.inv_ntt_layer_3_step a zeta); + f_ntt_multiply_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + -> + true); + f_ntt_multiply_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + -> + true); + f_ntt_multiply + = + (fun + (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (zeta4: i16) + -> + Libcrux_ml_kem.Vector.Neon.Ntt.ntt_multiply lhs rhs zeta1 zeta2 zeta3 zeta4); + f_serialize_1_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_serialize_1_post + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 2)) -> + true); + f_serialize_1_ + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Serialize.serialize_1_ a); + f_deserialize_1_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_1_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_deserialize_1_ + = + (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_1_ a); + f_serialize_4_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_serialize_4_post + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 8)) -> + true); + f_serialize_4_ + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Serialize.serialize_4_ a); + f_deserialize_4_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_4_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_deserialize_4_ + = + (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_4_ a); + f_serialize_5_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_serialize_5_post + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 10)) -> + true); + f_serialize_5_ + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Serialize.serialize_5_ a); + f_deserialize_5_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_5_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_deserialize_5_ + = + (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_5_ a); + f_serialize_10_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_serialize_10_post + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 20)) -> + true); + f_serialize_10_ + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Serialize.serialize_10_ a); + f_deserialize_10_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_10_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_deserialize_10_ + = + (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_10_ a); + f_serialize_11_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_serialize_11_post + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 22)) -> + true); + f_serialize_11_ + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Serialize.serialize_11_ a); + f_deserialize_11_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_11_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_deserialize_11_ + = + (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_11_ a); + f_serialize_12_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_serialize_12_post + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 24)) -> + true); + f_serialize_12_ + = + (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> + Libcrux_ml_kem.Vector.Neon.Serialize.serialize_12_ a); + f_deserialize_12_pre = (fun (a: t_Slice u8) -> true); + f_deserialize_12_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); + f_deserialize_12_ + = + (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_12_ a); + f_rej_sample_pre = (fun (a: t_Slice u8) (out: t_Slice i16) -> true); + f_rej_sample_post + = + (fun (a: t_Slice u8) (out: t_Slice i16) (out2: (t_Slice i16 & usize)) -> true); + f_rej_sample + = + fun (a: t_Slice u8) (out: t_Slice i16) -> + let tmp0, out1:(t_Slice i16 & usize) = rej_sample a out in + let out:t_Slice i16 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i16 & usize) + } diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.fsti index f3280f83e..a9ba571dd 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Neon.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Neon -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -14,492 +14,8 @@ val rej_sample (a: t_Slice u8) (result: t_Slice i16) : Prims.Pure (t_Slice i16 & usize) Prims.l_True (fun _ -> Prims.l_True) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl: Libcrux_ml_kem.Vector.Traits.t_Repr Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = - { - _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; - _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; - f_repr_pre = (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_repr_post - = - (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array i16 (sz 16)) -> - true); - f_repr - = - fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Vector_type.to_i16_array x - } +val impl:Libcrux_ml_kem.Vector.Traits.t_Repr Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_1: Libcrux_ml_kem.Vector.Traits.t_Operations -Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector = - { - _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; - _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; - _super_8706949974463268012 = FStar.Tactics.Typeclasses.solve; - f_ZERO_pre = (fun (_: Prims.unit) -> true); - f_ZERO_post - = - (fun (_: Prims.unit) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - impl.f_repr out == Seq.create 16 0s); - f_ZERO = (fun (_: Prims.unit) -> Libcrux_ml_kem.Vector.Neon.Vector_type.v_ZERO ()); - f_from_i16_array_pre - = - (fun (array: t_Slice i16) -> (Core.Slice.impl__len #i16 array <: usize) =. sz 16); - f_from_i16_array_post - = - (fun (array: t_Slice i16) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - impl.f_repr out == array); - f_from_i16_array - = - (fun (array: t_Slice i16) -> Libcrux_ml_kem.Vector.Neon.Vector_type.from_i16_array array); - f_to_i16_array_pre = (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_to_i16_array_post - = - (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array i16 (sz 16)) -> - out == impl.f_repr x); - f_to_i16_array - = - (fun (x: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Vector_type.to_i16_array x); - f_add_pre - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_add_post - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_add - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - Libcrux_ml_kem.Vector.Neon.Arithmetic.add lhs rhs); - f_sub_pre - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_sub_post - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_sub - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - Libcrux_ml_kem.Vector.Neon.Arithmetic.sub lhs rhs); - f_multiply_by_constant_pre - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> true); - f_multiply_by_constant_post - = - (fun - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (c: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_multiply_by_constant - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> - Libcrux_ml_kem.Vector.Neon.Arithmetic.multiply_by_constant v c); - f_bitwise_and_with_constant_pre - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> true); - f_bitwise_and_with_constant_post - = - (fun - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (c: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_bitwise_and_with_constant - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> - Libcrux_ml_kem.Vector.Neon.Arithmetic.bitwise_and_with_constant v c); - f_shift_right_pre - = - (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_shift_right_post - = - (fun - (v_SHIFT_BY: i32) - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_shift_right - = - (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Arithmetic.shift_right v_SHIFT_BY v); - f_cond_subtract_3329_pre - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_cond_subtract_3329_post - = - (fun - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_cond_subtract_3329_ - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Arithmetic.cond_subtract_3329_ v); - f_barrett_reduce_pre = (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_barrett_reduce_post - = - (fun - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_barrett_reduce - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Arithmetic.barrett_reduce v); - f_montgomery_multiply_by_constant_pre - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> true); - f_montgomery_multiply_by_constant_post - = - (fun - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (c: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_montgomery_multiply_by_constant - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (c: i16) -> - Libcrux_ml_kem.Vector.Neon.Arithmetic.montgomery_multiply_by_constant v c); - f_compress_1_pre = (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_compress_1_post - = - (fun - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_compress_1_ - = - (fun (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Compress.compress_1_ v); - f_compress_pre - = - (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - true); - f_compress_post - = - (fun - (v_COEFFICIENT_BITS: i32) - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_compress - = - (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Compress.compress v_COEFFICIENT_BITS v); - f_decompress_ciphertext_coefficient_pre - = - (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - true); - f_decompress_ciphertext_coefficient_post - = - (fun - (v_COEFFICIENT_BITS: i32) - (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_decompress_ciphertext_coefficient - = - (fun (v_COEFFICIENT_BITS: i32) (v: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS v); - f_ntt_layer_1_step_pre - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - -> - true); - f_ntt_layer_1_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_ntt_layer_1_step - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - -> - Libcrux_ml_kem.Vector.Neon.Ntt.ntt_layer_1_step a zeta1 zeta2 zeta3 zeta4); - f_ntt_layer_2_step_pre - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta1: i16) (zeta2: i16) -> - true); - f_ntt_layer_2_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_ntt_layer_2_step - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta1: i16) (zeta2: i16) -> - Libcrux_ml_kem.Vector.Neon.Ntt.ntt_layer_2_step a zeta1 zeta2); - f_ntt_layer_3_step_pre - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta: i16) -> true); - f_ntt_layer_3_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_ntt_layer_3_step - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta: i16) -> - Libcrux_ml_kem.Vector.Neon.Ntt.ntt_layer_3_step a zeta); - f_inv_ntt_layer_1_step_pre - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - -> - true); - f_inv_ntt_layer_1_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_inv_ntt_layer_1_step - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - -> - Libcrux_ml_kem.Vector.Neon.Ntt.inv_ntt_layer_1_step a zeta1 zeta2 zeta3 zeta4); - f_inv_ntt_layer_2_step_pre - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta1: i16) (zeta2: i16) -> - true); - f_inv_ntt_layer_2_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_inv_ntt_layer_2_step - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta1: i16) (zeta2: i16) -> - Libcrux_ml_kem.Vector.Neon.Ntt.inv_ntt_layer_2_step a zeta1 zeta2); - f_inv_ntt_layer_3_step_pre - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta: i16) -> true); - f_inv_ntt_layer_3_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_inv_ntt_layer_3_step - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (zeta: i16) -> - Libcrux_ml_kem.Vector.Neon.Ntt.inv_ntt_layer_3_step a zeta); - f_ntt_multiply_pre - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - -> - true); - f_ntt_multiply_post - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - -> - true); - f_ntt_multiply - = - (fun - (lhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (rhs: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (zeta4: i16) - -> - Libcrux_ml_kem.Vector.Neon.Ntt.ntt_multiply lhs rhs zeta1 zeta2 zeta3 zeta4); - f_serialize_1_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_serialize_1_post - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 2)) -> - true); - f_serialize_1_ - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Serialize.serialize_1_ a); - f_deserialize_1_pre = (fun (a: t_Slice u8) -> true); - f_deserialize_1_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_deserialize_1_ - = - (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_1_ a); - f_serialize_4_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_serialize_4_post - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 8)) -> - true); - f_serialize_4_ - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Serialize.serialize_4_ a); - f_deserialize_4_pre = (fun (a: t_Slice u8) -> true); - f_deserialize_4_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_deserialize_4_ - = - (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_4_ a); - f_serialize_5_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_serialize_5_post - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 10)) -> - true); - f_serialize_5_ - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Serialize.serialize_5_ a); - f_deserialize_5_pre = (fun (a: t_Slice u8) -> true); - f_deserialize_5_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_deserialize_5_ - = - (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_5_ a); - f_serialize_10_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_serialize_10_post - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 20)) -> - true); - f_serialize_10_ - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Serialize.serialize_10_ a); - f_deserialize_10_pre = (fun (a: t_Slice u8) -> true); - f_deserialize_10_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_deserialize_10_ - = - (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_10_ a); - f_serialize_11_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_serialize_11_post - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 22)) -> - true); - f_serialize_11_ - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Serialize.serialize_11_ a); - f_deserialize_11_pre = (fun (a: t_Slice u8) -> true); - f_deserialize_11_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_deserialize_11_ - = - (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_11_ a); - f_serialize_12_pre = (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_serialize_12_post - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) (out: t_Array u8 (sz 24)) -> - true); - f_serialize_12_ - = - (fun (a: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> - Libcrux_ml_kem.Vector.Neon.Serialize.serialize_12_ a); - f_deserialize_12_pre = (fun (a: t_Slice u8) -> true); - f_deserialize_12_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector) -> true); - f_deserialize_12_ - = - (fun (a: t_Slice u8) -> Libcrux_ml_kem.Vector.Neon.Serialize.deserialize_12_ a); - f_rej_sample_pre = (fun (a: t_Slice u8) (out: t_Slice i16) -> true); - f_rej_sample_post - = - (fun (a: t_Slice u8) (out: t_Slice i16) (out2: (t_Slice i16 & usize)) -> true); - f_rej_sample - = - fun (a: t_Slice u8) (out: t_Slice i16) -> - let tmp0, out1:(t_Slice i16 & usize) = rej_sample a out in - let out:t_Slice i16 = tmp0 in - let hax_temp_output:usize = out1 in - out, hax_temp_output <: (t_Slice i16 & usize) - } +val impl_1:Libcrux_ml_kem.Vector.Traits.t_Operations +Libcrux_ml_kem.Vector.Neon.Vector_type.t_SIMD128Vector diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Arithmetic.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Arithmetic.fst index bcb88d903..9f607fddd 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Arithmetic.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Arithmetic.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Portable.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -310,6 +310,8 @@ let bitwise_and_with_constant in vec +#push-options "--z3rlimit 300" + let cond_subtract_3329_ (vec: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) = let v__vec0:Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = vec in let vec:Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = @@ -356,6 +358,8 @@ let cond_subtract_3329_ (vec: Libcrux_ml_kem.Vector.Portable.Vector_type.t_Porta in vec +#pop-options + #push-options "--z3rlimit 150" let montgomery_multiply_by_constant diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Arithmetic.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Arithmetic.fsti index 92516558b..6a4fc4d3d 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Arithmetic.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Arithmetic.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Portable.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Compress.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Compress.fst index aa963a309..8ccf885b5 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Compress.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.Compress.fst @@ -1,8 +1,10 @@ module Libcrux_ml_kem.Vector.Portable.Compress -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul +#push-options "--z3rlimit 200 --ext context_pruning" + let compress_ciphertext_coefficient (coefficient_bits: u8) (fe: u16) = let compressed:u64 = (cast (fe <: u16) <: u64) < true); + f_repr_post + = + (fun + (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: t_Array i16 (sz 16)) + -> + true); + f_repr + = + fun (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Libcrux_ml_kem.Vector.Portable.Vector_type.to_i16_array x + } + let deserialize_1_ (a: t_Slice u8) = let _:Prims.unit = Libcrux_ml_kem.Vector.Portable.Serialize.deserialize_1_lemma a in let _:Prims.unit = Libcrux_ml_kem.Vector.Portable.Serialize.deserialize_1_bounded_lemma a in @@ -57,3 +77,597 @@ let serialize_4_ (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector let _:Prims.unit = assert (forall i. Rust_primitives.bounded (Seq.index a.f_elements i) 4) in let _:Prims.unit = Libcrux_ml_kem.Vector.Portable.Serialize.serialize_4_lemma a in Libcrux_ml_kem.Vector.Portable.Serialize.serialize_4_ a + +#push-options "--z3rlimit 400 --split_queries always" + +[@@ FStar.Tactics.Typeclasses.tcinstance] +let impl_1: Libcrux_ml_kem.Vector.Traits.t_Operations +Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = + { + _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; + _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; + _super_8706949974463268012 = FStar.Tactics.Typeclasses.solve; + f_ZERO_pre = (fun (_: Prims.unit) -> true); + f_ZERO_post + = + (fun (_: Prims.unit) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + impl.f_repr out == Seq.create 16 0s); + f_ZERO = (fun (_: Prims.unit) -> Libcrux_ml_kem.Vector.Portable.Vector_type.zero ()); + f_from_i16_array_pre + = + (fun (array: t_Slice i16) -> (Core.Slice.impl__len #i16 array <: usize) =. sz 16); + f_from_i16_array_post + = + (fun (array: t_Slice i16) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + impl.f_repr out == array); + f_from_i16_array + = + (fun (array: t_Slice i16) -> Libcrux_ml_kem.Vector.Portable.Vector_type.from_i16_array array); + f_to_i16_array_pre + = + (fun (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); + f_to_i16_array_post + = + (fun + (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: t_Array i16 (sz 16)) + -> + out == impl.f_repr x); + f_to_i16_array + = + (fun (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Libcrux_ml_kem.Vector.Portable.Vector_type.to_i16_array x); + f_add_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + forall i. + i < 16 ==> + Spec.Utils.is_intb (pow2 15 - 1) + (v (Seq.index lhs.f_elements i) + v (Seq.index rhs.f_elements i))); + f_add_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (result: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + forall i. + i < 16 ==> + (v (Seq.index result.f_elements i) == + v (Seq.index lhs.f_elements i) + v (Seq.index rhs.f_elements i))); + f_add + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Libcrux_ml_kem.Vector.Portable.Arithmetic.add lhs rhs); + f_sub_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + forall i. + i < 16 ==> + Spec.Utils.is_intb (pow2 15 - 1) + (v (Seq.index lhs.f_elements i) - v (Seq.index rhs.f_elements i))); + f_sub_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (result: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + forall i. + i < 16 ==> + (v (Seq.index result.f_elements i) == + v (Seq.index lhs.f_elements i) - v (Seq.index rhs.f_elements i))); + f_sub + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Libcrux_ml_kem.Vector.Portable.Arithmetic.sub lhs rhs); + f_multiply_by_constant_pre + = + (fun (vec: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (c: i16) -> + forall i. i < 16 ==> Spec.Utils.is_intb (pow2 15 - 1) (v (Seq.index vec.f_elements i) * v c) + ); + f_multiply_by_constant_post + = + (fun + (vec: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (c: i16) + (result: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + forall i. + i < 16 ==> (v (Seq.index result.f_elements i) == v (Seq.index vec.f_elements i) * v c)); + f_multiply_by_constant + = + (fun (vec: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (c: i16) -> + Libcrux_ml_kem.Vector.Portable.Arithmetic.multiply_by_constant vec c); + f_bitwise_and_with_constant_pre + = + (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (c: i16) -> true); + f_bitwise_and_with_constant_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (c: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + impl.f_repr out == Spec.Utils.map_array (fun x -> x &. c) (impl.f_repr v)); + f_bitwise_and_with_constant + = + (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (c: i16) -> + Libcrux_ml_kem.Vector.Portable.Arithmetic.bitwise_and_with_constant v c); + f_shift_right_pre + = + (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + v_SHIFT_BY >=. 0l && v_SHIFT_BY <. 16l); + f_shift_right_post + = + (fun + (v_SHIFT_BY: i32) + (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + (v_SHIFT_BY >=. 0l /\ v_SHIFT_BY <. 16l) ==> + impl.f_repr out == Spec.Utils.map_array (fun x -> x >>! v_SHIFT_BY) (impl.f_repr v)); + f_shift_right + = + (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Libcrux_ml_kem.Vector.Portable.Arithmetic.shift_right v_SHIFT_BY v); + f_cond_subtract_3329_pre + = + (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Spec.Utils.is_i16b_array (pow2 12 - 1) (impl.f_repr v)); + f_cond_subtract_3329_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + impl.f_repr out == + Spec.Utils.map_array (fun x -> if x >=. 3329s then x -! 3329s else x) (impl.f_repr v)); + f_cond_subtract_3329_ + = + (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Libcrux_ml_kem.Vector.Portable.Arithmetic.cond_subtract_3329_ v); + f_barrett_reduce_pre + = + (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Spec.Utils.is_i16b_array 28296 (impl.f_repr v)); + f_barrett_reduce_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + true); + f_barrett_reduce + = + (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Libcrux_ml_kem.Vector.Portable.Arithmetic.barrett_reduce v); + f_montgomery_multiply_by_constant_pre + = + (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (r: i16) -> + Spec.Utils.is_i16b 1664 r); + f_montgomery_multiply_by_constant_post + = + (fun + (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (r: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + true); + f_montgomery_multiply_by_constant + = + (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (r: i16) -> + Libcrux_ml_kem.Vector.Portable.Arithmetic.montgomery_multiply_by_constant v r); + f_compress_1_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + forall (i: nat). + i < 16 ==> v (Seq.index (impl.f_repr a) i) >= 0 /\ v (Seq.index (impl.f_repr a) i) < 3329); + f_compress_1_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + forall (i: nat). i < 16 ==> bounded (Seq.index (impl.f_repr out) i) 1); + f_compress_1_ + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Libcrux_ml_kem.Vector.Portable.Compress.compress_1_ a); + f_compress_pre + = + (fun + (v_COEFFICIENT_BITS: i32) + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ + v v_COEFFICIENT_BITS == 11) /\ + (forall (i: nat). + i < 16 ==> + v (Seq.index (impl.f_repr a) i) >= 0 /\ v (Seq.index (impl.f_repr a) i) < 3329)); + f_compress_post + = + (fun + (v_COEFFICIENT_BITS: i32) + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ + v v_COEFFICIENT_BITS == 11) ==> + (forall (i: nat). i < 16 ==> bounded (Seq.index (impl.f_repr out) i) (v v_COEFFICIENT_BITS)) + ); + f_compress + = + (fun + (v_COEFFICIENT_BITS: i32) + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Libcrux_ml_kem.Vector.Portable.Compress.compress v_COEFFICIENT_BITS a); + f_decompress_ciphertext_coefficient_pre + = + (fun + (v_COEFFICIENT_BITS: i32) + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ + v v_COEFFICIENT_BITS == 11) /\ + (forall (i: nat). + i < 16 ==> + v (Seq.index (impl.f_repr a) i) >= 0 /\ + v (Seq.index (impl.f_repr a) i) < pow2 (v v_COEFFICIENT_BITS))); + f_decompress_ciphertext_coefficient_post + = + (fun + (v_COEFFICIENT_BITS: i32) + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + true); + f_decompress_ciphertext_coefficient + = + (fun + (v_COEFFICIENT_BITS: i32) + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Libcrux_ml_kem.Vector.Portable.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS + a); + f_ntt_layer_1_step_pre + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ + Spec.Utils.is_i16b_array (11207 + 5 * 3328) (impl.f_repr a)); + f_ntt_layer_1_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Spec.Utils.is_i16b_array (11207 + 6 * 3328) (impl.f_repr out)); + f_ntt_layer_1_step + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + Libcrux_ml_kem.Vector.Portable.Ntt.ntt_layer_1_step a zeta0 zeta1 zeta2 zeta3); + f_ntt_layer_2_step_pre + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b_array (11207 + 4 * 3328) (impl.f_repr a)); + f_ntt_layer_2_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Spec.Utils.is_i16b_array (11207 + 5 * 3328) (impl.f_repr out)); + f_ntt_layer_2_step + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + -> + Libcrux_ml_kem.Vector.Portable.Ntt.ntt_layer_2_step a zeta0 zeta1); + f_ntt_layer_3_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (zeta: i16) -> + Spec.Utils.is_i16b 1664 zeta /\ Spec.Utils.is_i16b_array (11207 + 3 * 3328) (impl.f_repr a)); + f_ntt_layer_3_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Spec.Utils.is_i16b_array (11207 + 4 * 3328) (impl.f_repr out)); + f_ntt_layer_3_step + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (zeta: i16) -> + Libcrux_ml_kem.Vector.Portable.Ntt.ntt_layer_3_step a zeta); + f_inv_ntt_layer_1_step_pre + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ + Spec.Utils.is_i16b_array (4 * 3328) (impl.f_repr a)); + f_inv_ntt_layer_1_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); + f_inv_ntt_layer_1_step + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + Libcrux_ml_kem.Vector.Portable.Ntt.inv_ntt_layer_1_step a zeta0 zeta1 zeta2 zeta3); + f_inv_ntt_layer_2_step_pre + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b_array 3328 (impl.f_repr a)); + f_inv_ntt_layer_2_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); + f_inv_ntt_layer_2_step + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + -> + Libcrux_ml_kem.Vector.Portable.Ntt.inv_ntt_layer_2_step a zeta0 zeta1); + f_inv_ntt_layer_3_step_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (zeta: i16) -> + Spec.Utils.is_i16b 1664 zeta /\ Spec.Utils.is_i16b_array 3328 (impl.f_repr a)); + f_inv_ntt_layer_3_step_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); + f_inv_ntt_layer_3_step + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (zeta: i16) -> + Libcrux_ml_kem.Vector.Portable.Ntt.inv_ntt_layer_3_step a zeta); + f_ntt_multiply_pre + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ + Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ + Spec.Utils.is_i16b_array 3328 (impl.f_repr lhs) /\ + Spec.Utils.is_i16b_array 3328 (impl.f_repr rhs)); + f_ntt_multiply_post + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + -> + Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); + f_ntt_multiply + = + (fun + (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (zeta0: i16) + (zeta1: i16) + (zeta2: i16) + (zeta3: i16) + -> + Libcrux_ml_kem.Vector.Portable.Ntt.ntt_multiply lhs rhs zeta0 zeta1 zeta2 zeta3); + f_serialize_1_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Spec.MLKEM.serialize_pre 1 (impl.f_repr a)); + f_serialize_1_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: t_Array u8 (sz 2)) + -> + Spec.MLKEM.serialize_pre 1 (impl.f_repr a) ==> + Spec.MLKEM.serialize_post 1 (impl.f_repr a) out); + f_serialize_1_ + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_1_ a); + f_deserialize_1_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 2); + f_deserialize_1_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + sz (Seq.length a) =. sz 2 ==> Spec.MLKEM.deserialize_post 1 a (impl.f_repr out)); + f_deserialize_1_ = (fun (a: t_Slice u8) -> deserialize_1_ a); + f_serialize_4_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Spec.MLKEM.serialize_pre 4 (impl.f_repr a)); + f_serialize_4_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: t_Array u8 (sz 8)) + -> + Spec.MLKEM.serialize_pre 4 (impl.f_repr a) ==> + Spec.MLKEM.serialize_post 4 (impl.f_repr a) out); + f_serialize_4_ + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_4_ a); + f_deserialize_4_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 8); + f_deserialize_4_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + sz (Seq.length a) =. sz 8 ==> Spec.MLKEM.deserialize_post 4 a (impl.f_repr out)); + f_deserialize_4_ = (fun (a: t_Slice u8) -> deserialize_4_ a); + f_serialize_5_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); + f_serialize_5_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: t_Array u8 (sz 10)) + -> + true); + f_serialize_5_ + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_5_ a); + f_deserialize_5_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 10); + f_deserialize_5_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); + f_deserialize_5_ = (fun (a: t_Slice u8) -> deserialize_5_ a); + f_serialize_10_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Spec.MLKEM.serialize_pre 10 (impl.f_repr a)); + f_serialize_10_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: t_Array u8 (sz 20)) + -> + Spec.MLKEM.serialize_pre 10 (impl.f_repr a) ==> + Spec.MLKEM.serialize_post 10 (impl.f_repr a) out); + f_serialize_10_ + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_10_ a); + f_deserialize_10_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 20); + f_deserialize_10_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + sz (Seq.length a) =. sz 20 ==> Spec.MLKEM.deserialize_post 10 a (impl.f_repr out)); + f_deserialize_10_ = (fun (a: t_Slice u8) -> deserialize_10_ a); + f_serialize_11_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); + f_serialize_11_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: t_Array u8 (sz 22)) + -> + true); + f_serialize_11_ + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_11_ a); + f_deserialize_11_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 22); + f_deserialize_11_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); + f_deserialize_11_ = (fun (a: t_Slice u8) -> deserialize_11_ a); + f_serialize_12_pre + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + Spec.MLKEM.serialize_pre 12 (impl.f_repr a)); + f_serialize_12_post + = + (fun + (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) + (out: t_Array u8 (sz 24)) + -> + Spec.MLKEM.serialize_pre 12 (impl.f_repr a) ==> + Spec.MLKEM.serialize_post 12 (impl.f_repr a) out); + f_serialize_12_ + = + (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_12_ a); + f_deserialize_12_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 24); + f_deserialize_12_post + = + (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> + sz (Seq.length a) =. sz 24 ==> Spec.MLKEM.deserialize_post 12 a (impl.f_repr out)); + f_deserialize_12_ = (fun (a: t_Slice u8) -> deserialize_12_ a); + f_rej_sample_pre + = + (fun (a: t_Slice u8) (out: t_Slice i16) -> + (Core.Slice.impl__len #u8 a <: usize) =. sz 24 && + (Core.Slice.impl__len #i16 out <: usize) =. sz 16); + f_rej_sample_post + = + (fun (a: t_Slice u8) (out: t_Slice i16) (out_future, result: (t_Slice i16 & usize)) -> + Seq.length out_future == Seq.length out /\ v result <= 16); + f_rej_sample + = + fun (a: t_Slice u8) (out: t_Slice i16) -> + let tmp0, out1:(t_Slice i16 & usize) = + Libcrux_ml_kem.Vector.Portable.Sampling.rej_sample a out + in + let out:t_Slice i16 = tmp0 in + let hax_temp_output:usize = out1 in + out, hax_temp_output <: (t_Slice i16 & usize) + } + +#pop-options diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.fsti index 10098ed48..c9cf458ce 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Portable.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Portable -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -27,24 +27,8 @@ val serialize_5_ (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector : Prims.Pure (t_Array u8 (sz 10)) Prims.l_True (fun _ -> Prims.l_True) [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl: Libcrux_ml_kem.Vector.Traits.t_Repr -Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = - { - _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; - _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; - f_repr_pre = (fun (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); - f_repr_post - = - (fun - (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: t_Array i16 (sz 16)) - -> - true); - f_repr - = - fun (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Libcrux_ml_kem.Vector.Portable.Vector_type.to_i16_array x - } +val impl:Libcrux_ml_kem.Vector.Traits.t_Repr +Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector val deserialize_1_ (a: t_Slice u8) : Prims.Pure Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector @@ -114,592 +98,6 @@ val serialize_4_ (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector Spec.MLKEM.serialize_pre 4 (impl.f_repr a) ==> Spec.MLKEM.serialize_post 4 (impl.f_repr a) out) -#push-options "--z3rlimit 400 --split_queries always" - [@@ FStar.Tactics.Typeclasses.tcinstance] -let impl_1: Libcrux_ml_kem.Vector.Traits.t_Operations -Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector = - { - _super_11581440318597584651 = FStar.Tactics.Typeclasses.solve; - _super_9442900250278684536 = FStar.Tactics.Typeclasses.solve; - _super_8706949974463268012 = FStar.Tactics.Typeclasses.solve; - f_ZERO_pre = (fun (_: Prims.unit) -> true); - f_ZERO_post - = - (fun (_: Prims.unit) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - impl.f_repr out == Seq.create 16 0s); - f_ZERO = (fun (_: Prims.unit) -> Libcrux_ml_kem.Vector.Portable.Vector_type.zero ()); - f_from_i16_array_pre - = - (fun (array: t_Slice i16) -> (Core.Slice.impl__len #i16 array <: usize) =. sz 16); - f_from_i16_array_post - = - (fun (array: t_Slice i16) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - impl.f_repr out == array); - f_from_i16_array - = - (fun (array: t_Slice i16) -> Libcrux_ml_kem.Vector.Portable.Vector_type.from_i16_array array); - f_to_i16_array_pre - = - (fun (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); - f_to_i16_array_post - = - (fun - (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: t_Array i16 (sz 16)) - -> - out == impl.f_repr x); - f_to_i16_array - = - (fun (x: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Libcrux_ml_kem.Vector.Portable.Vector_type.to_i16_array x); - f_add_pre - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - forall i. - i < 16 ==> - Spec.Utils.is_intb (pow2 15 - 1) - (v (Seq.index lhs.f_elements i) + v (Seq.index rhs.f_elements i))); - f_add_post - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (result: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - forall i. - i < 16 ==> - (v (Seq.index result.f_elements i) == - v (Seq.index lhs.f_elements i) + v (Seq.index rhs.f_elements i))); - f_add - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Libcrux_ml_kem.Vector.Portable.Arithmetic.add lhs rhs); - f_sub_pre - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - forall i. - i < 16 ==> - Spec.Utils.is_intb (pow2 15 - 1) - (v (Seq.index lhs.f_elements i) - v (Seq.index rhs.f_elements i))); - f_sub_post - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (result: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - forall i. - i < 16 ==> - (v (Seq.index result.f_elements i) == - v (Seq.index lhs.f_elements i) - v (Seq.index rhs.f_elements i))); - f_sub - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Libcrux_ml_kem.Vector.Portable.Arithmetic.sub lhs rhs); - f_multiply_by_constant_pre - = - (fun (vec: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (c: i16) -> - forall i. i < 16 ==> Spec.Utils.is_intb (pow2 15 - 1) (v (Seq.index vec.f_elements i) * v c) - ); - f_multiply_by_constant_post - = - (fun - (vec: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (c: i16) - (result: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - forall i. - i < 16 ==> (v (Seq.index result.f_elements i) == v (Seq.index vec.f_elements i) * v c)); - f_multiply_by_constant - = - (fun (vec: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (c: i16) -> - Libcrux_ml_kem.Vector.Portable.Arithmetic.multiply_by_constant vec c); - f_bitwise_and_with_constant_pre - = - (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (c: i16) -> true); - f_bitwise_and_with_constant_post - = - (fun - (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (c: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - impl.f_repr out == Spec.Utils.map_array (fun x -> x &. c) (impl.f_repr v)); - f_bitwise_and_with_constant - = - (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (c: i16) -> - Libcrux_ml_kem.Vector.Portable.Arithmetic.bitwise_and_with_constant v c); - f_shift_right_pre - = - (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - v_SHIFT_BY >=. 0l && v_SHIFT_BY <. 16l); - f_shift_right_post - = - (fun - (v_SHIFT_BY: i32) - (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - (v_SHIFT_BY >=. 0l /\ v_SHIFT_BY <. 16l) ==> - impl.f_repr out == Spec.Utils.map_array (fun x -> x >>! v_SHIFT_BY) (impl.f_repr v)); - f_shift_right - = - (fun (v_SHIFT_BY: i32) (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Libcrux_ml_kem.Vector.Portable.Arithmetic.shift_right v_SHIFT_BY v); - f_cond_subtract_3329_pre - = - (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Spec.Utils.is_i16b_array (pow2 12 - 1) (impl.f_repr v)); - f_cond_subtract_3329_post - = - (fun - (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - impl.f_repr out == - Spec.Utils.map_array (fun x -> if x >=. 3329s then x -! 3329s else x) (impl.f_repr v)); - f_cond_subtract_3329_ - = - (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Libcrux_ml_kem.Vector.Portable.Arithmetic.cond_subtract_3329_ v); - f_barrett_reduce_pre - = - (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Spec.Utils.is_i16b_array 28296 (impl.f_repr v)); - f_barrett_reduce_post - = - (fun - (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - true); - f_barrett_reduce - = - (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Libcrux_ml_kem.Vector.Portable.Arithmetic.barrett_reduce v); - f_montgomery_multiply_by_constant_pre - = - (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (r: i16) -> - Spec.Utils.is_i16b 1664 r); - f_montgomery_multiply_by_constant_post - = - (fun - (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (r: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - true); - f_montgomery_multiply_by_constant - = - (fun (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (r: i16) -> - Libcrux_ml_kem.Vector.Portable.Arithmetic.montgomery_multiply_by_constant v r); - f_compress_1_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - forall (i: nat). - i < 16 ==> v (Seq.index (impl.f_repr a) i) >= 0 /\ v (Seq.index (impl.f_repr a) i) < 3329); - f_compress_1_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - forall (i: nat). i < 16 ==> bounded (Seq.index (impl.f_repr out) i) 1); - f_compress_1_ - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Libcrux_ml_kem.Vector.Portable.Compress.compress_1_ a); - f_compress_pre - = - (fun - (v_COEFFICIENT_BITS: i32) - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ - v v_COEFFICIENT_BITS == 11) /\ - (forall (i: nat). - i < 16 ==> - v (Seq.index (impl.f_repr a) i) >= 0 /\ v (Seq.index (impl.f_repr a) i) < 3329)); - f_compress_post - = - (fun - (v_COEFFICIENT_BITS: i32) - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ - v v_COEFFICIENT_BITS == 11) ==> - (forall (i: nat). i < 16 ==> bounded (Seq.index (impl.f_repr out) i) (v v_COEFFICIENT_BITS)) - ); - f_compress - = - (fun - (v_COEFFICIENT_BITS: i32) - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Libcrux_ml_kem.Vector.Portable.Compress.compress v_COEFFICIENT_BITS a); - f_decompress_ciphertext_coefficient_pre - = - (fun - (v_COEFFICIENT_BITS: i32) - (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - v_COEFFICIENT_BITS =. 4l || v_COEFFICIENT_BITS =. 5l || v_COEFFICIENT_BITS =. 10l || - v_COEFFICIENT_BITS =. 11l); - f_decompress_ciphertext_coefficient_post - = - (fun - (v_COEFFICIENT_BITS: i32) - (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - true); - f_decompress_ciphertext_coefficient - = - (fun - (v_COEFFICIENT_BITS: i32) - (v: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Libcrux_ml_kem.Vector.Portable.Compress.decompress_ciphertext_coefficient v_COEFFICIENT_BITS - v); - f_ntt_layer_1_step_pre - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ - Spec.Utils.is_i16b_array (11207 + 5 * 3328) (impl.f_repr a)); - f_ntt_layer_1_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Spec.Utils.is_i16b_array (11207 + 6 * 3328) (impl.f_repr out)); - f_ntt_layer_1_step - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - Libcrux_ml_kem.Vector.Portable.Ntt.ntt_layer_1_step a zeta0 zeta1 zeta2 zeta3); - f_ntt_layer_2_step_pre - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b_array (11207 + 4 * 3328) (impl.f_repr a)); - f_ntt_layer_2_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Spec.Utils.is_i16b_array (11207 + 5 * 3328) (impl.f_repr out)); - f_ntt_layer_2_step - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - -> - Libcrux_ml_kem.Vector.Portable.Ntt.ntt_layer_2_step a zeta0 zeta1); - f_ntt_layer_3_step_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (zeta: i16) -> - Spec.Utils.is_i16b 1664 zeta /\ Spec.Utils.is_i16b_array (11207 + 3 * 3328) (impl.f_repr a)); - f_ntt_layer_3_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Spec.Utils.is_i16b_array (11207 + 4 * 3328) (impl.f_repr out)); - f_ntt_layer_3_step - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (zeta: i16) -> - Libcrux_ml_kem.Vector.Portable.Ntt.ntt_layer_3_step a zeta); - f_inv_ntt_layer_1_step_pre - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ - Spec.Utils.is_i16b_array (4 * 3328) (impl.f_repr a)); - f_inv_ntt_layer_1_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); - f_inv_ntt_layer_1_step - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - Libcrux_ml_kem.Vector.Portable.Ntt.inv_ntt_layer_1_step a zeta0 zeta1 zeta2 zeta3); - f_inv_ntt_layer_2_step_pre - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b_array 3328 (impl.f_repr a)); - f_inv_ntt_layer_2_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); - f_inv_ntt_layer_2_step - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - -> - Libcrux_ml_kem.Vector.Portable.Ntt.inv_ntt_layer_2_step a zeta0 zeta1); - f_inv_ntt_layer_3_step_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (zeta: i16) -> - Spec.Utils.is_i16b 1664 zeta /\ Spec.Utils.is_i16b_array 3328 (impl.f_repr a)); - f_inv_ntt_layer_3_step_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); - f_inv_ntt_layer_3_step - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) (zeta: i16) -> - Libcrux_ml_kem.Vector.Portable.Ntt.inv_ntt_layer_3_step a zeta); - f_ntt_multiply_pre - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - Spec.Utils.is_i16b 1664 zeta0 /\ Spec.Utils.is_i16b 1664 zeta1 /\ - Spec.Utils.is_i16b 1664 zeta2 /\ Spec.Utils.is_i16b 1664 zeta3 /\ - Spec.Utils.is_i16b_array 3328 (impl.f_repr lhs) /\ - Spec.Utils.is_i16b_array 3328 (impl.f_repr rhs)); - f_ntt_multiply_post - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - -> - Spec.Utils.is_i16b_array 3328 (impl.f_repr out)); - f_ntt_multiply - = - (fun - (lhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (rhs: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (zeta0: i16) - (zeta1: i16) - (zeta2: i16) - (zeta3: i16) - -> - Libcrux_ml_kem.Vector.Portable.Ntt.ntt_multiply lhs rhs zeta0 zeta1 zeta2 zeta3); - f_serialize_1_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Spec.MLKEM.serialize_pre 1 (impl.f_repr a)); - f_serialize_1_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: t_Array u8 (sz 2)) - -> - Spec.MLKEM.serialize_pre 1 (impl.f_repr a) ==> - Spec.MLKEM.serialize_post 1 (impl.f_repr a) out); - f_serialize_1_ - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_1_ a); - f_deserialize_1_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 2); - f_deserialize_1_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - sz (Seq.length a) =. sz 2 ==> Spec.MLKEM.deserialize_post 1 a (impl.f_repr out)); - f_deserialize_1_ = (fun (a: t_Slice u8) -> deserialize_1_ a); - f_serialize_4_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Spec.MLKEM.serialize_pre 4 (impl.f_repr a)); - f_serialize_4_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: t_Array u8 (sz 8)) - -> - Spec.MLKEM.serialize_pre 4 (impl.f_repr a) ==> - Spec.MLKEM.serialize_post 4 (impl.f_repr a) out); - f_serialize_4_ - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_4_ a); - f_deserialize_4_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 8); - f_deserialize_4_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - sz (Seq.length a) =. sz 8 ==> Spec.MLKEM.deserialize_post 4 a (impl.f_repr out)); - f_deserialize_4_ = (fun (a: t_Slice u8) -> deserialize_4_ a); - f_serialize_5_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); - f_serialize_5_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: t_Array u8 (sz 10)) - -> - true); - f_serialize_5_ - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_5_ a); - f_deserialize_5_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 10); - f_deserialize_5_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); - f_deserialize_5_ = (fun (a: t_Slice u8) -> deserialize_5_ a); - f_serialize_10_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Spec.MLKEM.serialize_pre 10 (impl.f_repr a)); - f_serialize_10_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: t_Array u8 (sz 20)) - -> - Spec.MLKEM.serialize_pre 10 (impl.f_repr a) ==> - Spec.MLKEM.serialize_post 10 (impl.f_repr a) out); - f_serialize_10_ - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_10_ a); - f_deserialize_10_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 20); - f_deserialize_10_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - sz (Seq.length a) =. sz 20 ==> Spec.MLKEM.deserialize_post 10 a (impl.f_repr out)); - f_deserialize_10_ = (fun (a: t_Slice u8) -> deserialize_10_ a); - f_serialize_11_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); - f_serialize_11_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: t_Array u8 (sz 22)) - -> - true); - f_serialize_11_ - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_11_ a); - f_deserialize_11_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 22); - f_deserialize_11_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> true); - f_deserialize_11_ = (fun (a: t_Slice u8) -> deserialize_11_ a); - f_serialize_12_pre - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - Spec.MLKEM.serialize_pre 12 (impl.f_repr a)); - f_serialize_12_post - = - (fun - (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) - (out: t_Array u8 (sz 24)) - -> - Spec.MLKEM.serialize_pre 12 (impl.f_repr a) ==> - Spec.MLKEM.serialize_post 12 (impl.f_repr a) out); - f_serialize_12_ - = - (fun (a: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> serialize_12_ a); - f_deserialize_12_pre = (fun (a: t_Slice u8) -> (Core.Slice.impl__len #u8 a <: usize) =. sz 24); - f_deserialize_12_post - = - (fun (a: t_Slice u8) (out: Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector) -> - sz (Seq.length a) =. sz 24 ==> Spec.MLKEM.deserialize_post 12 a (impl.f_repr out)); - f_deserialize_12_ = (fun (a: t_Slice u8) -> deserialize_12_ a); - f_rej_sample_pre - = - (fun (a: t_Slice u8) (out: t_Slice i16) -> - (Core.Slice.impl__len #u8 a <: usize) =. sz 24 && - (Core.Slice.impl__len #i16 out <: usize) =. sz 16); - f_rej_sample_post - = - (fun (a: t_Slice u8) (out: t_Slice i16) (out_future, result: (t_Slice i16 & usize)) -> - Seq.length out_future == Seq.length out /\ v result <= 16); - f_rej_sample - = - fun (a: t_Slice u8) (out: t_Slice i16) -> - let tmp0, out1:(t_Slice i16 & usize) = - Libcrux_ml_kem.Vector.Portable.Sampling.rej_sample a out - in - let out:t_Slice i16 = tmp0 in - let hax_temp_output:usize = out1 in - out, hax_temp_output <: (t_Slice i16 & usize) - } - -#pop-options +val impl_1:Libcrux_ml_kem.Vector.Traits.t_Operations +Libcrux_ml_kem.Vector.Portable.Vector_type.t_PortableVector diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Rej_sample_table.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Rej_sample_table.fsti index f1aa1ee53..3d4f6be0a 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Rej_sample_table.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Rej_sample_table.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Rej_sample_table -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fst b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fst index cbc90050c..69e93a949 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fst +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fst @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Traits -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fsti b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fsti index cb32321d0..21e6d6a50 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fsti +++ b/libcrux-ml-kem/proofs/fstar/extraction/Libcrux_ml_kem.Vector.Traits.fsti @@ -1,5 +1,5 @@ module Libcrux_ml_kem.Vector.Traits -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" open Core open FStar.Mul @@ -167,11 +167,15 @@ class t_Operations (v_Self: Type0) = { -> Prims.Pure v_Self (f_compress_pre v_COEFFICIENT_BITS x0) (fun result -> f_compress_post v_COEFFICIENT_BITS x0 result); - f_decompress_ciphertext_coefficient_pre:v_COEFFICIENT_BITS: i32 -> v: v_Self + f_decompress_ciphertext_coefficient_pre:v_COEFFICIENT_BITS: i32 -> a: v_Self -> pred: Type0 - { v_COEFFICIENT_BITS =. 4l || v_COEFFICIENT_BITS =. 5l || v_COEFFICIENT_BITS =. 10l || - v_COEFFICIENT_BITS =. 11l ==> + { (v v_COEFFICIENT_BITS == 4 \/ v v_COEFFICIENT_BITS == 5 \/ v v_COEFFICIENT_BITS == 10 \/ + v v_COEFFICIENT_BITS == 11) /\ + (forall (i: nat). + i < 16 ==> + v (Seq.index (f_repr a) i) >= 0 /\ + v (Seq.index (f_repr a) i) < pow2 (v v_COEFFICIENT_BITS)) ==> pred }; f_decompress_ciphertext_coefficient_post:v_COEFFICIENT_BITS: i32 -> v_Self -> v_Self -> Type0; f_decompress_ciphertext_coefficient:v_COEFFICIENT_BITS: i32 -> x0: v_Self diff --git a/libcrux-ml-kem/proofs/fstar/extraction/Makefile b/libcrux-ml-kem/proofs/fstar/extraction/Makefile index b054ead79..1aa982aae 100644 --- a/libcrux-ml-kem/proofs/fstar/extraction/Makefile +++ b/libcrux-ml-kem/proofs/fstar/extraction/Makefile @@ -4,9 +4,6 @@ ADMIT_MODULES = Libcrux_ml_kem.Vector.Avx2.fsti \ Libcrux_ml_kem.Vector.Avx2.fst \ Libcrux_ml_kem.Vector.Avx2.Ntt.fst \ Libcrux_ml_kem.Vector.Avx2.Sampling.fst \ - Libcrux_ml_kem.Vector.Portable.Compress.fst \ - Libcrux_ml_kem.Vector.Portable.Sampling.fst \ - Libcrux_ml_kem.Vector.Portable.Vector_type.fst \ Libcrux_ml_kem.Vector.Rej_sample_table.fsti \ Libcrux_ml_kem.Vector.Neon.Arithmetic.fst \ Libcrux_ml_kem.Vector.Neon.Compress.fst \ @@ -16,4 +13,8 @@ ADMIT_MODULES = Libcrux_ml_kem.Vector.Avx2.fsti \ Libcrux_ml_kem.Vector.Neon.Serialize.fst \ Libcrux_ml_kem.Vector.Neon.Vector_type.fst +FSTAR_INCLUDE_DIRS_EXTRA += ../spec \ + $(shell git rev-parse --show-toplevel)/fstar-helpers/fstar-bitvec \ + $(shell git rev-parse --show-toplevel)/libcrux-intrinsics/proofs/fstar/extraction + include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.base diff --git a/libcrux-ml-kem/proofs/fstar/spec/Makefile b/libcrux-ml-kem/proofs/fstar/spec/Makefile index b4ce70a38..7520f4797 100644 --- a/libcrux-ml-kem/proofs/fstar/spec/Makefile +++ b/libcrux-ml-kem/proofs/fstar/spec/Makefile @@ -1 +1,3 @@ +FSTAR_INCLUDE_DIRS_EXTRA += $(shell git rev-parse --show-toplevel)/fstar-helpers/fstar-bitvec + include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.base diff --git a/libcrux-ml-kem/proofs/fstar/spec/Spec.MLKEM.fst b/libcrux-ml-kem/proofs/fstar/spec/Spec.MLKEM.fst index a6114ea93..5fc57dfcc 100644 --- a/libcrux-ml-kem/proofs/fstar/spec/Spec.MLKEM.fst +++ b/libcrux-ml-kem/proofs/fstar/spec/Spec.MLKEM.fst @@ -221,11 +221,11 @@ let decode_then_decompress_u (#r:rank) (arr: t_Array u8 (v_C1_SIZE r)): vector r byte_decode_then_decompress (v d) slice ) -let compress_then_encode_v (u:usize{u == sz 4 \/ u == sz 5}): polynomial -> t_Array u8 (sz 32 *! u) - = compress_then_byte_encode (v u) +let compress_then_encode_v (#r:rank): polynomial -> t_Array u8 (v_C2_SIZE r) + = compress_then_byte_encode (v (v_VECTOR_V_COMPRESSION_FACTOR r)) -let decode_then_decompress_v (u:usize{u == sz 4 \/ u == sz 5}): t_Array u8 (sz 32 *! u) -> polynomial - = byte_decode_then_decompress (v u) +let decode_then_decompress_v (#r:rank): t_Array u8 (v_C2_SIZE r) -> polynomial + = byte_decode_then_decompress (v (v_VECTOR_V_COMPRESSION_FACTOR r)) (** IND-CPA Functions *) @@ -263,6 +263,7 @@ val ind_cpa_encrypt_unpacked (r:rank) (matrix_A_as_ntt:matrix r) : t_MLKEMCiphertext r +#push-options "--z3rlimit 500 --ext context_pruning" let ind_cpa_encrypt_unpacked r message randomness t_as_ntt matrix_A_as_ntt = let r_as_ntt = sample_vector_cbd_then_ntt #r randomness (sz 0) in let error_1 = sample_vector_cbd2 #r randomness r in @@ -271,8 +272,9 @@ let ind_cpa_encrypt_unpacked r message randomness t_as_ntt matrix_A_as_ntt = let mu = decode_then_decompress_message message in let v = poly_add (poly_add (vector_dot_product_ntt t_as_ntt r_as_ntt) error_2) mu in let c1 = compress_then_encode_u #r u in - let c2 = compress_then_encode_v (v_VECTOR_V_COMPRESSION_FACTOR r) v in + let c2 = compress_then_encode_v #r v in concat c1 c2 +#pop-options /// This function implements Algorithm 13 of the /// NIST FIPS 203 specification; this is the MLKEM CPA-PKE encryption algorithm. @@ -297,7 +299,7 @@ val ind_cpa_decrypt_unpacked (r:rank) let ind_cpa_decrypt_unpacked r ciphertext secret_as_ntt = let (c1,c2) = split ciphertext (v_C1_SIZE r) in let u = decode_then_decompress_u #r c1 in - let v = decode_then_decompress_v (v_VECTOR_V_COMPRESSION_FACTOR r) c2 in + let v = decode_then_decompress_v #r c2 in let w = poly_sub v (poly_inv_ntt (vector_dot_product_ntt secret_as_ntt (vector_ntt u))) in compress_then_encode_message w diff --git a/libcrux-ml-kem/src/ind_cca.rs b/libcrux-ml-kem/src/ind_cca.rs index 3d05ce368..e0fa8f6a0 100644 --- a/libcrux-ml-kem/src/ind_cca.rs +++ b/libcrux-ml-kem/src/ind_cca.rs @@ -33,7 +33,9 @@ pub(crate) mod multiplexing; /// To use these, runtime checks must be performed before calling them. pub(crate) mod instantiations; + /// Serialize the secret key. + #[inline(always)] #[hax_lib::fstar::options("--z3rlimit 150")] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ @@ -41,44 +43,77 @@ pub(crate) mod instantiations; ${private_key.len()} == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ ${public_key.len()} == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ ${implicit_rejection_value.len()} == Spec.MLKEM.v_SHARED_SECRET_SIZE"))] -#[hax_lib::ensures(|result| fstar!("$result == Seq.append $private_key ( +#[hax_lib::ensures(|result| fstar!("${serialized}_future == Seq.append $private_key ( Seq.append $public_key ( Seq.append (Spec.Utils.v_H $public_key) $implicit_rejection_value))"))] -fn serialize_kem_secret_key>( +fn serialize_kem_secret_key_mut< + const K: usize, + const SERIALIZED_KEY_LEN: usize, + Hasher: Hash, +>( private_key: &[u8], public_key: &[u8], implicit_rejection_value: &[u8], -) -> [u8; SERIALIZED_KEY_LEN] { - let mut out = [0u8; SERIALIZED_KEY_LEN]; + serialized: &mut [u8; SERIALIZED_KEY_LEN], +) { let mut pointer = 0; - out[pointer..pointer + private_key.len()].copy_from_slice(private_key); + serialized[pointer..pointer + private_key.len()].copy_from_slice(private_key); pointer += private_key.len(); - out[pointer..pointer + public_key.len()].copy_from_slice(public_key); + serialized[pointer..pointer + public_key.len()].copy_from_slice(public_key); pointer += public_key.len(); - out[pointer..pointer + H_DIGEST_SIZE].copy_from_slice(&Hasher::H(public_key)); + serialized[pointer..pointer + H_DIGEST_SIZE].copy_from_slice(&Hasher::H(public_key)); pointer += H_DIGEST_SIZE; - out[pointer..pointer + implicit_rejection_value.len()] + serialized[pointer..pointer + implicit_rejection_value.len()] .copy_from_slice(implicit_rejection_value); + hax_lib::fstar!("let open Spec.Utils in - assert (Seq.slice $out 0 (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K)) `Seq.equal` $private_key); - assert (Seq.slice $out (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K)) - (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K)) `Seq.equal` $public_key); - assert (Seq.slice $out (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! - Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K)) - (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! - Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K +! - Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE)) - `Seq.equal` Libcrux_ml_kem.Hash_functions.f_H #$:Hasher #$K $public_key); - assert (Seq.slice $out (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! - Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K +! - Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE)) - (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! - Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K +! - Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE +! - Spec.MLKEM.v_SHARED_SECRET_SIZE)) - == $implicit_rejection_value); - lemma_slice_append_4 $out $private_key $public_key (Libcrux_ml_kem.Hash_functions.f_H #$:Hasher #$K $public_key) $implicit_rejection_value"); + assert (Seq.slice serialized 0 (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K)) `Seq.equal` $private_key); + assert (Seq.slice serialized (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K)) + (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K)) `Seq.equal` $public_key); + assert (Seq.slice serialized (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! + Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K)) + (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! + Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K +! + Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE)) + `Seq.equal` Libcrux_ml_kem.Hash_functions.f_H #$:Hasher #$K $public_key); + assert (Seq.slice serialized (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! + Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K +! + Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE)) + (v #usize_inttype (Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K +! + Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K +! + Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE +! + Spec.MLKEM.v_SHARED_SECRET_SIZE)) + == $implicit_rejection_value); + lemma_slice_append_4 serialized $private_key $public_key (Libcrux_ml_kem.Hash_functions.f_H #$:Hasher #$K $public_key) $implicit_rejection_value"); + +} + + +#[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 150")] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SERIALIZED_KEY_LEN == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + ${private_key.len()} == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + ${public_key.len()} == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + ${implicit_rejection_value.len()} == Spec.MLKEM.v_SHARED_SECRET_SIZE"))] +#[hax_lib::ensures(|result| fstar!("$result == Seq.append $private_key ( + Seq.append $public_key ( + Seq.append (Spec.Utils.v_H $public_key) + $implicit_rejection_value))"))] +fn serialize_kem_secret_key>( + private_key: &[u8], + public_key: &[u8], + implicit_rejection_value: &[u8], +) -> [u8; SERIALIZED_KEY_LEN] { + let mut out = [0u8; SERIALIZED_KEY_LEN]; + + serialize_kem_secret_key_mut::( + private_key, + public_key, + implicit_rejection_value, + &mut out, + ); out } @@ -117,6 +152,7 @@ fn validate_public_key< /// Note that the size checks in 7.2 1 and 2 are covered by the `SECRET_KEY_SIZE` /// and `CIPHERTEXT_SIZE` in the `private_key` and `ciphertext` types. #[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 300")] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K"))] @@ -128,6 +164,19 @@ fn validate_private_key< >( private_key: &MlKemPrivateKey, _ciphertext: &MlKemCiphertext, +) -> bool { + validate_private_key_only::(private_key) +} + +/// Validate an ML-KEM private key. +/// +/// This implements the Hash check in 7.3 3. +#[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 300")] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K"))] +fn validate_private_key_only>( + private_key: &MlKemPrivateKey, ) -> bool { // Eurydice can't access values directly on the types. We need to go to the // `value` directly. @@ -143,6 +192,7 @@ fn validate_private_key< /// /// Depending on the `Vector` and `Hasher` used, this requires different hardware /// features +#[hax_lib::fstar::options("--z3rlimit 300")] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ $PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ @@ -193,7 +243,7 @@ fn generate_keypair< MlKemKeyPair::from(private_key, MlKemPublicKey::from(public_key)) } -#[hax_lib::fstar::options("--z3rlimit 150")] +#[hax_lib::fstar::options("--z3rlimit 300")] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ @@ -309,9 +359,8 @@ pub(crate) fn decapsulate< ciphertext: &MlKemCiphertext, ) -> MlKemSharedSecret { hax_lib::fstar!("assert (v $CIPHERTEXT_SIZE == v $IMPLICIT_REJECTION_HASH_INPUT_SIZE - v $SHARED_SECRET_SIZE)"); - let (ind_cpa_secret_key, secret_key) = private_key.value.split_at(CPA_SECRET_KEY_SIZE); - let (ind_cpa_public_key, secret_key) = secret_key.split_at(PUBLIC_KEY_SIZE); - let (ind_cpa_public_key_hash, implicit_rejection_value) = secret_key.split_at(H_DIGEST_SIZE); + let (ind_cpa_secret_key, ind_cpa_public_key, ind_cpa_public_key_hash, implicit_rejection_value) = + unpack_private_key::(&private_key.value); hax_lib::fstar!("assert ($ind_cpa_secret_key == slice ${private_key}.f_value (sz 0) $CPA_SECRET_KEY_SIZE); assert ($ind_cpa_public_key == slice ${private_key}.f_value $CPA_SECRET_KEY_SIZE ($CPA_SECRET_KEY_SIZE +! $PUBLIC_KEY_SIZE)); @@ -393,7 +442,8 @@ pub(crate) mod unpacked { constant_time_ops::{ compare_ciphertexts_in_constant_time, select_shared_secret_in_constant_time, }, - ind_cpa::{generate_keypair_unpacked, serialize_public_key_mut, unpacked::*}, + hash_functions::portable::PortableHash, + ind_cpa::{self, generate_keypair_unpacked, serialize_public_key_mut, unpacked::*}, matrix::sample_matrix_A, polynomial::PolynomialRingElement, serialize::deserialize_ring_elements_reduced, @@ -480,7 +530,7 @@ pub(crate) mod unpacked { self.f_ind_cpa_public_key.f_t_as_ntt)) self.f_ind_cpa_public_key.f_seed_for_A)") )] - pub fn serialized_public_key_mut< + pub fn serialized_mut< const RANKED_BYTES_PER_RING_ELEMENT: usize, const PUBLIC_KEY_SIZE: usize, >( @@ -508,17 +558,21 @@ pub(crate) mod unpacked { self.f_ind_cpa_public_key.f_t_as_ntt)) self.f_ind_cpa_public_key.f_seed_for_A)") )] - pub fn serialized_public_key< + pub fn serialized< const RANKED_BYTES_PER_RING_ELEMENT: usize, const PUBLIC_KEY_SIZE: usize, >( &self, ) -> MlKemPublicKey { - serialize_public_key::( + MlKemPublicKey::from(serialize_public_key::< + K, + RANKED_BYTES_PER_RING_ELEMENT, + PUBLIC_KEY_SIZE, + Vector, + >( &self.ind_cpa_public_key.t_as_ntt, &self.ind_cpa_public_key.seed_for_A, - ) - .into() + )) } } @@ -532,6 +586,62 @@ pub(crate) mod unpacked { } } + /// Take a serialized private key and generate an unpacked key pair from it. + #[inline(always)] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K"))] + pub fn keys_from_private_key< + const K: usize, + const SECRET_KEY_SIZE: usize, + const CPA_SECRET_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const BYTES_PER_RING_ELEMENT: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + Vector: Operations, + >( + private_key: &MlKemPrivateKey, + key_pair: &mut MlKemKeyPairUnpacked, + ) { + let ( + ind_cpa_secret_key, + ind_cpa_public_key, + ind_cpa_public_key_hash, + implicit_rejection_value, + ) = unpack_private_key::(&private_key.value); + + // XXX: We need to copy_from_slice here because karamel can't handle + // the assignment cf. https://github.com/FStarLang/karamel/pull/491 + + key_pair + .private_key + .ind_cpa_private_key + .secret_as_ntt + .copy_from_slice(&ind_cpa::deserialize_secret_key::( + ind_cpa_secret_key, + )); + ind_cpa::build_unpacked_public_key_mut::>( + ind_cpa_public_key, + &mut key_pair.public_key.ind_cpa_public_key, + ); + key_pair + .public_key + .public_key_hash + .copy_from_slice(ind_cpa_public_key_hash); + key_pair + .private_key + .implicit_rejection_value + .copy_from_slice(implicit_rejection_value); + key_pair + .public_key + .ind_cpa_public_key + .seed_for_A + .copy_from_slice(&ind_cpa_public_key[T_AS_NTT_ENCODED_SIZE..]); + } + #[hax_lib::attributes] impl MlKemKeyPairUnpacked { /// Create a new empty unpacked key pair. @@ -540,6 +650,36 @@ pub(crate) mod unpacked { Self::default() } + /// Take a serialized private key and generate an unpacked key pair from it. + #[inline(always)] + #[requires(fstar!("Spec.MLKEM.is_rank $K /\\ + v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K)"))] + pub fn from_private_key< + const SECRET_KEY_SIZE: usize, + const CPA_SECRET_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const BYTES_PER_RING_ELEMENT: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + >( + private_key: &MlKemPrivateKey, + ) -> Self { + let mut out = Self::default(); + keys_from_private_key::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + T_AS_NTT_ENCODED_SIZE, + Vector, + >(private_key, &mut out); + out + } + /// Get the serialized public key. #[inline(always)] #[requires(fstar!("Spec.MLKEM.is_rank $K /\\ @@ -563,9 +703,7 @@ pub(crate) mod unpacked { serialized: &mut MlKemPublicKey, ) { self.public_key - .serialized_public_key_mut::( - serialized, - ) + .serialized_mut::(serialized) } /// Get the serialized public key. @@ -589,7 +727,7 @@ pub(crate) mod unpacked { &self, ) -> MlKemPublicKey { self.public_key - .serialized_public_key::() + .serialized::() } /// Get the serialized public key. @@ -605,9 +743,58 @@ pub(crate) mod unpacked { } /// Get the serialized private key. - pub fn serialized_private_key(&self) -> MlKemPrivateKey { - hax_lib::fstar!("admit()"); - todo!() + #[inline(always)] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K"))] + pub fn serialized_private_key_mut< + const CPA_PRIVATE_KEY_SIZE: usize, + const PRIVATE_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const RANKED_BYTES_PER_RING_ELEMENT: usize, + >( + &self, + serialized: &mut MlKemPrivateKey, + ) { + let (ind_cpa_private_key, ind_cpa_public_key) = ind_cpa::serialize_unpacked_secret_key::< + K, + CPA_PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + RANKED_BYTES_PER_RING_ELEMENT, + Vector, + >( + &self.public_key.ind_cpa_public_key, + &self.private_key.ind_cpa_private_key, + ); + + serialize_kem_secret_key_mut::>( + &ind_cpa_private_key, + &ind_cpa_public_key, + &self.private_key.implicit_rejection_value, + &mut serialized.value, + ); + } + + /// Get the serialized private key. + #[inline(always)] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K"))] + pub fn serialized_private_key< + const CPA_PRIVATE_KEY_SIZE: usize, + const PRIVATE_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const RANKED_BYTES_PER_RING_ELEMENT: usize, + >( + &self, + ) -> MlKemPrivateKey { + let mut sk = MlKemPrivateKey::default(); + self.serialized_private_key_mut::(&mut sk); + sk } } @@ -624,6 +811,7 @@ pub(crate) mod unpacked { } } + #[hax_lib::fstar::options("--z3rlimit 200")] #[hax_lib::ensures(|result| fstar!("forall (i: nat). i < v $K ==> (forall (j: nat). j < v $K ==> @@ -666,7 +854,7 @@ pub(crate) mod unpacked { /// Generate Unpacked Keys #[inline(always)] - #[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] + #[hax_lib::fstar::options("--z3rlimit 800 --ext context_pruning")] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ @@ -788,7 +976,7 @@ pub(crate) mod unpacked { let hashed = Hasher::G(&to_hash); let (shared_secret, pseudorandomness) = hashed.split_at(SHARED_SECRET_SIZE); - let ciphertext = crate::ind_cpa::encrypt_unpacked::< + let ciphertext = ind_cpa::encrypt_unpacked::< K, CIPHERTEXT_SIZE, T_AS_NTT_ENCODED_SIZE, @@ -861,7 +1049,7 @@ pub(crate) mod unpacked { assert (v (Spec.MLKEM.v_C1_SIZE $K) == v (Spec.MLKEM.v_C1_BLOCK_SIZE $K) * v $K); assert (v (Spec.MLKEM.v_C1_BLOCK_SIZE $K) == 32 * v (Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K)); assert (v (Spec.MLKEM.v_C2_SIZE $K) == 32 * v (Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K))"); - let decrypted = crate::ind_cpa::decrypt_unpacked::< + let decrypted = ind_cpa::decrypt_unpacked::< K, CIPHERTEXT_SIZE, C1_SIZE, @@ -887,7 +1075,7 @@ pub(crate) mod unpacked { (v (Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K)) ${ciphertext}.f_value $to_hash"); let implicit_rejection_shared_secret: [u8; SHARED_SECRET_SIZE] = Hasher::PRF(&to_hash); - let expected_ciphertext = crate::ind_cpa::encrypt_unpacked::< + let expected_ciphertext = ind_cpa::encrypt_unpacked::< K, CIPHERTEXT_SIZE, T_AS_NTT_ENCODED_SIZE, diff --git a/libcrux-ml-kem/src/ind_cca/instantiations.rs b/libcrux-ml-kem/src/ind_cca/instantiations.rs index fc2e754e2..3126b25db 100644 --- a/libcrux-ml-kem/src/ind_cca/instantiations.rs +++ b/libcrux-ml-kem/src/ind_cca/instantiations.rs @@ -65,11 +65,11 @@ macro_rules! instantiate { >(randomness) } - /// Portable public key validation + /// Public key validation + #[inline(always)] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K /\\ $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CCA_PUBLIC_KEY_SIZE $K"))] - #[inline(always)] pub(crate) fn validate_public_key< const K: usize, const RANKED_BYTES_PER_RING_ELEMENT: usize, @@ -85,7 +85,7 @@ macro_rules! instantiate { >(public_key) } - /// Portable private key validation + /// Private key validation #[inline(always)] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ @@ -104,6 +104,19 @@ macro_rules! instantiate { ) } + /// Private key validation + #[inline(always)] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K"))] + pub(crate) fn validate_private_key_only< + const K: usize, + const SECRET_KEY_SIZE: usize, + >( + private_key: &MlKemPrivateKey, + ) -> bool { + crate::ind_cca::validate_private_key_only::(private_key) + } + /// Portable encapsulate #[cfg(feature = "kyber")] pub(crate) fn kyber_encapsulate< @@ -247,7 +260,6 @@ macro_rules! instantiate { $CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ - $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ @@ -313,6 +325,12 @@ macro_rules! instantiate { crate::ind_cca::unpacked::MlKemPublicKeyUnpacked; /// Get the unpacked public key. + #[hax_lib::requires( + fstar!("Spec.MLKEM.is_rank $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K") + )] + #[inline(always)] pub(crate) fn unpack_public_key< const K: usize, const T_AS_NTT_ENCODED_SIZE: usize, @@ -332,7 +350,46 @@ macro_rules! instantiate { >(public_key, unpacked_public_key) } + /// Take a serialized private key and generate an unpacked key pair from it. + #[inline(always)] + #[hax_lib::requires( + fstar!("Spec.MLKEM.is_rank $K /\\ + v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K"))] + pub(crate) fn keypair_from_private_key< + const K: usize, + const SECRET_KEY_SIZE: usize, + const CPA_SECRET_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const BYTES_PER_RING_ELEMENT: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + >( + private_key: &MlKemPrivateKey, + key_pair: &mut MlKemKeyPairUnpacked, + ) { + crate::ind_cca::unpacked::keys_from_private_key::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + T_AS_NTT_ENCODED_SIZE, + $vector, + >(private_key, key_pair); + } + /// Generate a key pair + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + $PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K"))] + #[inline(always)] pub(crate) fn generate_keypair< const K: usize, const CPA_PRIVATE_KEY_SIZE: usize, @@ -360,6 +417,20 @@ macro_rules! instantiate { } /// Unpacked encapsulate + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K"))] + #[inline(always)] pub(crate) fn encapsulate< const K: usize, const CIPHERTEXT_SIZE: usize, @@ -398,6 +469,23 @@ macro_rules! instantiate { } /// Unpacked decapsulate + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K /\\ + $IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE $K"))] + #[inline(always)] pub(crate) fn decapsulate< const K: usize, const SECRET_KEY_SIZE: usize, diff --git a/libcrux-ml-kem/src/ind_cca/instantiations/avx2.rs b/libcrux-ml-kem/src/ind_cca/instantiations/avx2.rs index afaa606be..b13ce52e4 100644 --- a/libcrux-ml-kem/src/ind_cca/instantiations/avx2.rs +++ b/libcrux-ml-kem/src/ind_cca/instantiations/avx2.rs @@ -5,7 +5,14 @@ use crate::{ #[allow(unsafe_code)] /// Portable generate key pair. -#[target_feature(enable = "avx2")] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + $PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K"))] unsafe fn generate_keypair_avx2< const K: usize, const CPA_PRIVATE_KEY_SIZE: usize, @@ -32,6 +39,13 @@ unsafe fn generate_keypair_avx2< } #[allow(unsafe_code)] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $CPA_PRIVATE_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + $PRIVATE_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K"))] pub(crate) fn generate_keypair< const K: usize, const CPA_PRIVATE_KEY_SIZE: usize, @@ -58,7 +72,7 @@ pub(crate) fn generate_keypair< #[allow(unsafe_code)] #[cfg(feature = "kyber")] -#[target_feature(enable = "avx2")] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] unsafe fn kyber_generate_keypair_avx2< const K: usize, const CPA_PRIVATE_KEY_SIZE: usize, @@ -111,7 +125,10 @@ pub(crate) fn kyber_generate_keypair< } #[allow(unsafe_code)] -#[target_feature(enable = "avx2")] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CCA_PUBLIC_KEY_SIZE $K"))] unsafe fn validate_public_key_avx2< const K: usize, const RANKED_BYTES_PER_RING_ELEMENT: usize, @@ -128,6 +145,9 @@ unsafe fn validate_public_key_avx2< } #[allow(unsafe_code)] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $RANKED_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CCA_PUBLIC_KEY_SIZE $K"))] pub(crate) fn validate_public_key< const K: usize, const RANKED_BYTES_PER_RING_ELEMENT: usize, @@ -141,7 +161,10 @@ pub(crate) fn validate_public_key< } #[allow(unsafe_code)] -#[target_feature(enable = "avx2")] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K"))] unsafe fn validate_private_key_avx2< const K: usize, const SECRET_KEY_SIZE: usize, @@ -159,6 +182,9 @@ unsafe fn validate_private_key_avx2< } #[allow(unsafe_code)] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K"))] pub(crate) fn validate_private_key< const K: usize, const SECRET_KEY_SIZE: usize, @@ -172,9 +198,23 @@ pub(crate) fn validate_private_key< } } +/// Private key validation +#[inline(always)] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K"))] +pub(crate) fn validate_private_key_only( + private_key: &MlKemPrivateKey, +) -> bool { + crate::ind_cca::validate_private_key_only::< + K, + SECRET_KEY_SIZE, + crate::hash_functions::avx2::Simd256Hash, + >(private_key) +} + #[allow(unsafe_code)] #[cfg(feature = "kyber")] -#[target_feature(enable = "avx2")] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] unsafe fn kyber_encapsulate_avx2< const K: usize, const CIPHERTEXT_SIZE: usize, @@ -253,7 +293,20 @@ pub(crate) fn kyber_encapsulate< } #[allow(unsafe_code)] -#[target_feature(enable = "avx2")] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K"))] unsafe fn encapsulate_avx2< const K: usize, const CIPHERTEXT_SIZE: usize, @@ -293,6 +346,19 @@ unsafe fn encapsulate_avx2< } #[allow(unsafe_code)] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K"))] pub(crate) fn encapsulate< const K: usize, const CIPHERTEXT_SIZE: usize, @@ -332,7 +398,7 @@ pub(crate) fn encapsulate< #[allow(unsafe_code)] #[cfg(feature = "kyber")] -#[target_feature(enable = "avx2")] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] unsafe fn kyber_decapsulate_avx2< const K: usize, const SECRET_KEY_SIZE: usize, @@ -423,7 +489,23 @@ pub fn kyber_decapsulate< } #[allow(unsafe_code)] -#[target_feature(enable = "avx2")] +#[cfg_attr(not(hax), target_feature(enable = "avx2"))] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K /\\ + $IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE $K"))] unsafe fn decapsulate_avx2< const K: usize, const SECRET_KEY_SIZE: usize, @@ -469,6 +551,22 @@ unsafe fn decapsulate_avx2< } #[allow(unsafe_code)] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE $K /\\ + $CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K /\\ + $IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE $K"))] pub fn decapsulate< const K: usize, const SECRET_KEY_SIZE: usize, @@ -522,8 +620,13 @@ pub(crate) mod unpacked { crate::ind_cca::unpacked::MlKemPublicKeyUnpacked; /// Get the unpacked public key. - #[target_feature(enable = "avx2")] + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] #[allow(unsafe_code)] + #[hax_lib::requires( + fstar!("Spec.MLKEM.is_rank $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K") + )] unsafe fn unpack_public_key_avx2< const K: usize, const T_AS_NTT_ENCODED_SIZE: usize, @@ -545,6 +648,11 @@ pub(crate) mod unpacked { /// Get the unpacked public key. #[allow(unsafe_code)] + #[hax_lib::requires( + fstar!("Spec.MLKEM.is_rank $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K") + )] pub(crate) fn unpack_public_key< const K: usize, const T_AS_NTT_ENCODED_SIZE: usize, @@ -564,8 +672,44 @@ pub(crate) mod unpacked { } } + /// Take a serialized private key and generate an unpacked key pair from it. + #[inline(always)] + #[hax_lib::requires( + fstar!("Spec.MLKEM.is_rank $K /\\ + v_SECRET_KEY_SIZE == Spec.MLKEM.v_CCA_PRIVATE_KEY_SIZE v_K /\\ + v_CPA_SECRET_KEY_SIZE == Spec.MLKEM.v_CPA_PRIVATE_KEY_SIZE v_K /\\ + v_PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE v_K /\\ + v_BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT v_K /\\ + v_T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE v_K"))] + pub(crate) fn keypair_from_private_key< + const K: usize, + const SECRET_KEY_SIZE: usize, + const CPA_SECRET_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const BYTES_PER_RING_ELEMENT: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + >( + private_key: &MlKemPrivateKey, + key_pair: &mut MlKemKeyPairUnpacked, + ) { + crate::ind_cca::unpacked::keys_from_private_key::< + K, + SECRET_KEY_SIZE, + CPA_SECRET_KEY_SIZE, + PUBLIC_KEY_SIZE, + BYTES_PER_RING_ELEMENT, + T_AS_NTT_ENCODED_SIZE, + crate::vector::SIMD256Vector, + >(private_key, key_pair); + } + #[allow(unsafe_code)] - #[target_feature(enable = "avx2")] + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K"))] unsafe fn generate_keypair_avx2< const K: usize, const CPA_PRIVATE_KEY_SIZE: usize, @@ -594,6 +738,11 @@ pub(crate) mod unpacked { /// Generate a key pair #[allow(unsafe_code)] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $BYTES_PER_RING_ELEMENT == Spec.MLKEM.v_RANKED_BYTES_PER_RING_ELEMENT $K /\\ + $PUBLIC_KEY_SIZE == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K"))] pub(crate) fn generate_keypair< const K: usize, const CPA_PRIVATE_KEY_SIZE: usize, @@ -620,7 +769,18 @@ pub(crate) mod unpacked { } #[allow(unsafe_code)] - #[target_feature(enable = "avx2")] + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K"))] unsafe fn encapsulate_avx2< const K: usize, const CIPHERTEXT_SIZE: usize, @@ -660,6 +820,17 @@ pub(crate) mod unpacked { /// Unpacked encapsulate #[allow(unsafe_code)] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $VECTOR_U_BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K"))] pub(crate) fn encapsulate< const K: usize, const CIPHERTEXT_SIZE: usize, @@ -697,8 +868,20 @@ pub(crate) mod unpacked { } } - #[target_feature(enable = "avx2")] + #[cfg_attr(not(hax), target_feature(enable = "avx2"))] #[allow(unsafe_code)] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ + $IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE $K"))] unsafe fn decapsulate_avx2< const K: usize, const SECRET_KEY_SIZE: usize, @@ -744,6 +927,18 @@ pub(crate) mod unpacked { /// Unpacked decapsulate #[allow(unsafe_code)] + #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $ETA1 == Spec.MLKEM.v_ETA1 $K /\\ + $ETA1_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ + $ETA2 == Spec.MLKEM.v_ETA2 $K /\\ + $ETA2_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA2_RANDOMNESS_SIZE $K /\\ + $C1_SIZE == Spec.MLKEM.v_C1_SIZE $K /\\ + $C2_SIZE == Spec.MLKEM.v_C2_SIZE $K /\\ + $VECTOR_U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ + $VECTOR_V_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + $C1_BLOCK_SIZE == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ + $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ + $IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.MLKEM.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE $K"))] pub(crate) fn decapsulate< const K: usize, const SECRET_KEY_SIZE: usize, diff --git a/libcrux-ml-kem/src/ind_cpa.rs b/libcrux-ml-kem/src/ind_cpa.rs index 4891caff8..6e5fcee19 100644 --- a/libcrux-ml-kem/src/ind_cpa.rs +++ b/libcrux-ml-kem/src/ind_cpa.rs @@ -15,7 +15,7 @@ use crate::{ deserialize_then_decompress_ring_element_v, deserialize_to_uncompressed_ring_element, serialize_uncompressed_ring_element, }, - utils::into_padded_array, + utils::{into_padded_array, prf_input_inc}, variant::Variant, vector::Operations, }; @@ -164,6 +164,7 @@ pub(crate) fn serialize_secret_key::ZERO()); let mut prf_inputs = [prf_input; K]; let _domain_separator_init = domain_separator; - let _prf_inputs_init = prf_inputs; - for i in 0..K { - hax_lib::loop_invariant!(|i: usize| { fstar!("v $domain_separator == v $_domain_separator_init + v $i /\\ - (v $i < v $K ==> (forall (j:nat). (j >= v $i /\\ j < v $K) ==> - ${prf_inputs}.[ sz j ] == ${_prf_inputs_init}.[ sz j ])) /\\ - (forall (j:nat). j < v $i ==> v (Seq.index (Seq.index $prf_inputs j) 32) == v $_domain_separator_init + j /\\ - Seq.slice (Seq.index $prf_inputs j) 0 32 == Seq.slice (Seq.index $_prf_inputs_init j) 0 32)") }); - prf_inputs[i][32] = domain_separator; - domain_separator += 1; - } + domain_separator = prf_input_inc::(&mut prf_inputs, domain_separator); hax_lib::fstar!("let lemma_aux (i:nat{ i < v $K }) : Lemma (${prf_inputs}.[sz i] == (Seq.append (Seq.slice $prf_input 0 32) (Seq.create 1 (mk_int #u8_inttype (v ($_domain_separator_init +! (mk_int #u8_inttype i))))))) = Lib.Sequence.eq_intro #u8 #33 ${prf_inputs}.[sz i] (Seq.append (Seq.slice $prf_input 0 32) @@ -230,7 +222,58 @@ fn sample_ring_element_cbd< /// Sample a vector of ring elements from a centered binomial distribution and /// convert them into their NTT representations. #[inline(always)] -#[hax_lib::fstar::options("--max_fuel 10 --z3rlimit 1000 --ext context_pruning --z3refresh --split_queries always")] +#[hax_lib::fstar::options("--max_fuel 15 --z3rlimit 1500 --ext context_pruning --z3refresh --split_queries always")] +#[cfg_attr(hax, hax_lib::fstar::before("let sample_vector_cbd_then_ntt_helper_2 + (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) + (#v_Vector: Type0) + (#[FStar.Tactics.Typeclasses.tcresolve ()] + i2: + Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector) + (re_as_ntt: t_Array (Libcrux_ml_kem.Polynomial.t_PolynomialRingElement v_Vector) v_K) + (prf_input: t_Array u8 (sz 33)) + (domain_separator: u8) : Lemma + (requires Spec.MLKEM.is_rank v_K /\\ v_ETA == Spec.MLKEM.v_ETA1 v_K /\\ + v_ETA_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE v_K /\\ + v domain_separator < 2 * v v_K /\\ + (let prf_outputs = Spec.MLKEM.v_PRFxN v_K v_ETA_RANDOMNESS_SIZE + (createi v_K (Spec.MLKEM.sample_vector_cbd1_prf_input #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator)))) in + forall (i: nat). i < v v_K ==> + Libcrux_ml_kem.Polynomial.to_spec_poly_t #v_Vector re_as_ntt.[ sz i ] == + Spec.MLKEM.poly_ntt (Spec.MLKEM.sample_poly_cbd v_ETA prf_outputs.[ sz i ]))) + (ensures Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector re_as_ntt == + (Spec.MLKEM.sample_vector_cbd_then_ntt #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator)))) + = + reveal_opaque (`%Spec.MLKEM.sample_vector_cbd_then_ntt) (Spec.MLKEM.sample_vector_cbd_then_ntt #v_K); + Lib.Sequence.eq_intro #(Spec.MLKEM.polynomial) #(v v_K) + (Libcrux_ml_kem.Polynomial.to_spec_vector_t #v_K #v_Vector re_as_ntt) + (Spec.MLKEM.sample_vector_cbd_then_ntt #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator)))"))] +#[cfg_attr(hax, hax_lib::fstar::before("let sample_vector_cbd_then_ntt_helper_1 + (v_K: usize) + (prf_inputs: t_Array (t_Array u8 (sz 33)) v_K) + (prf_input: t_Array u8 (sz 33)) + (domain_separator: u8) : Lemma + (requires Spec.MLKEM.is_rank v_K /\\ v domain_separator < 2 * v v_K /\\ + (forall (i: nat). i < v v_K ==> + v (Seq.index (Seq.index prf_inputs i) 32) == v domain_separator + i /\\ + Seq.slice (Seq.index prf_inputs i) 0 32 == Seq.slice prf_input 0 32)) + (ensures prf_inputs == createi v_K + (Spec.MLKEM.sample_vector_cbd1_prf_input #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator)))) + = + let lemma_aux (i: nat{i < v v_K}) : Lemma + (prf_inputs.[ sz i ] == (Seq.append (Seq.slice prf_input 0 32) (Seq.create 1 + (mk_int #u8_inttype (v (domain_separator +! (mk_int #u8_inttype i))))))) = + Lib.Sequence.eq_intro #u8 #33 prf_inputs.[ sz i ] + (Seq.append (Seq.slice prf_input 0 32) + (Seq.create 1 (mk_int #u8_inttype (v domain_separator + i)))) + in + Classical.forall_intro lemma_aux; + Lib.Sequence.eq_intro #(t_Array u8 (sz 33)) #(v v_K) prf_inputs + (createi v_K (Spec.MLKEM.sample_vector_cbd1_prf_input #v_K + (Seq.slice prf_input 0 32) (sz (v domain_separator))))"))] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $ETA_RANDOMNESS_SIZE == Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ $ETA == Spec.MLKEM.v_ETA1 $K /\\ @@ -241,7 +284,7 @@ fn sample_ring_element_cbd< Libcrux_ml_kem.Polynomial.to_spec_vector_t #$K #$:Vector ${re_as_ntt}_future == Spec.MLKEM.sample_vector_cbd_then_ntt #$K (Seq.slice $prf_input 0 32) (sz (v $domain_separator)) /\\ (forall (i: nat). i < v $K ==> - Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index ${re_as_ntt}_future i))") + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range #$:Vector (Seq.index ${re_as_ntt}_future i))") )] fn sample_vector_cbd_then_ntt< const K: usize, @@ -256,35 +299,19 @@ fn sample_vector_cbd_then_ntt< ) -> u8 { let mut prf_inputs = [prf_input; K]; let _domain_separator_init = domain_separator; - let _prf_inputs_init = prf_inputs; - for i in 0..K { - hax_lib::loop_invariant!(|i: usize| { fstar!("v $domain_separator == v $_domain_separator_init + v $i /\\ - (v $i < v $K ==> (forall (j:nat). (j >= v $i /\\ j < v $K) ==> - ${prf_inputs}.[ sz j ] == ${_prf_inputs_init}.[ sz j ])) /\\ - (forall (j:nat). j < v $i ==> v (Seq.index (Seq.index $prf_inputs j) 32) == v $_domain_separator_init + j /\\ - Seq.slice (Seq.index $prf_inputs j) 0 32 == Seq.slice (Seq.index $_prf_inputs_init j) 0 32)") }); - prf_inputs[i][32] = domain_separator; - domain_separator += 1; - } - hax_lib::fstar!("let lemma_aux (i:nat{ i < v $K }) : Lemma (${prf_inputs}.[sz i] == (Seq.append (Seq.slice $prf_input 0 32) - (Seq.create 1 (mk_int #u8_inttype (v ($_domain_separator_init +! (mk_int #u8_inttype i))))))) = - Lib.Sequence.eq_intro #u8 #33 ${prf_inputs}.[sz i] (Seq.append (Seq.slice $prf_input 0 32) - (Seq.create 1 (mk_int #u8_inttype (v $_domain_separator_init + i)))) in - - Classical.forall_intro lemma_aux; - Lib.Sequence.eq_intro #(t_Array u8 (sz 33)) #(v $K) $prf_inputs - (createi $K (Spec.MLKEM.sample_vector_cbd1_prf_input #$K (Seq.slice $prf_input 0 32) (sz (v $_domain_separator_init))))"); + domain_separator = prf_input_inc::(&mut prf_inputs, domain_separator); + hax_lib::fstar!("sample_vector_cbd_then_ntt_helper_1 $K $prf_inputs $prf_input $_domain_separator_init"); let prf_outputs: [[u8; ETA_RANDOMNESS_SIZE]; K] = Hasher::PRFxN(&prf_inputs); for i in 0..K { hax_lib::loop_invariant!(|i: usize| { fstar!("forall (j:nat). j < v $i ==> Libcrux_ml_kem.Polynomial.to_spec_poly_t #$:Vector re_as_ntt.[ sz j ] == - Spec.MLKEM.poly_ntt (Spec.MLKEM.sample_poly_cbd $ETA ${prf_outputs}.[ sz j ])") }); + Spec.MLKEM.poly_ntt (Spec.MLKEM.sample_poly_cbd $ETA ${prf_outputs}.[ sz j ]) /\\ + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range #$:Vector re_as_ntt.[ sz j ]") }); re_as_ntt[i] = sample_from_binomial_distribution::(&prf_outputs[i]); ntt_binomially_sampled_ring_element(&mut re_as_ntt[i]); } - hax_lib::fstar!("Lib.Sequence.eq_intro #(Spec.MLKEM.polynomial) #(v $K) - (Libcrux_ml_kem.Polynomial.to_spec_vector_t #$K #$:Vector re_as_ntt) - (Spec.MLKEM.sample_vector_cbd_then_ntt #$K (Seq.slice $prf_input 0 32) (sz (v $_domain_separator_init)))"); + hax_lib::fstar!("sample_vector_cbd_then_ntt_helper_2 + $K $ETA $ETA_RANDOMNESS_SIZE #$:Vector re_as_ntt $prf_input $_domain_separator_init"); domain_separator } @@ -470,6 +497,27 @@ pub(crate) fn generate_keypair< &mut public_key, ); + serialize_unpacked_secret_key::< + K, + PRIVATE_KEY_SIZE, + PUBLIC_KEY_SIZE, + RANKED_BYTES_PER_RING_ELEMENT, + Vector, + >(&public_key, &private_key) +} + +/// Serialize the secret key from the unpacked key pair generation. +#[hax_lib::fstar::verification_status(lax)] +pub(crate) fn serialize_unpacked_secret_key< + const K: usize, + const PRIVATE_KEY_SIZE: usize, + const PUBLIC_KEY_SIZE: usize, + const RANKED_BYTES_PER_RING_ELEMENT: usize, + Vector: Operations, +>( + public_key: &IndCpaPublicKeyUnpacked, + private_key: &IndCpaPrivateKeyUnpacked, +) -> ([u8; PRIVATE_KEY_SIZE], [u8; PUBLIC_KEY_SIZE]) { // pk := (Encode_12(tˆ mod^{+}q) || ρ) let public_key_serialized = serialize_public_key::( @@ -484,7 +532,7 @@ pub(crate) fn generate_keypair< } /// Call [`compress_then_serialize_ring_element_u`] on each ring element. -#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning --z3refresh")] +#[hax_lib::fstar::options("--z3rlimit 800 --ext context_pruning --z3refresh")] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $OUT_LEN == Spec.MLKEM.v_C1_SIZE $K /\\ $COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K /\\ @@ -600,7 +648,6 @@ fn compress_then_serialize_u< $BLOCK_LEN == Spec.MLKEM.v_C1_BLOCK_SIZE $K /\\ $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ length $randomness == Spec.MLKEM.v_SHARED_SECRET_SIZE"))] - #[hax_lib::ensures(|result| fstar!("$result == Spec.MLKEM.ind_cpa_encrypt_unpacked $K $message $randomness (Libcrux_ml_kem.Polynomial.to_spec_vector_t #$K #$:Vector ${public_key}.f_t_as_ntt) @@ -682,7 +729,7 @@ pub(crate) fn encrypt_unpacked< ); // c_2 := Encode_{dv}(Compress_q(v,d_v)) - compress_then_serialize_ring_element_v::( + compress_then_serialize_ring_element_v::( v, &mut ciphertext[C1_LEN..], ); @@ -693,6 +740,7 @@ pub(crate) fn encrypt_unpacked< } #[allow(non_snake_case)] +#[hax_lib::fstar::options("--z3rlimit 500 --ext context_pruning")] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $ETA1 = Spec.MLKEM.v_ETA1 $K /\\ $ETA1_RANDOMNESS_SIZE = Spec.MLKEM.v_ETA1_RANDOMNESS_SIZE $K /\\ @@ -733,8 +781,73 @@ pub(crate) fn encrypt< randomness: &[u8], ) -> [u8; CIPHERTEXT_SIZE] { hax_lib::fstar!("reveal_opaque (`%Spec.MLKEM.ind_cpa_encrypt) Spec.MLKEM.ind_cpa_encrypt"); + let unpacked_public_key = + build_unpacked_public_key::(public_key); + + // After unpacking the public key we can now call the unpacked decryption. + encrypt_unpacked::< + K, + CIPHERTEXT_SIZE, + T_AS_NTT_ENCODED_SIZE, + C1_LEN, + C2_LEN, + U_COMPRESSION_FACTOR, + V_COMPRESSION_FACTOR, + BLOCK_LEN, + ETA1, + ETA1_RANDOMNESS_SIZE, + ETA2, + ETA2_RANDOMNESS_SIZE, + Vector, + Hasher, + >(&unpacked_public_key, message, randomness) +} + +#[inline(always)] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ + length $public_key == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K"))] +#[hax_lib::ensures(|result| fstar!(" + let (t_as_ntt_bytes, seed_for_A) = split public_key $T_AS_NTT_ENCODED_SIZE in + let t_as_ntt = Spec.MLKEM.vector_decode_12 #$K t_as_ntt_bytes in + let matrix_A_as_ntt, valid = Spec.MLKEM.sample_matrix_A_ntt #$K seed_for_A in + (Libcrux_ml_kem.Polynomial.to_spec_vector_t #$K #$:Vector ${result}.f_t_as_ntt == t_as_ntt /\\ + valid ==> Libcrux_ml_kem.Polynomial.to_spec_matrix_t #$K #$:Vector ${result}.f_A == Spec.MLKEM.matrix_transpose matrix_A_as_ntt)"))] +fn build_unpacked_public_key< + const K: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + Vector: Operations, + Hasher: Hash, +>( + public_key: &[u8], +) -> IndCpaPublicKeyUnpacked { let mut unpacked_public_key = IndCpaPublicKeyUnpacked::::default(); + build_unpacked_public_key_mut::( + public_key, + &mut unpacked_public_key, + ); + unpacked_public_key +} +#[inline(always)] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $T_AS_NTT_ENCODED_SIZE == Spec.MLKEM.v_T_AS_NTT_ENCODED_SIZE $K /\\ + length $public_key == Spec.MLKEM.v_CPA_PUBLIC_KEY_SIZE $K"))] +#[hax_lib::ensures(|_| fstar!(" + let (t_as_ntt_bytes, seed_for_A) = split public_key $T_AS_NTT_ENCODED_SIZE in + let t_as_ntt = Spec.MLKEM.vector_decode_12 #$K t_as_ntt_bytes in + let matrix_A_as_ntt, valid = Spec.MLKEM.sample_matrix_A_ntt #$K seed_for_A in + (Libcrux_ml_kem.Polynomial.to_spec_vector_t #$K #$:Vector ${unpacked_public_key}_future.f_t_as_ntt == t_as_ntt /\\ + valid ==> Libcrux_ml_kem.Polynomial.to_spec_matrix_t #$K #$:Vector ${unpacked_public_key}_future.f_A == Spec.MLKEM.matrix_transpose matrix_A_as_ntt)"))] +pub(crate) fn build_unpacked_public_key_mut< + const K: usize, + const T_AS_NTT_ENCODED_SIZE: usize, + Vector: Operations, + Hasher: Hash, +>( + public_key: &[u8], + unpacked_public_key: &mut IndCpaPublicKeyUnpacked, +) { // tˆ := Decode_12(pk) deserialize_ring_elements_reduced::( &public_key[..T_AS_NTT_ENCODED_SIZE], @@ -748,37 +861,19 @@ pub(crate) fn encrypt< // end for // end for let seed = &public_key[T_AS_NTT_ENCODED_SIZE..]; - hax_lib::fstar!("Lib.Sequence.eq_intro #u8 #32 $seed (Seq.slice - (Libcrux_ml_kem.Utils.into_padded_array (Rust_primitives.mk_usize 34) $seed) 0 32)"); + hax_lib::fstar!("Lib.Sequence.eq_intro #u8 #32 $seed + (Seq.slice (Libcrux_ml_kem.Utils.into_padded_array (sz 34) $seed) 0 32)"); sample_matrix_A::( &mut unpacked_public_key.A, into_padded_array(seed), false, ); - - // After unpacking the public key we can now call the unpacked decryption. - encrypt_unpacked::< - K, - CIPHERTEXT_SIZE, - T_AS_NTT_ENCODED_SIZE, - C1_LEN, - C2_LEN, - U_COMPRESSION_FACTOR, - V_COMPRESSION_FACTOR, - BLOCK_LEN, - ETA1, - ETA1_RANDOMNESS_SIZE, - ETA2, - ETA2_RANDOMNESS_SIZE, - Vector, - Hasher, - >(&unpacked_public_key, message, randomness) } /// Call [`deserialize_then_decompress_ring_element_u`] on each ring element /// in the `ciphertext`. #[inline(always)] -#[hax_lib::fstar::options("--ext context_pruning")] +#[hax_lib::fstar::options("--z3rlimit 800 --ext context_pruning")] #[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ $CIPHERTEXT_SIZE == Spec.MLKEM.v_CPA_CIPHERTEXT_SIZE $K /\\ $U_COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_U_COMPRESSION_FACTOR $K"))] @@ -795,7 +890,7 @@ fn deserialize_then_decompress_u< ciphertext: &[u8; CIPHERTEXT_SIZE], ) -> [PolynomialRingElement; K] { hax_lib::fstar!("assert (v (($COEFFICIENTS_IN_RING_ELEMENT *! $U_COMPRESSION_FACTOR ) /! - Rust_primitives.mk_usize 8) == v (Spec.MLKEM.v_C1_BLOCK_SIZE $K))"); + sz 8) == v (Spec.MLKEM.v_C1_BLOCK_SIZE $K))"); let mut u_as_ntt = from_fn(|_| PolynomialRingElement::::ZERO()); cloop! { for (i, u_bytes) in ciphertext @@ -829,7 +924,7 @@ fn deserialize_then_decompress_u< fstar!("Libcrux_ml_kem.Polynomial.to_spec_vector_t #$K #$:Vector $res == Spec.MLKEM.vector_decode_12 #$K $secret_key") )] -fn deserialize_secret_key( +pub(crate) fn deserialize_secret_key( secret_key: &[u8], ) -> [PolynomialRingElement; K] { hax_lib::fstar!("assert_norm (Spec.MLKEM.polynomial_d 12 == Spec.MLKEM.polynomial)"); @@ -902,7 +997,7 @@ pub(crate) fn decrypt_unpacked< ); // v := Decompress_q(Decode_{d_v}(c + d_u·k·n / 8), d_v) - let v = deserialize_then_decompress_ring_element_v::( + let v = deserialize_then_decompress_ring_element_v::( &ciphertext[VECTOR_U_ENCODED_SIZE..], ); diff --git a/libcrux-ml-kem/src/invert_ntt.rs b/libcrux-ml-kem/src/invert_ntt.rs index 49fa7fea5..2770d0988 100644 --- a/libcrux-ml-kem/src/invert_ntt.rs +++ b/libcrux-ml-kem/src/invert_ntt.rs @@ -5,6 +5,7 @@ use crate::{ }; #[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] #[hax_lib::fstar::before(interface, "[@@ \"opaque_to_smt\"] let invert_ntt_re_range_2 (#v_Vector: Type0) {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} @@ -60,6 +61,7 @@ pub(crate) fn invert_ntt_at_layer_1( } #[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] #[hax_lib::requires(fstar!("v ${*zeta_i} == 64 /\\ invert_ntt_re_range_2 $re "))] #[hax_lib::ensures(|result| fstar!("invert_ntt_re_range_2 ${re}_future /\\ @@ -100,6 +102,7 @@ pub(crate) fn invert_ntt_at_layer_2( } #[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] #[hax_lib::requires(fstar!("v ${*zeta_i} == 32 /\\ invert_ntt_re_range_2 $re"))] #[hax_lib::ensures(|result| fstar!("invert_ntt_re_range_2 ${re}_future /\\ diff --git a/libcrux-ml-kem/src/mlkem1024.rs b/libcrux-ml-kem/src/mlkem1024.rs index 6bc86a8cf..52f2b8d21 100644 --- a/libcrux-ml-kem/src/mlkem1024.rs +++ b/libcrux-ml-kem/src/mlkem1024.rs @@ -79,6 +79,18 @@ macro_rules! instantiate { } + /// Validate the private key only. + /// + /// Returns `true` if valid, and `false` otherwise. + pub fn validate_private_key_only( + private_key: &MlKem1024PrivateKey, + ) -> bool { + p::validate_private_key_only::< + RANK_1024, + SECRET_KEY_SIZE_1024, + >(private_key) + } + /// Generate Kyber 1024 Key Pair #[cfg(feature = "kyber")] #[cfg_attr(docsrs, doc(cfg(feature = "kyber")))] @@ -251,14 +263,48 @@ macro_rules! instantiate { } /// Get the serialized public key. + #[hax_lib::requires(fstar!("forall (i:nat). i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${public_key}.f_ind_cpa_public_key.f_t_as_ntt i)"))] pub fn serialized_public_key( public_key: &MlKem1024PublicKeyUnpacked, serialized: &mut MlKem1024PublicKey, ) { - public_key.serialized_public_key_mut::< - RANKED_BYTES_PER_RING_ELEMENT_1024, - CPA_PKE_PUBLIC_KEY_SIZE_1024, - >(serialized); + public_key.serialized_mut::< + RANKED_BYTES_PER_RING_ELEMENT_1024, + CPA_PKE_PUBLIC_KEY_SIZE_1024, + >(serialized); + } + + /// Get the serialized private key. + pub fn key_pair_serialized_private_key(key_pair: &MlKem1024KeyPairUnpacked) -> MlKem1024PrivateKey { + key_pair.serialized_private_key::() + } + + /// Get the serialized private key. + pub fn key_pair_serialized_private_key_mut(key_pair: &MlKem1024KeyPairUnpacked, serialized : &mut MlKem1024PrivateKey) { + key_pair.serialized_private_key_mut::(serialized); + } + + /// Get the serialized public key. + #[hax_lib::requires(fstar!("forall (i:nat). i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${key_pair}.f_public_key.f_ind_cpa_public_key.f_t_as_ntt i)"))] + pub fn key_pair_serialized_public_key_mut(key_pair: &MlKem1024KeyPairUnpacked, serialized: &mut MlKem1024PublicKey) { + key_pair.serialized_public_key_mut::(serialized); + } + + /// Get the serialized public key. + #[hax_lib::requires(fstar!("forall (i:nat). i < 4 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${key_pair}.f_public_key.f_ind_cpa_public_key.f_t_as_ntt i)"))] + pub fn key_pair_serialized_public_key(key_pair: &MlKem1024KeyPairUnpacked) ->MlKem1024PublicKey { + key_pair.serialized_public_key::() + } + + /// Get an unpacked key from a private key. + pub fn key_pair_from_private_mut(private_key: &MlKem1024PrivateKey, key_pair: &mut MlKem1024KeyPairUnpacked) { + p::unpacked::keypair_from_private_key::(private_key, key_pair); } /// Get the unpacked public key. @@ -275,8 +321,17 @@ macro_rules! instantiate { } - /// Generate ML-KEM 1024 Key Pair in "unpacked" form + /// Generate ML-KEM 1024 Key Pair in "unpacked" form. pub fn generate_key_pair( + randomness: [u8; KEY_GENERATION_SEED_SIZE] + ) -> MlKem1024KeyPairUnpacked { + let mut key_pair = MlKem1024KeyPairUnpacked::default(); + generate_key_pair_mut(randomness, &mut key_pair); + key_pair + } + + /// Generate ML-KEM 1024 Key Pair in "unpacked" form + pub fn generate_key_pair_mut( randomness: [u8; KEY_GENERATION_SEED_SIZE], key_pair: &mut MlKem1024KeyPairUnpacked, ) { diff --git a/libcrux-ml-kem/src/mlkem512.rs b/libcrux-ml-kem/src/mlkem512.rs index cad3bd02b..0d82a07a8 100644 --- a/libcrux-ml-kem/src/mlkem512.rs +++ b/libcrux-ml-kem/src/mlkem512.rs @@ -74,6 +74,18 @@ macro_rules! instantiate { } + /// Validate the private key only. + /// + /// Returns `true` if valid, and `false` otherwise. + pub fn validate_private_key_only( + private_key: &MlKem512PrivateKey, + ) -> bool { + p::validate_private_key_only::< + RANK_512, + SECRET_KEY_SIZE_512, + >(private_key) + } + /// Generate ML-KEM 512 Key Pair pub fn generate_key_pair( randomness: [u8; KEY_GENERATION_SEED_SIZE], @@ -243,14 +255,48 @@ macro_rules! instantiate { } /// Get the serialized public key. + #[hax_lib::requires(fstar!("forall (i:nat). i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${public_key}.f_ind_cpa_public_key.f_t_as_ntt i)"))] pub fn serialized_public_key( public_key: &MlKem512PublicKeyUnpacked, serialized: &mut MlKem512PublicKey, ) { - public_key.serialized_public_key_mut::< - RANKED_BYTES_PER_RING_ELEMENT_512, - CPA_PKE_PUBLIC_KEY_SIZE_512 - >(serialized) + public_key.serialized_mut::< + RANKED_BYTES_PER_RING_ELEMENT_512, + CPA_PKE_PUBLIC_KEY_SIZE_512 + >(serialized) + } + + /// Get the serialized private key. + pub fn key_pair_serialized_private_key(key_pair: &MlKem512KeyPairUnpacked) -> MlKem512PrivateKey { + key_pair.serialized_private_key::() + } + + /// Get the serialized private key. + pub fn key_pair_serialized_private_key_mut(key_pair: &MlKem512KeyPairUnpacked, serialized : &mut MlKem512PrivateKey) { + key_pair.serialized_private_key_mut::(serialized); + } + + /// Get the serialized public key. + #[hax_lib::requires(fstar!("forall (i:nat). i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${key_pair}.f_public_key.f_ind_cpa_public_key.f_t_as_ntt i)"))] + pub fn key_pair_serialized_public_key_mut(key_pair: &MlKem512KeyPairUnpacked, serialized: &mut MlKem512PublicKey) { + key_pair.serialized_public_key_mut::(serialized); + } + + /// Get the serialized public key. + #[hax_lib::requires(fstar!("forall (i:nat). i < 2 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${key_pair}.f_public_key.f_ind_cpa_public_key.f_t_as_ntt i)"))] + pub fn key_pair_serialized_public_key(key_pair: &MlKem512KeyPairUnpacked) ->MlKem512PublicKey { + key_pair.serialized_public_key::() + } + + /// Get an unpacked key from a private key. + pub fn key_pair_from_private_mut(private_key: &MlKem512PrivateKey, key_pair: &mut MlKem512KeyPairUnpacked) { + p::unpacked::keypair_from_private_key::(private_key, key_pair); } /// Get the unpacked public key. @@ -266,8 +312,17 @@ macro_rules! instantiate { >(public_key, unpacked_public_key) } - /// Generate ML-KEM 512 Key Pair in "unpacked" form + /// Generate ML-KEM 512 Key Pair in "unpacked" form. pub fn generate_key_pair( + randomness: [u8; KEY_GENERATION_SEED_SIZE] + ) -> MlKem512KeyPairUnpacked { + let mut key_pair = MlKem512KeyPairUnpacked::default(); + generate_key_pair_mut(randomness, &mut key_pair); + key_pair + } + + /// Generate ML-KEM 512 Key Pair in "unpacked" form + pub fn generate_key_pair_mut( randomness: [u8; KEY_GENERATION_SEED_SIZE], key_pair: &mut MlKem512KeyPairUnpacked, ) { diff --git a/libcrux-ml-kem/src/mlkem768.rs b/libcrux-ml-kem/src/mlkem768.rs index 17cf7aadf..7a684b2a4 100644 --- a/libcrux-ml-kem/src/mlkem768.rs +++ b/libcrux-ml-kem/src/mlkem768.rs @@ -77,6 +77,18 @@ macro_rules! instantiate { >(private_key, ciphertext) } + /// Validate the private key only. + /// + /// Returns `true` if valid, and `false` otherwise. + pub fn validate_private_key_only( + private_key: &MlKem768PrivateKey, + ) -> bool { + p::validate_private_key_only::< + RANK_768, + SECRET_KEY_SIZE_768, + >(private_key) + } + /// Generate ML-KEM 768 Key Pair pub fn generate_key_pair( randomness: [u8; KEY_GENERATION_SEED_SIZE], @@ -242,15 +254,44 @@ macro_rules! instantiate { } /// Get the serialized public key. + #[hax_lib::requires(fstar!("forall (i:nat). i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${public_key}.f_ind_cpa_public_key.f_t_as_ntt i)"))] pub fn serialized_public_key(public_key: &MlKem768PublicKeyUnpacked, serialized : &mut MlKem768PublicKey) { - public_key.serialized_public_key_mut::(serialized); + public_key.serialized_mut::(serialized); + } + + /// Get the serialized private key. + pub fn key_pair_serialized_private_key(key_pair: &MlKem768KeyPairUnpacked) -> MlKem768PrivateKey { + key_pair.serialized_private_key::() + } + + /// Get the serialized private key. + pub fn key_pair_serialized_private_key_mut(key_pair: &MlKem768KeyPairUnpacked, serialized: &mut MlKem768PrivateKey) { + key_pair.serialized_private_key_mut::(serialized); } /// Get the serialized public key. - pub fn key_pair_serialized_public_key(key_pair: &MlKem768KeyPairUnpacked, serialized : &mut MlKem768PublicKey) { + #[hax_lib::requires(fstar!("(forall (i:nat). i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${key_pair}.f_public_key.f_ind_cpa_public_key.f_t_as_ntt i))"))] + pub fn key_pair_serialized_public_key_mut(key_pair: &MlKem768KeyPairUnpacked, serialized: &mut MlKem768PublicKey) { key_pair.serialized_public_key_mut::(serialized); } + /// Get the serialized public key. + #[hax_lib::requires(fstar!("forall (i:nat). i < 3 ==> + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range (Seq.index + ${key_pair}.f_public_key.f_ind_cpa_public_key.f_t_as_ntt i)"))] + pub fn key_pair_serialized_public_key(key_pair: &MlKem768KeyPairUnpacked) ->MlKem768PublicKey { + key_pair.serialized_public_key::() + } + + /// Get an unpacked key from a private key. + pub fn key_pair_from_private_mut(private_key: &MlKem768PrivateKey, key_pair: &mut MlKem768KeyPairUnpacked) { + p::unpacked::keypair_from_private_key::(private_key, key_pair); + } + /// Get the unpacked public key. pub fn public_key(key_pair: &MlKem768KeyPairUnpacked, pk: &mut MlKem768PublicKeyUnpacked) { *pk = (*key_pair.public_key()).clone(); @@ -271,6 +312,15 @@ macro_rules! instantiate { /// Generate ML-KEM 768 Key Pair in "unpacked" form. pub fn generate_key_pair( + randomness: [u8; KEY_GENERATION_SEED_SIZE] + ) -> MlKem768KeyPairUnpacked { + let mut key_pair = MlKem768KeyPairUnpacked::default(); + generate_key_pair_mut(randomness, &mut key_pair); + key_pair + } + + /// Generate ML-KEM 768 Key Pair in "unpacked" form. + pub fn generate_key_pair_mut( randomness: [u8; KEY_GENERATION_SEED_SIZE], key_pair: &mut MlKem768KeyPairUnpacked, ) { diff --git a/libcrux-ml-kem/src/ntt.rs b/libcrux-ml-kem/src/ntt.rs index 9008f7190..69eb1656f 100644 --- a/libcrux-ml-kem/src/ntt.rs +++ b/libcrux-ml-kem/src/ntt.rs @@ -5,6 +5,7 @@ use crate::{ }; #[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] #[hax_lib::fstar::before(interface, "[@@ \"opaque_to_smt\"] let ntt_re_range_2 (#v_Vector: Type0) {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} @@ -61,6 +62,7 @@ pub(crate) fn ntt_at_layer_1( } #[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] #[hax_lib::fstar::before(interface, "[@@ \"opaque_to_smt\"] let ntt_re_range_3 (#v_Vector: Type0) {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} @@ -109,6 +111,7 @@ pub(crate) fn ntt_at_layer_2( } #[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] #[hax_lib::fstar::before(interface, "[@@ \"opaque_to_smt\"] let ntt_re_range_4 (#v_Vector: Type0) {| i1: Libcrux_ml_kem.Vector.Traits.t_Operations v_Vector |} @@ -261,7 +264,8 @@ pub(crate) fn ntt_at_layer_7(re: &mut PolynomialRingElement< #[hax_lib::requires(fstar!("forall i. i < 8 ==> ntt_layer_7_pre (${re}.f_coefficients.[ sz i ]) (${re}.f_coefficients.[ sz i +! sz 8 ])"))] #[hax_lib::ensures(|_| fstar!("Libcrux_ml_kem.Polynomial.to_spec_poly_t #$:Vector ${re}_future == - Spec.MLKEM.poly_ntt (Libcrux_ml_kem.Polynomial.to_spec_poly_t #$:Vector $re)"))] + Spec.MLKEM.poly_ntt (Libcrux_ml_kem.Polynomial.to_spec_poly_t #$:Vector $re) /\\ + Libcrux_ml_kem.Serialize.coefficients_field_modulus_range #$:Vector ${re}_future"))] pub(crate) fn ntt_binomially_sampled_ring_element( re: &mut PolynomialRingElement, ) { diff --git a/libcrux-ml-kem/src/polynomial.rs b/libcrux-ml-kem/src/polynomial.rs index e2aa447a2..d62225b59 100644 --- a/libcrux-ml-kem/src/polynomial.rs +++ b/libcrux-ml-kem/src/polynomial.rs @@ -1,6 +1,6 @@ use crate::vector::{to_standard_domain, Operations, FIELD_ELEMENTS_IN_VECTOR}; -const ZETAS_TIMES_MONTGOMERY_R: [i16; 128] = { +pub(crate) const ZETAS_TIMES_MONTGOMERY_R: [i16; 128] = { hax_lib::fstar!("assert_norm (pow2 16 == 65536)"); [ -1044, -758, -359, -1517, 1493, 1422, 287, 202, -171, 622, 1577, 182, 962, -1202, -1474, 1468, 573, -1325, 264, 383, -829, 1458, -1602, -130, -681, 1017, 732, 608, -1542, 411, -205, -1571, diff --git a/libcrux-ml-kem/src/serialize.rs b/libcrux-ml-kem/src/serialize.rs index 18f8444b7..f6b196aa7 100644 --- a/libcrux-ml-kem/src/serialize.rs +++ b/libcrux-ml-kem/src/serialize.rs @@ -325,14 +325,17 @@ fn compress_then_serialize_5( #[inline(always)] #[hax_lib::fstar::verification_status(panic_free)] -#[hax_lib::requires(fstar!("(v $COMPRESSION_FACTOR == 4 \\/ v $COMPRESSION_FACTOR == 5) /\\ v $OUT_LEN == 32 * v $COMPRESSION_FACTOR /\\ - Seq.length $out == v $OUT_LEN /\\ coefficients_field_modulus_range $re"))] +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank v_K /\\ + $COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR v_K /\\ + Seq.length $out == v $OUT_LEN /\\ v $OUT_LEN == 32 * v $COMPRESSION_FACTOR /\\ + coefficients_field_modulus_range $re"))] #[hax_lib::ensures(|_| fstar!("${out_future.len()} == ${out.len()} /\\ - ${out}_future == Spec.MLKEM.compress_then_encode_v $COMPRESSION_FACTOR + ${out}_future == Spec.MLKEM.compress_then_encode_v #v_K (Libcrux_ml_kem.Polynomial.to_spec_poly_t #$:Vector $re)") )] pub(super) fn compress_then_serialize_ring_element_v< + const K: usize, const COMPRESSION_FACTOR: usize, const OUT_LEN: usize, Vector: Operations, @@ -372,6 +375,7 @@ fn deserialize_then_decompress_10( } #[inline(always)] +#[hax_lib::fstar::verification_status(lax)] #[hax_lib::requires( serialized.len() == 352 )] @@ -437,6 +441,7 @@ fn deserialize_then_decompress_4( } #[inline(always)] +#[hax_lib::fstar::verification_status(lax)] #[hax_lib::requires( serialized.len() == 160 )] @@ -457,15 +462,16 @@ fn deserialize_then_decompress_5( #[inline(always)] #[hax_lib::fstar::verification_status(panic_free)] -#[hax_lib::requires( - (COMPRESSION_FACTOR == 4 || COMPRESSION_FACTOR == 5) && - serialized.len() == 32 * COMPRESSION_FACTOR +#[hax_lib::requires(fstar!("Spec.MLKEM.is_rank $K /\\ + $COMPRESSION_FACTOR == Spec.MLKEM.v_VECTOR_V_COMPRESSION_FACTOR $K /\\ + Seq.length $serialized == 32 * v $COMPRESSION_FACTOR") )] #[hax_lib::ensures(|result| fstar!("Libcrux_ml_kem.Polynomial.to_spec_poly_t #$:Vector $result == - Spec.MLKEM.decode_then_decompress_v $COMPRESSION_FACTOR $serialized") + Spec.MLKEM.decode_then_decompress_v #${K} $serialized") )] pub(super) fn deserialize_then_decompress_ring_element_v< + const K: usize, const COMPRESSION_FACTOR: usize, Vector: Operations, >( diff --git a/libcrux-ml-kem/src/types.rs b/libcrux-ml-kem/src/types.rs index b1ff9dc03..f1a11eb52 100644 --- a/libcrux-ml-kem/src/types.rs +++ b/libcrux-ml-kem/src/types.rs @@ -11,13 +11,17 @@ macro_rules! impl_generic_struct { } } + #[hax_lib::attributes] impl AsRef<[u8]> for $name { + #[ensures(|result| fstar!("$result = self___.f_value"))] fn as_ref(&self) -> &[u8] { &self.value } } + #[hax_lib::attributes] impl From<[u8; SIZE]> for $name { + #[ensures(|result| fstar!("${result}.f_value = $value"))] fn from(value: [u8; SIZE]) -> Self { Self { value } } @@ -199,3 +203,41 @@ impl (self.sk, self.pk) } } + +/// Unpack an incoming private key into it's different parts. +/// +/// We have this here in types to extract into a common core for C. +#[hax_lib::requires(fstar!("Seq.length private_key >= + v v_CPA_SECRET_KEY_SIZE + v v_PUBLIC_KEY_SIZE + + v Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE"))] +#[hax_lib::ensures(|result| fstar!(" + let (ind_cpa_secret_key_s,rest) = split $private_key $CPA_SECRET_KEY_SIZE in + let (ind_cpa_public_key_s,rest) = split rest $PUBLIC_KEY_SIZE in + let (ind_cpa_public_key_hash_s,implicit_rejection_value_s) = split rest Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE in + let (ind_cpa_secret_key,ind_cpa_public_key,ind_cpa_public_key_hash,implicit_rejection_value) + = result in + ind_cpa_secret_key_s == ind_cpa_secret_key /\\ + ind_cpa_public_key_s == ind_cpa_public_key /\\ + ind_cpa_public_key_hash_s == ind_cpa_public_key_hash /\\ + implicit_rejection_value_s == implicit_rejection_value /\\ + Seq.length ind_cpa_secret_key == v v_CPA_SECRET_KEY_SIZE /\\ + Seq.length ind_cpa_public_key == v v_PUBLIC_KEY_SIZE /\\ + Seq.length ind_cpa_public_key_hash == v Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE /\\ + Seq.length implicit_rejection_value == + Seq.length private_key - + (v v_CPA_SECRET_KEY_SIZE + v v_PUBLIC_KEY_SIZE + v Libcrux_ml_kem.Constants.v_H_DIGEST_SIZE) + "))] +pub(crate) fn unpack_private_key( + private_key: &[u8], // len: SECRET_KEY_SIZE +) -> (&[u8], &[u8], &[u8], &[u8]) { + let (ind_cpa_secret_key, secret_key) = private_key.split_at(CPA_SECRET_KEY_SIZE); + let (ind_cpa_public_key, secret_key) = secret_key.split_at(PUBLIC_KEY_SIZE); + let (ind_cpa_public_key_hash, implicit_rejection_value) = + secret_key.split_at(crate::constants::H_DIGEST_SIZE); + ( + ind_cpa_secret_key, + ind_cpa_public_key, + ind_cpa_public_key_hash, + implicit_rejection_value, + ) +} diff --git a/libcrux-ml-kem/src/utils.rs b/libcrux-ml-kem/src/utils.rs index 62590aa13..3193ba19d 100644 --- a/libcrux-ml-kem/src/utils.rs +++ b/libcrux-ml-kem/src/utils.rs @@ -21,6 +21,35 @@ pub(crate) fn into_padded_array(slice: &[u8]) -> [u8; LEN] { out } +#[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 200")] +#[hax_lib::requires(fstar!("range (v $domain_separator + v $K) u8_inttype"))] +#[hax_lib::ensures(|ds| + fstar!("v $ds == v $domain_separator + v $K /\\ + (forall (i:nat). i < v $K ==> + v (Seq.index (Seq.index ${prf_inputs}_future i) 32) == v $domain_separator + i /\\ + Seq.slice (Seq.index ${prf_inputs}_future i) 0 32 == Seq.slice (Seq.index $prf_inputs i) 0 32)") +)] +pub(crate) fn prf_input_inc< + const K: usize, +>( + prf_inputs: &mut [[u8; 33]; K], + mut domain_separator: u8, +) -> u8 { + let _domain_separator_init = domain_separator; + let _prf_inputs_init = prf_inputs.clone(); + for i in 0..K { + hax_lib::loop_invariant!(|i: usize| { fstar!("v $domain_separator == v $_domain_separator_init + v $i /\\ + (v $i < v $K ==> (forall (j:nat). (j >= v $i /\\ j < v $K) ==> + prf_inputs.[ sz j ] == ${_prf_inputs_init}.[ sz j ])) /\\ + (forall (j:nat). j < v $i ==> v (Seq.index (Seq.index prf_inputs j) 32) == v $_domain_separator_init + j /\\ + Seq.slice (Seq.index prf_inputs j) 0 32 == Seq.slice (Seq.index $_prf_inputs_init j) 0 32)") }); + prf_inputs[i][32] = domain_separator; + domain_separator += 1; + } + domain_separator +} + // C extraction: // // This is only enabled when extracting. diff --git a/libcrux-ml-kem/src/vector/avx2.rs b/libcrux-ml-kem/src/vector/avx2.rs index 2d6d18798..9f3035fde 100644 --- a/libcrux-ml-kem/src/vector/avx2.rs +++ b/libcrux-ml-kem/src/vector/avx2.rs @@ -181,8 +181,12 @@ impl Operations for SIMD256Vector { } } - #[requires(COEFFICIENT_BITS == 4 || COEFFICIENT_BITS == 5 || - COEFFICIENT_BITS == 10 || COEFFICIENT_BITS == 11)] + #[requires(fstar!("(v $COEFFICIENT_BITS == 4 \\/ + v $COEFFICIENT_BITS == 5 \\/ + v $COEFFICIENT_BITS == 10 \\/ + v $COEFFICIENT_BITS == 11) /\\ + (forall (i:nat). i < 16 ==> v (Seq.index (impl.f_repr $vector) i) >= 0 /\\ + v (Seq.index (impl.f_repr $vector) i) < pow2 (v $COEFFICIENT_BITS))"))] #[inline(always)] fn decompress_ciphertext_coefficient(vector: Self) -> Self { Self { diff --git a/libcrux-ml-kem/src/vector/portable.rs b/libcrux-ml-kem/src/vector/portable.rs index b8e46b460..7d0752f97 100644 --- a/libcrux-ml-kem/src/vector/portable.rs +++ b/libcrux-ml-kem/src/vector/portable.rs @@ -102,8 +102,8 @@ fn deserialize_12(a: &[u8]) -> PortableVector { serialize::deserialize_12(a) } -#[hax_lib::fstar::before(interface, r#"#push-options "--z3rlimit 400 --split_queries always""#)] -#[hax_lib::fstar::after(interface, r#"#pop-options"#)] +#[hax_lib::fstar::before(r#"#push-options "--z3rlimit 400 --split_queries always""#)] +#[hax_lib::fstar::after(r#"#pop-options"#)] #[hax_lib::attributes] impl Operations for PortableVector { #[ensures(|out| fstar!("impl.f_repr out == Seq.create 16 0s"))] @@ -198,10 +198,14 @@ impl Operations for PortableVector { compress::(a) } - #[requires(COEFFICIENT_BITS == 4 || COEFFICIENT_BITS == 5 || - COEFFICIENT_BITS == 10 || COEFFICIENT_BITS == 11)] - fn decompress_ciphertext_coefficient(v: Self) -> Self { - decompress_ciphertext_coefficient::(v) + #[requires(fstar!("(v $COEFFICIENT_BITS == 4 \\/ + v $COEFFICIENT_BITS == 5 \\/ + v $COEFFICIENT_BITS == 10 \\/ + v $COEFFICIENT_BITS == 11) /\\ + (forall (i:nat). i < 16 ==> v (Seq.index (impl.f_repr $a) i) >= 0 /\\ + v (Seq.index (impl.f_repr $a) i) < pow2 (v $COEFFICIENT_BITS))"))] + fn decompress_ciphertext_coefficient(a: Self) -> Self { + decompress_ciphertext_coefficient::(a) } #[requires(fstar!("Spec.Utils.is_i16b 1664 zeta0 /\\ Spec.Utils.is_i16b 1664 zeta1 /\\ diff --git a/libcrux-ml-kem/src/vector/portable/arithmetic.rs b/libcrux-ml-kem/src/vector/portable/arithmetic.rs index 54a7b150f..320e51a09 100644 --- a/libcrux-ml-kem/src/vector/portable/arithmetic.rs +++ b/libcrux-ml-kem/src/vector/portable/arithmetic.rs @@ -135,6 +135,7 @@ pub fn shift_right(mut vec: PortableVector) -> PortableVect /// Note: This function is not secret independent /// Only use with public values. #[inline(always)] +#[hax_lib::fstar::options("--z3rlimit 300")] #[hax_lib::requires(fstar!("Spec.Utils.is_i16b_array (pow2 12 - 1) ${vec}.f_elements"))] #[hax_lib::ensures(|result| fstar!("${result}.f_elements == Spec.Utils.map_array (fun x -> if x >=. 3329s then x -! 3329s else x) (${vec}.f_elements)"))] diff --git a/libcrux-ml-kem/src/vector/portable/compress.rs b/libcrux-ml-kem/src/vector/portable/compress.rs index ae3be0ab3..ef533f712 100644 --- a/libcrux-ml-kem/src/vector/portable/compress.rs +++ b/libcrux-ml-kem/src/vector/portable/compress.rs @@ -23,6 +23,7 @@ use crate::vector::FIELD_MODULUS; /// /// The NIST FIPS 203 standard can be found at /// . +#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] #[cfg_attr(hax, hax_lib::requires(fe < (FIELD_MODULUS as u16)))] #[cfg_attr(hax, hax_lib::ensures(|result| hax_lib::implies(833 <= fe && fe <= 2496, || result == 1) && @@ -78,6 +79,7 @@ pub(crate) fn compress_message_coefficient(fe: u16) -> u8 { res } +#[hax_lib::fstar::options("--z3rlimit 200 --ext context_pruning")] #[cfg_attr(hax, hax_lib::requires( (coefficient_bits == 4 || diff --git a/libcrux-ml-kem/src/vector/traits.rs b/libcrux-ml-kem/src/vector/traits.rs index 208e58b51..50062b0f0 100644 --- a/libcrux-ml-kem/src/vector/traits.rs +++ b/libcrux-ml-kem/src/vector/traits.rs @@ -88,9 +88,13 @@ pub trait Operations: Copy + Clone + Repr { v $COEFFICIENT_BITS == 11) ==> (forall (i:nat). i < 16 ==> bounded (Seq.index (f_repr $result) i) (v $COEFFICIENT_BITS))"))] fn compress(a: Self) -> Self; - #[requires(COEFFICIENT_BITS == 4 || COEFFICIENT_BITS == 5 || - COEFFICIENT_BITS == 10 || COEFFICIENT_BITS == 11)] - fn decompress_ciphertext_coefficient(v: Self) -> Self; + #[requires(fstar!("(v $COEFFICIENT_BITS == 4 \\/ + v $COEFFICIENT_BITS == 5 \\/ + v $COEFFICIENT_BITS == 10 \\/ + v $COEFFICIENT_BITS == 11) /\\ + (forall (i:nat). i < 16 ==> v (Seq.index (f_repr $a) i) >= 0 /\\ + v (Seq.index (f_repr $a) i) < pow2 (v $COEFFICIENT_BITS))"))] + fn decompress_ciphertext_coefficient(a: Self) -> Self; // NTT #[requires(fstar!("Spec.Utils.is_i16b 1664 zeta0 /\\ Spec.Utils.is_i16b 1664 zeta1 /\\ @@ -189,7 +193,7 @@ pub trait Operations: Copy + Clone { fn montgomery_multiply_by_constant(v: Self, c: i16) -> Self; fn compress_1(v: Self) -> Self; fn compress(v: Self) -> Self; - fn decompress_ciphertext_coefficient(v: Self) -> Self; + fn decompress_ciphertext_coefficient(a: Self) -> Self; fn ntt_layer_1_step(a: Self, zeta0: i16, zeta1: i16, zeta2: i16, zeta3: i16) -> Self; fn ntt_layer_2_step(a: Self, zeta0: i16, zeta1: i16) -> Self; fn ntt_layer_3_step(a: Self, zeta: i16) -> Self; diff --git a/libcrux-ml-kem/tests/nistkats.rs b/libcrux-ml-kem/tests/nistkats.rs index 76abc4316..c597b2bac 100644 --- a/libcrux-ml-kem/tests/nistkats.rs +++ b/libcrux-ml-kem/tests/nistkats.rs @@ -46,6 +46,20 @@ macro_rules! impl_nist_known_answer_tests { #[cfg(feature = "pre-verification")] assert!(validate_public_key(key_pair.public_key())); + #[cfg(all(feature = "pre-verification", not(feature = "kyber")))] + { + let unpacked_keys = unpacked::generate_key_pair(kat.key_generation_seed); + + let pk = unpacked::key_pair_serialized_public_key(&unpacked_keys); + let sk = unpacked::key_pair_serialized_private_key(&unpacked_keys); + + let public_key_hash = sha256(pk.as_slice()); + let secret_key_hash = sha256(sk.as_slice()); + + assert_eq!(public_key_hash, kat.sha3_256_hash_of_public_key, "lhs: computed public key hash, rhs: hash from kat"); + assert_eq!(secret_key_hash, kat.sha3_256_hash_of_secret_key, "lhs: computed secret key hash, rhs: hash from kat"); + } + let public_key_hash = sha256(key_pair.pk()); eprintln!("pk hash: {}", hex::encode(public_key_hash)); let secret_key_hash = sha256(key_pair.sk()); diff --git a/libcrux-ml-kem/tests/self.rs b/libcrux-ml-kem/tests/self.rs index ebffcc0b2..4496b65c7 100644 --- a/libcrux-ml-kem/tests/self.rs +++ b/libcrux-ml-kem/tests/self.rs @@ -45,18 +45,14 @@ macro_rules! impl_consistency_unpacked { let randomness = random_array(); // Generate unpacked key - let mut key_pair_unpacked = Default::default(); - p::unpacked::generate_key_pair(randomness, &mut key_pair_unpacked); + let key_pair_unpacked = p::unpacked::generate_key_pair(randomness); // Generate regular key let key_pair = p::generate_key_pair(randomness); // Ensure the two keys are the same - let mut serialized_public_key = Default::default(); - p::unpacked::serialized_public_key( - key_pair_unpacked.public_key(), - &mut serialized_public_key, - ); + let serialized_public_key = + p::unpacked::key_pair_serialized_public_key(&key_pair_unpacked); assert_eq!( key_pair.public_key().as_slice(), serialized_public_key.as_slice() @@ -69,6 +65,19 @@ macro_rules! impl_consistency_unpacked { serialized_public_key.as_slice(), key_pair.public_key().as_slice() ); + let mut serialized_private_key = Default::default(); + p::unpacked::key_pair_serialized_private_key_mut( + &key_pair_unpacked, + &mut serialized_private_key, + ); + assert_eq!( + serialized_private_key.as_slice(), + key_pair.private_key().as_slice() + ); + + // Unpacked key from the serialized private key + let mut new_kp = Default::default(); + p::unpacked::key_pair_from_private_mut(&serialized_private_key, &mut new_kp); let randomness = random_array(); let (ciphertext, shared_secret) = p::encapsulate(key_pair.public_key(), randomness); @@ -83,6 +92,20 @@ macro_rules! impl_consistency_unpacked { ciphertext_unpacked.as_slice(), "lhs: ciphertext, rhs: ciphertext_unpacked" ); + + // Check with re-assembled new_kp + let (ciphertext_unpacked, shared_secret_unpacked) = + p::unpacked::encapsulate(&new_kp.public_key, randomness); + assert_eq!( + shared_secret, shared_secret_unpacked, + "lhs: shared_secret, rhs: shared_secret_unpacked" + ); + assert_eq!( + ciphertext.as_slice(), + ciphertext_unpacked.as_slice(), + "lhs: ciphertext, rhs: ciphertext_unpacked" + ); + let shared_secret_decapsulated = p::unpacked::decapsulate(&key_pair_unpacked, &ciphertext); let shared_secret = p::decapsulate(key_pair.private_key(), &ciphertext); @@ -94,6 +117,14 @@ macro_rules! impl_consistency_unpacked { shared_secret, shared_secret_decapsulated, "lhs: shared_secret, rhs: shared_secret_decapsulated" ); + + // Check with re-assembled new_kp + let shared_secret_decapsulated = p::unpacked::decapsulate(&new_kp, &ciphertext); + assert_eq!( + shared_secret_unpacked, shared_secret_decapsulated, + "lhs: shared_secret_unpacked, rhs: shared_secret_decapsulated" + ); + // If the randomness was not enough for the rejection sampling step // in key-generation and encapsulation, simply return without // failing. diff --git a/libcrux-sha3/Cargo.toml b/libcrux-sha3/Cargo.toml index d76bbd9ca..85ed0be95 100644 --- a/libcrux-sha3/Cargo.toml +++ b/libcrux-sha3/Cargo.toml @@ -20,7 +20,7 @@ libcrux-intrinsics = { version = "0.0.2-beta.2", path = "../libcrux-intrinsics" # This is only required for verification. # The hax config is set by the hax toolchain. [target.'cfg(hax)'.dependencies] -hax-lib.workspace = true +hax-lib = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax/" } [features] simd128 = [] diff --git a/libcrux-sha3/proofs/fstar/extraction/Makefile b/libcrux-sha3/proofs/fstar/extraction/Makefile deleted file mode 100644 index ec420d509..000000000 --- a/libcrux-sha3/proofs/fstar/extraction/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.template diff --git a/macros/Cargo.toml b/macros/Cargo.toml new file mode 100644 index 000000000..26501a724 --- /dev/null +++ b/macros/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "libcrux-macros" +description = "Macros needed in libcrux" + +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[lib] +proc-macro = true diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 000000000..30896bf7f --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1,46 @@ +use proc_macro::{Delimiter, TokenStream, TokenTree}; + +fn skip_comma>(ts: &mut T) { + match ts.next() { + Some(TokenTree::Punct(p)) => assert_eq!(p.as_char(), ','), + _ => panic!("Expected comma"), + } +} + +fn accept_token>(ts: &mut T) -> TokenTree { + match ts.next() { + Some(t) => t, + _ => panic!("early end"), + } +} + +fn brace(ts: TokenStream) -> TokenTree { + TokenTree::Group(proc_macro::Group::new(Delimiter::Brace, ts)) +} + +#[proc_macro] +pub fn unroll_for(ts: TokenStream) -> TokenStream { + let mut i = ts.into_iter(); + let n_loops = accept_token(&mut i).to_string().parse::().unwrap(); + skip_comma(&mut i); + let var = accept_token(&mut i).to_string(); + let var = &var[1..var.len() - 1]; + skip_comma(&mut i); + let start = accept_token(&mut i).to_string(); + skip_comma(&mut i); + let increment = accept_token(&mut i).to_string(); + skip_comma(&mut i); + let grouped_body = brace(TokenStream::from_iter(i)); + let chunks = (0..n_loops).map(|i| { + let chunks = [ + format!("const {}: u32 = {} + {} * {};", var, start, i, increment) + .parse() + .unwrap(), + TokenStream::from(grouped_body.clone()), + ";".parse().unwrap(), + ]; + TokenStream::from(brace(TokenStream::from_iter(chunks))) + }); + TokenStream::from(brace(TokenStream::from_iter(chunks.into_iter().flatten()))) + // "{ let i = 0; println!(\"FROM MACRO{}\", i); }".parse().unwrap() +} diff --git a/proofs/fstar/extraction-edited/Makefile b/proofs/fstar/extraction-edited/Makefile index ec420d509..6b294a42d 100644 --- a/proofs/fstar/extraction-edited/Makefile +++ b/proofs/fstar/extraction-edited/Makefile @@ -1 +1,150 @@ -include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.template +# This is a generically useful Makefile for F* that is self-contained +# +# It is tempting to factor this out into multiple Makefiles but that +# makes it less portable, so resist temptation, or move to a more +# sophisticated build system. +# +# We expect FSTAR_HOME to be set to your FSTAR repo/install directory +# We expect HACL_HOME to be set to your HACL* repo location +# We expect HAX_LIBS_HOME to be set to the folder containing core, rust_primitives etc. +# +# ROOTS contains all the top-level F* files you wish to verify +# The default target `verify` verified ROOTS and its dependencies +# To lax-check instead, set `OTHERFLAGS="--lax"` on the command-line +# +# +# To make F* emacs mode use the settings in this file, you need to +# add the following lines to your .emacs +# +# (setq-default fstar-executable "/bin/fstar.exe") +# (setq-default fstar-smt-executable "/bin/z3") +# +# (defun my-fstar-compute-prover-args-using-make () +# "Construct arguments to pass to F* by calling make." +# (with-demoted-errors "Error when constructing arg string: %S" +# (let* ((fname (file-name-nondirectory buffer-file-name)) +# (target (concat fname "-in")) +# (argstr (car (process-lines "make" "--quiet" target)))) +# (split-string argstr)))) +# (setq fstar-subp-prover-args #'my-fstar-compute-prover-args-using-make) +# + +WORKSPACE_ROOT ?= $(shell git rev-parse --show-toplevel)/.. + +HAX_HOME ?= $(WORKSPACE_ROOT)/hax +HAX_PROOF_LIBS_HOME ?= $(HAX_HOME)/proof-libs/fstar +HAX_LIBS_HOME ?= $(HAX_HOME)/hax-lib/proofs/fstar/extraction +FSTAR_HOME ?= $(WORKSPACE_ROOT)/FStar +HACL_HOME ?= $(WORKSPACE_ROOT)/hacl-star +FSTAR_BIN ?= $(shell command -v fstar.exe 1>&2 2> /dev/null && echo "fstar.exe" || echo "$(FSTAR_HOME)/bin/fstar.exe") + +CACHE_DIR ?= .cache +HINT_DIR ?= .hints + +.PHONY: all verify verify-lax clean + +all: + rm -f .depend && $(MAKE) .depend + $(MAKE) verify + +ifeq ($(OTHERFLAGS),$(subst --admit_smt_queries true,,$(OTHERFLAGS))) +FSTAR_HINTS ?= --use_hints --use_hint_hashes --record_hints +else +FSTAR_HINTS ?= --use_hints --use_hint_hashes +endif + +VERIFIED = \ + Libcrux.Digest.fsti \ + Libcrux.Kem.Kyber.Constants.fsti \ + Libcrux.Kem.Kyber.Hash_functions.fsti \ + Libcrux.Kem.Kyber.Hash_functions.fst \ + Libcrux.Kem.Kyber.Types.fst \ + Libcrux.Kem.Kyber.Kyber768.fsti \ + Libcrux.Kem.Kyber.Kyber768.fst \ + Libcrux.Kem.Kyber.Kyber1024.fsti \ + Libcrux.Kem.Kyber.Kyber1024.fst \ + Libcrux.Kem.Kyber.Kyber512.fsti \ + Libcrux.Kem.Kyber.Kyber512.fst \ + Libcrux.Kem.Kyber.Ind_cpa.fsti \ + Libcrux.Kem.Kyber.Ind_cpa.fst \ + Libcrux.Kem.Kyber.fsti \ + Libcrux.Kem.Kyber.fst \ + Libcrux.Kem.Kyber.Arithmetic.fsti \ + Libcrux.Kem.Kyber.Arithmetic.fst \ + Libcrux.Kem.Kyber.Compress.fsti \ + Libcrux.Kem.Kyber.Compress.fst \ + Libcrux.Kem.Kyber.Constant_time_ops.fsti \ + Libcrux.Kem.Kyber.Constant_time_ops.fst \ + Libcrux.Kem.Kyber.Matrix.fsti \ + Libcrux.Kem.Kyber.Matrix.fst \ + Libcrux.Kem.Kyber.Ntt.fsti \ + Libcrux.Kem.Kyber.Ntt.fst \ + Libcrux.Kem.Kyber.Sampling.fst \ + Libcrux.Kem.Kyber.Serialize.fsti \ + Libcrux.Kem.Kyber.Serialize.fst + +UNVERIFIED = + + +VERIFIED_CHECKED = $(addsuffix .checked, $(addprefix $(CACHE_DIR)/,$(VERIFIED))) +UNVERIFIED_CHECKED = $(addsuffix .checked, $(addprefix $(CACHE_DIR)/,$(UNVERIFIED))) + +# By default, we process all the files in the current directory. Here, we +# *extend* the set of relevant files with the tests. +ROOTS = $(UNVERIFIED) $(VERIFIED) + +FSTAR_INCLUDE_DIRS = $(HACL_HOME)/lib $(HAX_PROOF_LIBS_HOME)/rust_primitives $(HAX_PROOF_LIBS_HOME)/core $(HAX_LIBS_HOME) + +FSTAR_FLAGS = $(FSTAR_HINTS) \ + --cmi \ + --warn_error -331 \ + --warn_error -321 \ + --warn_error -274 \ + --query_stats \ + --cache_checked_modules --cache_dir $(CACHE_DIR) \ + --already_cached "+Prims+FStar+LowStar+C+Spec.Loops+TestLib" \ + $(addprefix --include ,$(FSTAR_INCLUDE_DIRS)) + +# --log_queries \ +# --z3version 4.12.3 \ +# --smtencoding.l_arith_repr native \ +# --smtencoding.nl_arith_repr native \ + +FSTAR = $(FSTAR_BIN) $(FSTAR_FLAGS) + + +.depend: $(HINT_DIR) $(CACHE_DIR) $(ROOTS) + $(info $(ROOTS)) + $(FSTAR) --cmi --dep full $(ROOTS) --extract '* -Prims -LowStar -FStar' > $@ + +include .depend + +$(HINT_DIR): + mkdir -p $@ + +$(CACHE_DIR): + mkdir -p $@ + +$(UNVERIFIED_CHECKED): OTHERFLAGS=--admit_smt_queries true +$(CACHE_DIR)/%.checked: | .depend $(HINT_DIR) $(CACHE_DIR) + $(FSTAR) $(OTHERFLAGS) $< $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(notdir $*).hints + +verify: $(UNVERIFIED_CHECKED) $(VERIFIED_CHECKED) + +# Targets for interactive mode + +%.fst-in: + $(info $(FSTAR_FLAGS) \ + $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(basename $@).fst.hints) + +%.fsti-in: + $(info $(FSTAR_FLAGS) \ + $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(basename $@).fsti.hints) + + +# Clean targets + +SHELL=/usr/bin/env bash + +clean: + rm -rf $(CACHE_DIR)/* diff --git a/proofs/fstar/extraction-secret-independent/Makefile b/proofs/fstar/extraction-secret-independent/Makefile index ec420d509..3c4a3f008 100644 --- a/proofs/fstar/extraction-secret-independent/Makefile +++ b/proofs/fstar/extraction-secret-independent/Makefile @@ -1 +1,134 @@ -include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.template +# This is a generically useful Makefile for F* that is self-contained +# +# It is tempting to factor this out into multiple Makefiles but that +# makes it less portable, so resist temptation, or move to a more +# sophisticated build system. +# +# We expect FSTAR_HOME to be set to your FSTAR repo/install directory +# We expect HACL_HOME to be set to your HACL* repo location +# We expect HAX_LIBS_HOME to be set to the folder containing core, rust_primitives etc. +# +# ROOTS contains all the top-level F* files you wish to verify +# The default target `verify` verified ROOTS and its dependencies +# To lax-check instead, set `OTHERFLAGS="--lax"` on the command-line +# +# +# To make F* emacs mode use the settings in this file, you need to +# add the following lines to your .emacs +# +# (setq-default fstar-executable "/bin/fstar.exe") +# (setq-default fstar-smt-executable "/bin/z3") +# +# (defun my-fstar-compute-prover-args-using-make () +# "Construct arguments to pass to F* by calling make." +# (with-demoted-errors "Error when constructing arg string: %S" +# (let* ((fname (file-name-nondirectory buffer-file-name)) +# (target (concat fname "-in")) +# (argstr (car (process-lines "make" "--quiet" target)))) +# (split-string argstr)))) +# (setq fstar-subp-prover-args #'my-fstar-compute-prover-args-using-make) +# + +WORKSPACE_ROOT ?= $(shell git rev-parse --show-toplevel)/.. + +HAX_HOME ?= $(WORKSPACE_ROOT)/hax +HAX_PROOF_LIBS_HOME ?= $(HAX_HOME)/proof-libs/fstar-secret-integers +HAX_LIBS_HOME ?= $(HAX_HOME)/hax-lib/proofs/fstar/extraction +FSTAR_HOME ?= $(WORKSPACE_ROOT)/FStar +HACL_HOME ?= $(WORKSPACE_ROOT)/hacl-star +FSTAR_BIN ?= $(shell command -v fstar.exe 1>&2 2> /dev/null && echo "fstar.exe" || echo "$(FSTAR_HOME)/bin/fstar.exe") + +CACHE_DIR ?= .cache +HINT_DIR ?= .hints + +.PHONY: all verify verify-lax clean + +all: + rm -f .depend && $(MAKE) .depend + $(MAKE) verify + + +SECRET_INDEPENDENT = \ + Libcrux.Kem.Kyber.Constants.fsti \ + Libcrux.Digest.fsti \ + Libcrux.Kem.Kyber.Hash_functions.fsti \ + Libcrux.Kem.Kyber.Hash_functions.fst \ + Libcrux.Kem.Kyber.Kyber768.fsti \ + Libcrux.Kem.Kyber.Kyber768.fst \ + Libcrux.Kem.Kyber.Kyber1024.fsti \ + Libcrux.Kem.Kyber.Kyber1024.fst \ + Libcrux.Kem.Kyber.Kyber512.fsti \ + Libcrux.Kem.Kyber.Kyber512.fst \ + Libcrux.Kem.Kyber.Types.fst \ + Libcrux.Kem.Kyber.fsti \ + Libcrux.Kem.Kyber.fst \ + Libcrux.Kem.Kyber.Ind_cpa.fsti \ + Libcrux.Kem.Kyber.Ind_cpa.fst \ + Libcrux.Kem.Kyber.Arithmetic.fsti \ + Libcrux.Kem.Kyber.Arithmetic.fst \ + Libcrux.Kem.Kyber.Compress.fsti \ + Libcrux.Kem.Kyber.Compress.fst \ + Libcrux.Kem.Kyber.Constant_time_ops.fsti \ + Libcrux.Kem.Kyber.Constant_time_ops.fst \ + Libcrux.Kem.Kyber.Matrix.fsti \ + Libcrux.Kem.Kyber.Matrix.fst \ + Libcrux.Kem.Kyber.Ntt.fsti \ + Libcrux.Kem.Kyber.Ntt.fst \ + Libcrux.Kem.Kyber.Sampling.fst \ + Libcrux.Kem.Kyber.Serialize.fsti \ + Libcrux.Kem.Kyber.Serialize.fst + +SECRET_INDEPENDENT_CHECKED = $(addsuffix .checked, $(addprefix $(CACHE_DIR)/,$(SECRET_INDEPENDENT))) + +# By default, we process all the files in the current directory. Here, we +# *extend* the set of relevant files with the tests. +ROOTS = $(SECRET_INDEPENDENT) + +FSTAR_INCLUDE_DIRS = $(HACL_HOME)/lib $(HAX_PROOF_LIBS_HOME)/rust_primitives $(HAX_PROOF_LIBS_HOME)/core $(HAX_LIBS_HOME) + +FSTAR_FLAGS = --cmi \ + --warn_error -331-321-274 \ + --admit_smt_queries true \ + --cache_checked_modules --cache_dir $(CACHE_DIR) \ + --already_cached "+Prims+FStar+LowStar+C+Spec.Loops+TestLib" \ + $(addprefix --include ,$(FSTAR_INCLUDE_DIRS)) + +FSTAR = $(FSTAR_BIN) $(FSTAR_FLAGS) + + +.depend: $(HINT_DIR) $(CACHE_DIR) $(ROOTS) + $(info $(ROOTS)) + $(FSTAR) --cmi --dep full $(ROOTS) --extract '* -Prims -LowStar -FStar' > $@ + +include .depend + +$(HINT_DIR): + mkdir -p $@ + +$(CACHE_DIR): + mkdir -p $@ + +$(SECRET_INDEPENDENT_CHECKED): OTHERFLAGS=--admit_smt_queries true +$(CACHE_DIR)/%.checked: | .depend $(HINT_DIR) $(CACHE_DIR) + $(FSTAR) $(OTHERFLAGS) $< $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(notdir $*).hints + +verify: $(SECRET_INDEPENDENT_CHECKED) + +# Targets for interactive mode + +%.fst-in: + $(info $(FSTAR_FLAGS) \ + $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(basename $@).fst.hints) + +%.fsti-in: + $(info $(FSTAR_FLAGS) \ + $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(basename $@).fsti.hints) + + +# Clean targets + +SHELL=/usr/bin/env bash + +clean: + rm -rf $(CACHE_DIR)/* + rm *.fst diff --git a/proofs/fstar/extraction/Makefile b/proofs/fstar/extraction/Makefile index ec420d509..763274af1 100644 --- a/proofs/fstar/extraction/Makefile +++ b/proofs/fstar/extraction/Makefile @@ -1 +1,127 @@ -include $(shell git rev-parse --show-toplevel)/fstar-helpers/Makefile.template +# This is a generically useful Makefile for F* that is self-contained +# +# It is tempting to factor this out into multiple Makefiles but that +# makes it less portable, so resist temptation, or move to a more +# sophisticated build system. +# +# We expect FSTAR_HOME to be set to your FSTAR repo/install directory +# We expect HACL_HOME to be set to your HACL* repo location +# We expect HAX_LIBS_HOME to be set to the folder containing core, rust_primitives etc. +# +# ROOTS contains all the top-level F* files you wish to verify +# The default target `verify` verified ROOTS and its dependencies +# To lax-check instead, set `OTHERFLAGS="--lax"` on the command-line +# +# +# To make F* emacs mode use the settings in this file, you need to +# add the following lines to your .emacs +# +# (setq-default fstar-executable "/bin/fstar.exe") +# (setq-default fstar-smt-executable "/bin/z3") +# +# (defun my-fstar-compute-prover-args-using-make () +# "Construct arguments to pass to F* by calling make." +# (with-demoted-errors "Error when constructing arg string: %S" +# (let* ((fname (file-name-nondirectory buffer-file-name)) +# (target (concat fname "-in")) +# (argstr (car (process-lines "make" "--quiet" target)))) +# (split-string argstr)))) +# (setq fstar-subp-prover-args #'my-fstar-compute-prover-args-using-make) +# + +WORKSPACE_ROOT ?= $(shell git rev-parse --show-toplevel)/.. + +HAX_HOME ?= $(WORKSPACE_ROOT)/hax +HAX_PROOF_LIBS_HOME ?= $(HAX_HOME)/proof-libs/fstar +HAX_LIBS_HOME ?= $(HAX_HOME)/hax-lib/proofs/fstar/extraction +FSTAR_HOME ?= $(WORKSPACE_ROOT)/FStar +HACL_HOME ?= $(WORKSPACE_ROOT)/hacl-star +FSTAR_BIN ?= $(shell command -v fstar.exe 1>&2 2> /dev/null && echo "fstar.exe" || echo "$(FSTAR_HOME)/bin/fstar.exe") + +CACHE_DIR ?= .cache +HINT_DIR ?= .hints + +.PHONY: all verify verify-lax clean + +all: + rm -f .depend && $(MAKE) .depend + $(MAKE) verify + + +VERIFIED = \ + Libcrux.Kem.Kyber.Constants.fsti \ + Libcrux.Kem.Kyber.Kyber768.fst \ + Libcrux.Kem.Kyber.Kyber1024.fst \ + Libcrux.Kem.Kyber.Kyber512.fst + + +UNVERIFIED = \ + Libcrux.Kem.Kyber.Types.fst \ + Libcrux.Kem.Kyber.fst \ + Libcrux.Kem.Kyber.Ind_cpa.fst \ + Libcrux.Kem.Kyber.Arithmetic.fst \ + Libcrux.Kem.Kyber.Arithmetic.fsti \ + Libcrux.Kem.Kyber.Compress.fst \ + Libcrux.Kem.Kyber.Constant_time_ops.fst \ + Libcrux.Digest.fsti \ + Libcrux.Digest.Incremental_x4.fsti \ + Libcrux.Kem.Kyber.Hash_functions.fst \ + Libcrux.Kem.Kyber.Matrix.fst \ + Libcrux.Kem.Kyber.Ntt.fst \ + Libcrux.Kem.Kyber.Sampling.fst \ + Libcrux.Kem.Kyber.Serialize.fst + +VERIFIED_CHECKED = $(addsuffix .checked, $(addprefix $(CACHE_DIR)/,$(VERIFIED))) +UNVERIFIED_CHECKED = $(addsuffix .checked, $(addprefix $(CACHE_DIR)/,$(UNVERIFIED))) + +# By default, we process all the files in the current directory. Here, we +# *extend* the set of relevant files with the tests. +ROOTS = $(UNVERIFIED) $(VERIFIED) + +FSTAR_INCLUDE_DIRS = $(HACL_HOME)/lib $(HAX_PROOF_LIBS_HOME)/rust_primitives $(HAX_PROOF_LIBS_HOME)/core $(HAX_LIBS_HOME) ../../../sys/platform/proofs/fstar/extraction/ + +FSTAR_FLAGS = --cmi \ + --warn_error -331-321-274 \ + --cache_checked_modules --cache_dir $(CACHE_DIR) \ + --already_cached "+Prims+FStar+LowStar+C+Spec.Loops+TestLib" \ + $(addprefix --include ,$(FSTAR_INCLUDE_DIRS)) + +FSTAR = $(FSTAR_BIN) $(FSTAR_FLAGS) + + +.depend: $(HINT_DIR) $(CACHE_DIR) $(ROOTS) + $(info $(ROOTS)) + $(FSTAR) --cmi --dep full $(ROOTS) --extract '* -Prims -LowStar -FStar' > $@ + +include .depend + +$(HINT_DIR): + mkdir -p $@ + +$(CACHE_DIR): + mkdir -p $@ + +$(UNVERIFIED_CHECKED): OTHERFLAGS=--admit_smt_queries true +$(CACHE_DIR)/%.checked: | .depend $(HINT_DIR) $(CACHE_DIR) + $(FSTAR) $(OTHERFLAGS) $< $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(notdir $*).hints + +verify: $(UNVERIFIED_CHECKED) $(VERIFIED_CHECKED) + +# Targets for interactive mode + +%.fst-in: + $(info $(FSTAR_FLAGS) \ + $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(basename $@).fst.hints) + +%.fsti-in: + $(info $(FSTAR_FLAGS) \ + $(ENABLE_HINTS) --hint_file $(HINT_DIR)/$(basename $@).fsti.hints) + + +# Clean targets + +SHELL=/usr/bin/env bash + +clean: + rm -rf $(CACHE_DIR)/* + rm *.fst diff --git a/sha2/Cargo.toml b/sha2/Cargo.toml new file mode 100644 index 000000000..1c17ba859 --- /dev/null +++ b/sha2/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "libcrux-sha2" +description = "Formally verified SHA2 hash library" + +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +[features] +default = ["portable_hacl"] +portable_hacl = ["hacl"] +hacl = ["dep:libcrux-hacl-rs"] + +[dependencies] +libcrux-hacl-rs = { version = "=0.0.2-beta.2", path = "../hacl-rs", optional = true } +libcrux-traits = { version = "=0.0.2-beta.2", path = "../traits/" } +libcrux-macros = { version = "=0.0.2-beta.2", path = "../macros" } diff --git a/sha2/src/hacl.rs b/sha2/src/hacl.rs new file mode 100644 index 000000000..5529d3552 --- /dev/null +++ b/sha2/src/hacl.rs @@ -0,0 +1,1243 @@ +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(unused_assignments)] +#![allow(unreachable_patterns)] + +use libcrux_hacl_rs::fstar; +use libcrux_hacl_rs::lowstar; +use libcrux_hacl_rs::streaming_types; +use libcrux_macros as krml; + +pub const h224: [u32; 8] = [ + 0xc1059ed8u32, + 0x367cd507u32, + 0x3070dd17u32, + 0xf70e5939u32, + 0xffc00b31u32, + 0x68581511u32, + 0x64f98fa7u32, + 0xbefa4fa4u32, +]; + +pub const h256: [u32; 8] = [ + 0x6a09e667u32, + 0xbb67ae85u32, + 0x3c6ef372u32, + 0xa54ff53au32, + 0x510e527fu32, + 0x9b05688cu32, + 0x1f83d9abu32, + 0x5be0cd19u32, +]; + +pub const h384: [u64; 8] = [ + 0xcbbb9d5dc1059ed8u64, + 0x629a292a367cd507u64, + 0x9159015a3070dd17u64, + 0x152fecd8f70e5939u64, + 0x67332667ffc00b31u64, + 0x8eb44a8768581511u64, + 0xdb0c2e0d64f98fa7u64, + 0x47b5481dbefa4fa4u64, +]; + +pub const h512: [u64; 8] = [ + 0x6a09e667f3bcc908u64, + 0xbb67ae8584caa73bu64, + 0x3c6ef372fe94f82bu64, + 0xa54ff53a5f1d36f1u64, + 0x510e527fade682d1u64, + 0x9b05688c2b3e6c1fu64, + 0x1f83d9abfb41bd6bu64, + 0x5be0cd19137e2179u64, +]; + +pub const k224_256: [u32; 64] = [ + 0x428a2f98u32, + 0x71374491u32, + 0xb5c0fbcfu32, + 0xe9b5dba5u32, + 0x3956c25bu32, + 0x59f111f1u32, + 0x923f82a4u32, + 0xab1c5ed5u32, + 0xd807aa98u32, + 0x12835b01u32, + 0x243185beu32, + 0x550c7dc3u32, + 0x72be5d74u32, + 0x80deb1feu32, + 0x9bdc06a7u32, + 0xc19bf174u32, + 0xe49b69c1u32, + 0xefbe4786u32, + 0x0fc19dc6u32, + 0x240ca1ccu32, + 0x2de92c6fu32, + 0x4a7484aau32, + 0x5cb0a9dcu32, + 0x76f988dau32, + 0x983e5152u32, + 0xa831c66du32, + 0xb00327c8u32, + 0xbf597fc7u32, + 0xc6e00bf3u32, + 0xd5a79147u32, + 0x06ca6351u32, + 0x14292967u32, + 0x27b70a85u32, + 0x2e1b2138u32, + 0x4d2c6dfcu32, + 0x53380d13u32, + 0x650a7354u32, + 0x766a0abbu32, + 0x81c2c92eu32, + 0x92722c85u32, + 0xa2bfe8a1u32, + 0xa81a664bu32, + 0xc24b8b70u32, + 0xc76c51a3u32, + 0xd192e819u32, + 0xd6990624u32, + 0xf40e3585u32, + 0x106aa070u32, + 0x19a4c116u32, + 0x1e376c08u32, + 0x2748774cu32, + 0x34b0bcb5u32, + 0x391c0cb3u32, + 0x4ed8aa4au32, + 0x5b9cca4fu32, + 0x682e6ff3u32, + 0x748f82eeu32, + 0x78a5636fu32, + 0x84c87814u32, + 0x8cc70208u32, + 0x90befffau32, + 0xa4506cebu32, + 0xbef9a3f7u32, + 0xc67178f2u32, +]; + +pub const k384_512: [u64; 80] = [ + 0x428a2f98d728ae22u64, + 0x7137449123ef65cdu64, + 0xb5c0fbcfec4d3b2fu64, + 0xe9b5dba58189dbbcu64, + 0x3956c25bf348b538u64, + 0x59f111f1b605d019u64, + 0x923f82a4af194f9bu64, + 0xab1c5ed5da6d8118u64, + 0xd807aa98a3030242u64, + 0x12835b0145706fbeu64, + 0x243185be4ee4b28cu64, + 0x550c7dc3d5ffb4e2u64, + 0x72be5d74f27b896fu64, + 0x80deb1fe3b1696b1u64, + 0x9bdc06a725c71235u64, + 0xc19bf174cf692694u64, + 0xe49b69c19ef14ad2u64, + 0xefbe4786384f25e3u64, + 0x0fc19dc68b8cd5b5u64, + 0x240ca1cc77ac9c65u64, + 0x2de92c6f592b0275u64, + 0x4a7484aa6ea6e483u64, + 0x5cb0a9dcbd41fbd4u64, + 0x76f988da831153b5u64, + 0x983e5152ee66dfabu64, + 0xa831c66d2db43210u64, + 0xb00327c898fb213fu64, + 0xbf597fc7beef0ee4u64, + 0xc6e00bf33da88fc2u64, + 0xd5a79147930aa725u64, + 0x06ca6351e003826fu64, + 0x142929670a0e6e70u64, + 0x27b70a8546d22ffcu64, + 0x2e1b21385c26c926u64, + 0x4d2c6dfc5ac42aedu64, + 0x53380d139d95b3dfu64, + 0x650a73548baf63deu64, + 0x766a0abb3c77b2a8u64, + 0x81c2c92e47edaee6u64, + 0x92722c851482353bu64, + 0xa2bfe8a14cf10364u64, + 0xa81a664bbc423001u64, + 0xc24b8b70d0f89791u64, + 0xc76c51a30654be30u64, + 0xd192e819d6ef5218u64, + 0xd69906245565a910u64, + 0xf40e35855771202au64, + 0x106aa07032bbd1b8u64, + 0x19a4c116b8d2d0c8u64, + 0x1e376c085141ab53u64, + 0x2748774cdf8eeb99u64, + 0x34b0bcb5e19b48a8u64, + 0x391c0cb3c5c95a63u64, + 0x4ed8aa4ae3418acbu64, + 0x5b9cca4f7763e373u64, + 0x682e6ff3d6b2b8a3u64, + 0x748f82ee5defb2fcu64, + 0x78a5636f43172f60u64, + 0x84c87814a1f0ab72u64, + 0x8cc702081a6439ecu64, + 0x90befffa23631e28u64, + 0xa4506cebde82bde9u64, + 0xbef9a3f7b2c67915u64, + 0xc67178f2e372532bu64, + 0xca273eceea26619cu64, + 0xd186b8c721c0c207u64, + 0xeada7dd6cde0eb1eu64, + 0xf57d4f7fee6ed178u64, + 0x06f067aa72176fbau64, + 0x0a637dc5a2c898a6u64, + 0x113f9804bef90daeu64, + 0x1b710b35131c471bu64, + 0x28db77f523047d84u64, + 0x32caab7b40c72493u64, + 0x3c9ebe0a15c9bebcu64, + 0x431d67c49c100d4cu64, + 0x4cc5d4becb3e42b6u64, + 0x597f299cfc657e2au64, + 0x5fcb6fab3ad6faecu64, + 0x6c44198c4a475817u64, +]; + +pub fn sha256_init(hash: &mut [u32]) { + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u32 = (&crate::hacl::h256)[i as usize]; + let os: (&mut [u32], &mut [u32]) = hash.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +#[inline] +fn sha256_update(b: &[u8], hash: &mut [u32]) { + let mut hash_old: [u32; 8] = [0u32; 8usize]; + let mut ws: [u32; 16] = [0u32; 16usize]; + ((&mut hash_old)[0usize..8usize]).copy_from_slice(&hash[0usize..8usize]); + let b1: &[u8] = b; + let u: u32 = lowstar::endianness::load32_be(&b1[0usize..]); + (&mut ws)[0usize] = u; + let u0: u32 = lowstar::endianness::load32_be(&b1[4usize..]); + (&mut ws)[1usize] = u0; + let u1: u32 = lowstar::endianness::load32_be(&b1[8usize..]); + (&mut ws)[2usize] = u1; + let u2: u32 = lowstar::endianness::load32_be(&b1[12usize..]); + (&mut ws)[3usize] = u2; + let u3: u32 = lowstar::endianness::load32_be(&b1[16usize..]); + (&mut ws)[4usize] = u3; + let u4: u32 = lowstar::endianness::load32_be(&b1[20usize..]); + (&mut ws)[5usize] = u4; + let u5: u32 = lowstar::endianness::load32_be(&b1[24usize..]); + (&mut ws)[6usize] = u5; + let u6: u32 = lowstar::endianness::load32_be(&b1[28usize..]); + (&mut ws)[7usize] = u6; + let u7: u32 = lowstar::endianness::load32_be(&b1[32usize..]); + (&mut ws)[8usize] = u7; + let u8: u32 = lowstar::endianness::load32_be(&b1[36usize..]); + (&mut ws)[9usize] = u8; + let u9: u32 = lowstar::endianness::load32_be(&b1[40usize..]); + (&mut ws)[10usize] = u9; + let u10: u32 = lowstar::endianness::load32_be(&b1[44usize..]); + (&mut ws)[11usize] = u10; + let u11: u32 = lowstar::endianness::load32_be(&b1[48usize..]); + (&mut ws)[12usize] = u11; + let u12: u32 = lowstar::endianness::load32_be(&b1[52usize..]); + (&mut ws)[13usize] = u12; + let u13: u32 = lowstar::endianness::load32_be(&b1[56usize..]); + (&mut ws)[14usize] = u13; + let u14: u32 = lowstar::endianness::load32_be(&b1[60usize..]); + (&mut ws)[15usize] = u14; + krml::unroll_for!(4, "i", 0u32, 1u32, { + krml::unroll_for!(16, "i0", 0u32, 1u32, { + let k_t: u32 = + (&crate::hacl::k224_256)[16u32.wrapping_mul(i).wrapping_add(i0) as usize]; + let ws_t: u32 = (&ws)[i0 as usize]; + let a0: u32 = hash[0usize]; + let b0: u32 = hash[1usize]; + let c0: u32 = hash[2usize]; + let d0: u32 = hash[3usize]; + let e0: u32 = hash[4usize]; + let f0: u32 = hash[5usize]; + let g0: u32 = hash[6usize]; + let h02: u32 = hash[7usize]; + let k_e_t: u32 = k_t; + let t1: u32 = h02 + .wrapping_add( + (e0.wrapping_shl(26u32) | e0.wrapping_shr(6u32)) + ^ ((e0.wrapping_shl(21u32) | e0.wrapping_shr(11u32)) + ^ (e0.wrapping_shl(7u32) | e0.wrapping_shr(25u32))), + ) + .wrapping_add(e0 & f0 ^ !e0 & g0) + .wrapping_add(k_e_t) + .wrapping_add(ws_t); + let t2: u32 = ((a0.wrapping_shl(30u32) | a0.wrapping_shr(2u32)) + ^ ((a0.wrapping_shl(19u32) | a0.wrapping_shr(13u32)) + ^ (a0.wrapping_shl(10u32) | a0.wrapping_shr(22u32)))) + .wrapping_add(a0 & b0 ^ (a0 & c0 ^ b0 & c0)); + let a1: u32 = t1.wrapping_add(t2); + let b10: u32 = a0; + let c1: u32 = b0; + let d1: u32 = c0; + let e1: u32 = d0.wrapping_add(t1); + let f1: u32 = e0; + let g1: u32 = f0; + let h12: u32 = g0; + hash[0usize] = a1; + hash[1usize] = b10; + hash[2usize] = c1; + hash[3usize] = d1; + hash[4usize] = e1; + hash[5usize] = f1; + hash[6usize] = g1; + hash[7usize] = h12 + }); + if i < 3u32 { + krml::unroll_for!(16, "i0", 0u32, 1u32, { + let t16: u32 = (&ws)[i0 as usize]; + let t15: u32 = (&ws)[i0.wrapping_add(1u32).wrapping_rem(16u32) as usize]; + let t7: u32 = (&ws)[i0.wrapping_add(9u32).wrapping_rem(16u32) as usize]; + let t2: u32 = (&ws)[i0.wrapping_add(14u32).wrapping_rem(16u32) as usize]; + let s1: u32 = (t2.wrapping_shl(15u32) | t2.wrapping_shr(17u32)) + ^ ((t2.wrapping_shl(13u32) | t2.wrapping_shr(19u32)) ^ t2.wrapping_shr(10u32)); + let s0: u32 = (t15.wrapping_shl(25u32) | t15.wrapping_shr(7u32)) + ^ ((t15.wrapping_shl(14u32) | t15.wrapping_shr(18u32)) + ^ t15.wrapping_shr(3u32)); + (&mut ws)[i0 as usize] = s1.wrapping_add(t7).wrapping_add(s0).wrapping_add(t16) + }) + } + }); + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u32 = (hash[i as usize]).wrapping_add((&hash_old)[i as usize]); + let os: (&mut [u32], &mut [u32]) = hash.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +pub fn sha256_update_nblocks(len: u32, b: &[u8], st: &mut [u32]) { + let blocks: u32 = len.wrapping_div(64u32); + for i in 0u32..blocks { + let b0: &[u8] = b; + let mb: (&[u8], &[u8]) = b0.split_at(i.wrapping_mul(64u32) as usize); + crate::hacl::sha256_update(mb.1, st) + } +} + +pub fn sha256_update_last(totlen: u64, len: u32, b: &[u8], hash: &mut [u32]) { + let blocks: u32 = if len.wrapping_add(8u32).wrapping_add(1u32) <= 64u32 { + 1u32 + } else { + 2u32 + }; + let fin: u32 = blocks.wrapping_mul(64u32); + let mut last: [u8; 128] = [0u8; 128usize]; + let mut totlen_buf: [u8; 8] = [0u8; 8usize]; + let total_len_bits: u64 = totlen.wrapping_shl(3u32); + lowstar::endianness::store64_be(&mut totlen_buf, total_len_bits); + let b0: &[u8] = b; + ((&mut last)[0usize..len as usize]).copy_from_slice(&b0[0usize..len as usize]); + (&mut last)[len as usize] = 0x80u8; + ((&mut last)[fin.wrapping_sub(8u32) as usize..fin.wrapping_sub(8u32) as usize + 8usize]) + .copy_from_slice(&(&totlen_buf)[0usize..8usize]); + let last0: (&[u8], &[u8]) = last.split_at(0usize); + let last1: (&[u8], &[u8]) = last0.1.split_at(64usize); + let l0: &[u8] = last1.0; + let l1: &[u8] = last1.1; + let lb0: &[u8] = l0; + let lb1: &[u8] = l1; + let last00: &[u8] = lb0; + let last10: &[u8] = lb1; + crate::hacl::sha256_update(last00, hash); + if blocks > 1u32 { + crate::hacl::sha256_update(last10, hash) + } +} + +pub fn sha256_finish(st: &[u32], h: &mut [u8]) { + let mut hbuf: [u8; 32] = [0u8; 32usize]; + krml::unroll_for!( + 8, + "i", + 0u32, + 1u32, + lowstar::endianness::store32_be( + &mut (&mut hbuf)[i.wrapping_mul(4u32) as usize..], + st[i as usize] + ) + ); + (h[0usize..32usize]).copy_from_slice(&(&(&hbuf)[0usize..])[0usize..32usize]) +} + +#[inline] +fn sha224_init(hash: &mut [u32]) { + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u32 = (&crate::hacl::h224)[i as usize]; + let os: (&mut [u32], &mut [u32]) = hash.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +#[inline] +fn sha224_update_nblocks(len: u32, b: &[u8], st: &mut [u32]) { + crate::hacl::sha256_update_nblocks(len, b, st) +} + +fn sha224_update_last(totlen: u64, len: u32, b: &[u8], st: &mut [u32]) { + crate::hacl::sha256_update_last(totlen, len, b, st) +} + +#[inline] +fn sha224_finish(st: &[u32], h: &mut [u8]) { + let mut hbuf: [u8; 32] = [0u8; 32usize]; + krml::unroll_for!( + 8, + "i", + 0u32, + 1u32, + lowstar::endianness::store32_be( + &mut (&mut hbuf)[i.wrapping_mul(4u32) as usize..], + st[i as usize] + ) + ); + (h[0usize..28usize]).copy_from_slice(&(&(&hbuf)[0usize..])[0usize..28usize]) +} + +pub fn sha512_init(hash: &mut [u64]) { + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u64 = (&crate::hacl::h512)[i as usize]; + let os: (&mut [u64], &mut [u64]) = hash.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +#[inline] +fn sha512_update(b: &[u8], hash: &mut [u64]) { + let mut hash_old: [u64; 8] = [0u64; 8usize]; + let mut ws: [u64; 16] = [0u64; 16usize]; + ((&mut hash_old)[0usize..8usize]).copy_from_slice(&hash[0usize..8usize]); + let b1: &[u8] = b; + let u: u64 = lowstar::endianness::load64_be(&b1[0usize..]); + (&mut ws)[0usize] = u; + let u0: u64 = lowstar::endianness::load64_be(&b1[8usize..]); + (&mut ws)[1usize] = u0; + let u1: u64 = lowstar::endianness::load64_be(&b1[16usize..]); + (&mut ws)[2usize] = u1; + let u2: u64 = lowstar::endianness::load64_be(&b1[24usize..]); + (&mut ws)[3usize] = u2; + let u3: u64 = lowstar::endianness::load64_be(&b1[32usize..]); + (&mut ws)[4usize] = u3; + let u4: u64 = lowstar::endianness::load64_be(&b1[40usize..]); + (&mut ws)[5usize] = u4; + let u5: u64 = lowstar::endianness::load64_be(&b1[48usize..]); + (&mut ws)[6usize] = u5; + let u6: u64 = lowstar::endianness::load64_be(&b1[56usize..]); + (&mut ws)[7usize] = u6; + let u7: u64 = lowstar::endianness::load64_be(&b1[64usize..]); + (&mut ws)[8usize] = u7; + let u8: u64 = lowstar::endianness::load64_be(&b1[72usize..]); + (&mut ws)[9usize] = u8; + let u9: u64 = lowstar::endianness::load64_be(&b1[80usize..]); + (&mut ws)[10usize] = u9; + let u10: u64 = lowstar::endianness::load64_be(&b1[88usize..]); + (&mut ws)[11usize] = u10; + let u11: u64 = lowstar::endianness::load64_be(&b1[96usize..]); + (&mut ws)[12usize] = u11; + let u12: u64 = lowstar::endianness::load64_be(&b1[104usize..]); + (&mut ws)[13usize] = u12; + let u13: u64 = lowstar::endianness::load64_be(&b1[112usize..]); + (&mut ws)[14usize] = u13; + let u14: u64 = lowstar::endianness::load64_be(&b1[120usize..]); + (&mut ws)[15usize] = u14; + krml::unroll_for!(5, "i", 0u32, 1u32, { + krml::unroll_for!(16, "i0", 0u32, 1u32, { + let k_t: u64 = + (&crate::hacl::k384_512)[16u32.wrapping_mul(i).wrapping_add(i0) as usize]; + let ws_t: u64 = (&ws)[i0 as usize]; + let a0: u64 = hash[0usize]; + let b0: u64 = hash[1usize]; + let c0: u64 = hash[2usize]; + let d0: u64 = hash[3usize]; + let e0: u64 = hash[4usize]; + let f0: u64 = hash[5usize]; + let g0: u64 = hash[6usize]; + let h02: u64 = hash[7usize]; + let k_e_t: u64 = k_t; + let t1: u64 = h02 + .wrapping_add( + (e0.wrapping_shl(50u32) | e0.wrapping_shr(14u32)) + ^ ((e0.wrapping_shl(46u32) | e0.wrapping_shr(18u32)) + ^ (e0.wrapping_shl(23u32) | e0.wrapping_shr(41u32))), + ) + .wrapping_add(e0 & f0 ^ !e0 & g0) + .wrapping_add(k_e_t) + .wrapping_add(ws_t); + let t2: u64 = ((a0.wrapping_shl(36u32) | a0.wrapping_shr(28u32)) + ^ ((a0.wrapping_shl(30u32) | a0.wrapping_shr(34u32)) + ^ (a0.wrapping_shl(25u32) | a0.wrapping_shr(39u32)))) + .wrapping_add(a0 & b0 ^ (a0 & c0 ^ b0 & c0)); + let a1: u64 = t1.wrapping_add(t2); + let b10: u64 = a0; + let c1: u64 = b0; + let d1: u64 = c0; + let e1: u64 = d0.wrapping_add(t1); + let f1: u64 = e0; + let g1: u64 = f0; + let h12: u64 = g0; + hash[0usize] = a1; + hash[1usize] = b10; + hash[2usize] = c1; + hash[3usize] = d1; + hash[4usize] = e1; + hash[5usize] = f1; + hash[6usize] = g1; + hash[7usize] = h12 + }); + if i < 4u32 { + krml::unroll_for!(16, "i0", 0u32, 1u32, { + let t16: u64 = (&ws)[i0 as usize]; + let t15: u64 = (&ws)[i0.wrapping_add(1u32).wrapping_rem(16u32) as usize]; + let t7: u64 = (&ws)[i0.wrapping_add(9u32).wrapping_rem(16u32) as usize]; + let t2: u64 = (&ws)[i0.wrapping_add(14u32).wrapping_rem(16u32) as usize]; + let s1: u64 = (t2.wrapping_shl(45u32) | t2.wrapping_shr(19u32)) + ^ ((t2.wrapping_shl(3u32) | t2.wrapping_shr(61u32)) ^ t2.wrapping_shr(6u32)); + let s0: u64 = (t15.wrapping_shl(63u32) | t15.wrapping_shr(1u32)) + ^ ((t15.wrapping_shl(56u32) | t15.wrapping_shr(8u32)) ^ t15.wrapping_shr(7u32)); + (&mut ws)[i0 as usize] = s1.wrapping_add(t7).wrapping_add(s0).wrapping_add(t16) + }) + } + }); + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u64 = (hash[i as usize]).wrapping_add((&hash_old)[i as usize]); + let os: (&mut [u64], &mut [u64]) = hash.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +pub fn sha512_update_nblocks(len: u32, b: &[u8], st: &mut [u64]) { + let blocks: u32 = len.wrapping_div(128u32); + for i in 0u32..blocks { + let b0: &[u8] = b; + let mb: (&[u8], &[u8]) = b0.split_at(i.wrapping_mul(128u32) as usize); + crate::hacl::sha512_update(mb.1, st) + } +} + +pub fn sha512_update_last(totlen: fstar::uint128::uint128, len: u32, b: &[u8], hash: &mut [u64]) { + let blocks: u32 = if len.wrapping_add(16u32).wrapping_add(1u32) <= 128u32 { + 1u32 + } else { + 2u32 + }; + let fin: u32 = blocks.wrapping_mul(128u32); + let mut last: [u8; 256] = [0u8; 256usize]; + let mut totlen_buf: [u8; 16] = [0u8; 16usize]; + let total_len_bits: fstar::uint128::uint128 = fstar::uint128::shift_left(totlen, 3u32); + lowstar::endianness::store128_be(&mut totlen_buf, total_len_bits); + let b0: &[u8] = b; + ((&mut last)[0usize..len as usize]).copy_from_slice(&b0[0usize..len as usize]); + (&mut last)[len as usize] = 0x80u8; + ((&mut last)[fin.wrapping_sub(16u32) as usize..fin.wrapping_sub(16u32) as usize + 16usize]) + .copy_from_slice(&(&totlen_buf)[0usize..16usize]); + let last0: (&[u8], &[u8]) = last.split_at(0usize); + let last1: (&[u8], &[u8]) = last0.1.split_at(128usize); + let l0: &[u8] = last1.0; + let l1: &[u8] = last1.1; + let lb0: &[u8] = l0; + let lb1: &[u8] = l1; + let last00: &[u8] = lb0; + let last10: &[u8] = lb1; + crate::hacl::sha512_update(last00, hash); + if blocks > 1u32 { + crate::hacl::sha512_update(last10, hash) + } +} + +pub fn sha512_finish(st: &[u64], h: &mut [u8]) { + let mut hbuf: [u8; 64] = [0u8; 64usize]; + krml::unroll_for!( + 8, + "i", + 0u32, + 1u32, + lowstar::endianness::store64_be( + &mut (&mut hbuf)[i.wrapping_mul(8u32) as usize..], + st[i as usize] + ) + ); + (h[0usize..64usize]).copy_from_slice(&(&(&hbuf)[0usize..])[0usize..64usize]) +} + +pub fn sha384_init(hash: &mut [u64]) { + krml::unroll_for!(8, "i", 0u32, 1u32, { + let x: u64 = (&crate::hacl::h384)[i as usize]; + let os: (&mut [u64], &mut [u64]) = hash.split_at_mut(0usize); + os.1[i as usize] = x + }) +} + +pub fn sha384_update_nblocks(len: u32, b: &[u8], st: &mut [u64]) { + crate::hacl::sha512_update_nblocks(len, b, st) +} + +pub fn sha384_update_last(totlen: fstar::uint128::uint128, len: u32, b: &[u8], st: &mut [u64]) { + crate::hacl::sha512_update_last(totlen, len, b, st) +} + +pub fn sha384_finish(st: &[u64], h: &mut [u8]) { + let mut hbuf: [u8; 64] = [0u8; 64usize]; + krml::unroll_for!( + 8, + "i", + 0u32, + 1u32, + lowstar::endianness::store64_be( + &mut (&mut hbuf)[i.wrapping_mul(8u32) as usize..], + st[i as usize] + ) + ); + (h[0usize..48usize]).copy_from_slice(&(&(&hbuf)[0usize..])[0usize..48usize]) +} + +pub type state_t_224 = streaming_types::state_32; + +pub type state_t_256 = streaming_types::state_32; + +pub type state_t_384 = streaming_types::state_64; + +pub type state_t_512 = streaming_types::state_64; + +/** +Allocate initial state for the SHA2_256 hash. The state is to be freed by +calling `free_256`. +*/ +pub fn malloc_256() -> Box<[streaming_types::state_32]> { + let buf: Box<[u8]> = vec![0u8; 64usize].into_boxed_slice(); + let mut block_state: Box<[u32]> = vec![0u32; 8usize].into_boxed_slice(); + crate::hacl::sha256_init(&mut block_state); + let s: streaming_types::state_32 = streaming_types::state_32 { + block_state, + buf, + total_len: 0u32 as u64, + }; + let p: Box<[streaming_types::state_32]> = vec![s].into_boxed_slice(); + p +} + +/** +Copies the state passed as argument into a newly allocated state (deep copy). +The state is to be freed by calling `free_256`. Cloning the state this way is +useful, for instance, if your control-flow diverges and you need to feed +more (different) data into the hash in each branch. +*/ +pub fn copy_256(state: &[streaming_types::state_32]) -> Box<[streaming_types::state_32]> { + let block_state0: &[u32] = &(state[0usize]).block_state; + let buf0: &[u8] = &(state[0usize]).buf; + let total_len0: u64 = (state[0usize]).total_len; + let mut buf: Box<[u8]> = vec![0u8; 64usize].into_boxed_slice(); + ((&mut buf)[0usize..64usize]).copy_from_slice(&buf0[0usize..64usize]); + let mut block_state: Box<[u32]> = vec![0u32; 8usize].into_boxed_slice(); + ((&mut block_state)[0usize..8usize]).copy_from_slice(&block_state0[0usize..8usize]); + let s: streaming_types::state_32 = streaming_types::state_32 { + block_state, + buf, + total_len: total_len0, + }; + let p: Box<[streaming_types::state_32]> = vec![s].into_boxed_slice(); + p +} + +/** +Reset an existing state to the initial hash state with empty data. +*/ +pub fn reset_256(state: &mut [streaming_types::state_32]) { + let block_state: &mut [u32] = &mut (state[0usize]).block_state; + crate::hacl::sha256_init(block_state); + let total_len: u64 = 0u32 as u64; + (state[0usize]).total_len = total_len +} + +#[inline] +fn update_224_256( + state: &mut [streaming_types::state_32], + chunk: &[u8], + chunk_len: u32, +) -> streaming_types::error_code { + let block_state: &mut [u32] = &mut (state[0usize]).block_state; + let total_len: u64 = (state[0usize]).total_len; + if chunk_len as u64 > 2305843009213693951u64.wrapping_sub(total_len) { + streaming_types::error_code::MaximumLengthExceeded + } else { + let sz: u32 = if total_len.wrapping_rem(64u32 as u64) == 0u64 && total_len > 0u64 { + 64u32 + } else { + total_len.wrapping_rem(64u32 as u64) as u32 + }; + if chunk_len <= 64u32.wrapping_sub(sz) { + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(64u32 as u64) == 0u64 && total_len1 > 0u64 { + 64u32 + } else { + total_len1.wrapping_rem(64u32 as u64) as u32 + }; + let buf2: (&mut [u8], &mut [u8]) = buf.split_at_mut(sz1 as usize); + (buf2.1[0usize..chunk_len as usize]) + .copy_from_slice(&chunk[0usize..chunk_len as usize]); + let total_len2: u64 = total_len1.wrapping_add(chunk_len as u64); + (state[0usize]).total_len = total_len2 + } else if sz == 0u32 { + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(64u32 as u64) == 0u64 && total_len1 > 0u64 { + 64u32 + } else { + total_len1.wrapping_rem(64u32 as u64) as u32 + }; + if sz1 != 0u32 { + crate::hacl::sha256_update_nblocks(64u32, buf, block_state) + }; + let ite: u32 = if (chunk_len as u64).wrapping_rem(64u32 as u64) == 0u64 + && chunk_len as u64 > 0u64 + { + 64u32 + } else { + (chunk_len as u64).wrapping_rem(64u32 as u64) as u32 + }; + let n_blocks: u32 = chunk_len.wrapping_sub(ite).wrapping_div(64u32); + let data1_len: u32 = n_blocks.wrapping_mul(64u32); + let data2_len: u32 = chunk_len.wrapping_sub(data1_len); + let data1: (&[u8], &[u8]) = chunk.split_at(0usize); + let data2: (&[u8], &[u8]) = data1.1.split_at(data1_len as usize); + crate::hacl::sha256_update_nblocks( + data1_len.wrapping_div(64u32).wrapping_mul(64u32), + data2.0, + block_state, + ); + let dst: (&mut [u8], &mut [u8]) = buf.split_at_mut(0usize); + (dst.1[0usize..data2_len as usize]) + .copy_from_slice(&data2.1[0usize..data2_len as usize]); + (state[0usize]).total_len = total_len1.wrapping_add(chunk_len as u64) + } else { + let diff: u32 = 64u32.wrapping_sub(sz); + let chunk1: (&[u8], &[u8]) = chunk.split_at(0usize); + let chunk2: (&[u8], &[u8]) = chunk1.1.split_at(diff as usize); + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(64u32 as u64) == 0u64 && total_len1 > 0u64 { + 64u32 + } else { + total_len1.wrapping_rem(64u32 as u64) as u32 + }; + let buf2: (&mut [u8], &mut [u8]) = buf.split_at_mut(sz1 as usize); + (buf2.1[0usize..diff as usize]).copy_from_slice(&chunk2.0[0usize..diff as usize]); + let total_len2: u64 = total_len1.wrapping_add(diff as u64); + (state[0usize]).total_len = total_len2; + let buf0: &mut [u8] = &mut (state[0usize]).buf; + let total_len10: u64 = (state[0usize]).total_len; + let sz10: u32 = if total_len10.wrapping_rem(64u32 as u64) == 0u64 && total_len10 > 0u64 + { + 64u32 + } else { + total_len10.wrapping_rem(64u32 as u64) as u32 + }; + if sz10 != 0u32 { + crate::hacl::sha256_update_nblocks(64u32, buf0, block_state) + }; + let ite: u32 = if (chunk_len.wrapping_sub(diff) as u64).wrapping_rem(64u32 as u64) + == 0u64 + && chunk_len.wrapping_sub(diff) as u64 > 0u64 + { + 64u32 + } else { + (chunk_len.wrapping_sub(diff) as u64).wrapping_rem(64u32 as u64) as u32 + }; + let n_blocks: u32 = chunk_len + .wrapping_sub(diff) + .wrapping_sub(ite) + .wrapping_div(64u32); + let data1_len: u32 = n_blocks.wrapping_mul(64u32); + let data2_len: u32 = chunk_len.wrapping_sub(diff).wrapping_sub(data1_len); + let data1: (&[u8], &[u8]) = chunk2.1.split_at(0usize); + let data2: (&[u8], &[u8]) = data1.1.split_at(data1_len as usize); + crate::hacl::sha256_update_nblocks( + data1_len.wrapping_div(64u32).wrapping_mul(64u32), + data2.0, + block_state, + ); + let dst: (&mut [u8], &mut [u8]) = buf0.split_at_mut(0usize); + (dst.1[0usize..data2_len as usize]) + .copy_from_slice(&data2.1[0usize..data2_len as usize]); + (state[0usize]).total_len = + total_len10.wrapping_add(chunk_len.wrapping_sub(diff) as u64) + }; + streaming_types::error_code::Success + } +} + +/** +Feed an arbitrary amount of data into the hash. This function returns 0 for +success, or 1 if the combined length of all of the data passed to `update_256` +(since the last call to `reset_256`) exceeds 2^61-1 bytes. + +This function is identical to the update function for SHA2_224. +*/ +pub fn update_256( + state: &mut [streaming_types::state_32], + input: &[u8], + input_len: u32, +) -> streaming_types::error_code { + crate::hacl::update_224_256(state, input, input_len) +} + +/** +Write the resulting hash into `output`, an array of 32 bytes. The state remains +valid after a call to `digest_256`, meaning the user may feed more data into +the hash via `update_256`. (The digest_256 function operates on an internal copy of +the state and therefore does not invalidate the client-held state `p`.) +*/ +pub fn digest_256(state: &[streaming_types::state_32], output: &mut [u8]) { + let block_state: &[u32] = &(state[0usize]).block_state; + let buf_: &[u8] = &(state[0usize]).buf; + let total_len: u64 = (state[0usize]).total_len; + let r: u32 = if total_len.wrapping_rem(64u32 as u64) == 0u64 && total_len > 0u64 { + 64u32 + } else { + total_len.wrapping_rem(64u32 as u64) as u32 + }; + let buf_1: (&[u8], &[u8]) = buf_.split_at(0usize); + let mut tmp_block_state: [u32; 8] = [0u32; 8usize]; + ((&mut tmp_block_state)[0usize..8usize]).copy_from_slice(&block_state[0usize..8usize]); + let buf_multi: (&[u8], &[u8]) = buf_1.1.split_at(0usize); + let ite: u32 = if r.wrapping_rem(64u32) == 0u32 && r > 0u32 { + 64u32 + } else { + r.wrapping_rem(64u32) + }; + let buf_last: (&[u8], &[u8]) = buf_multi.1.split_at(r.wrapping_sub(ite) as usize); + crate::hacl::sha256_update_nblocks(0u32, buf_last.0, &mut tmp_block_state); + let prev_len_last: u64 = total_len.wrapping_sub(r as u64); + crate::hacl::sha256_update_last( + prev_len_last.wrapping_add(r as u64), + r, + buf_last.1, + &mut tmp_block_state, + ); + crate::hacl::sha256_finish(&tmp_block_state, output) +} + +/** +Hash `input`, of len `input_len`, into `output`, an array of 32 bytes. +*/ +pub fn hash_256(output: &mut [u8], input: &[u8], input_len: u32) { + let ib: &[u8] = input; + let rb: &mut [u8] = output; + let mut st: [u32; 8] = [0u32; 8usize]; + crate::hacl::sha256_init(&mut st); + let rem: u32 = input_len.wrapping_rem(64u32); + let len·: u64 = input_len as u64; + crate::hacl::sha256_update_nblocks(input_len, ib, &mut st); + let rem1: u32 = input_len.wrapping_rem(64u32); + let b0: &[u8] = ib; + let lb: (&[u8], &[u8]) = b0.split_at(input_len.wrapping_sub(rem1) as usize); + crate::hacl::sha256_update_last(len·, rem, lb.1, &mut st); + crate::hacl::sha256_finish(&st, rb) +} + +pub fn malloc_224() -> Box<[streaming_types::state_32]> { + let buf: Box<[u8]> = vec![0u8; 64usize].into_boxed_slice(); + let mut block_state: Box<[u32]> = vec![0u32; 8usize].into_boxed_slice(); + crate::hacl::sha224_init(&mut block_state); + let s: streaming_types::state_32 = streaming_types::state_32 { + block_state, + buf, + total_len: 0u32 as u64, + }; + let p: Box<[streaming_types::state_32]> = vec![s].into_boxed_slice(); + p +} + +pub fn reset_224(state: &mut [streaming_types::state_32]) { + let block_state: &mut [u32] = &mut (state[0usize]).block_state; + crate::hacl::sha224_init(block_state); + let total_len: u64 = 0u32 as u64; + (state[0usize]).total_len = total_len +} + +pub fn update_224( + state: &mut [streaming_types::state_32], + input: &[u8], + input_len: u32, +) -> streaming_types::error_code { + crate::hacl::update_224_256(state, input, input_len) +} + +/** +Write the resulting hash into `output`, an array of 28 bytes. The state remains +valid after a call to `digest_224`, meaning the user may feed more data into +the hash via `update_224`. +*/ +pub fn digest_224(state: &[streaming_types::state_32], output: &mut [u8]) { + let block_state: &[u32] = &(state[0usize]).block_state; + let buf_: &[u8] = &(state[0usize]).buf; + let total_len: u64 = (state[0usize]).total_len; + let r: u32 = if total_len.wrapping_rem(64u32 as u64) == 0u64 && total_len > 0u64 { + 64u32 + } else { + total_len.wrapping_rem(64u32 as u64) as u32 + }; + let buf_1: (&[u8], &[u8]) = buf_.split_at(0usize); + let mut tmp_block_state: [u32; 8] = [0u32; 8usize]; + ((&mut tmp_block_state)[0usize..8usize]).copy_from_slice(&block_state[0usize..8usize]); + let buf_multi: (&[u8], &[u8]) = buf_1.1.split_at(0usize); + let ite: u32 = if r.wrapping_rem(64u32) == 0u32 && r > 0u32 { + 64u32 + } else { + r.wrapping_rem(64u32) + }; + let buf_last: (&[u8], &[u8]) = buf_multi.1.split_at(r.wrapping_sub(ite) as usize); + crate::hacl::sha224_update_nblocks(0u32, buf_last.0, &mut tmp_block_state); + let prev_len_last: u64 = total_len.wrapping_sub(r as u64); + crate::hacl::sha224_update_last( + prev_len_last.wrapping_add(r as u64), + r, + buf_last.1, + &mut tmp_block_state, + ); + crate::hacl::sha224_finish(&tmp_block_state, output) +} + +/** +Hash `input`, of len `input_len`, into `output`, an array of 28 bytes. +*/ +pub fn hash_224(output: &mut [u8], input: &[u8], input_len: u32) { + let ib: &[u8] = input; + let rb: &mut [u8] = output; + let mut st: [u32; 8] = [0u32; 8usize]; + crate::hacl::sha224_init(&mut st); + let rem: u32 = input_len.wrapping_rem(64u32); + let len·: u64 = input_len as u64; + crate::hacl::sha224_update_nblocks(input_len, ib, &mut st); + let rem1: u32 = input_len.wrapping_rem(64u32); + let b0: &[u8] = ib; + let lb: (&[u8], &[u8]) = b0.split_at(input_len.wrapping_sub(rem1) as usize); + crate::hacl::sha224_update_last(len·, rem, lb.1, &mut st); + crate::hacl::sha224_finish(&st, rb) +} + +pub fn malloc_512() -> Box<[streaming_types::state_64]> { + let buf: Box<[u8]> = vec![0u8; 128usize].into_boxed_slice(); + let mut block_state: Box<[u64]> = vec![0u64; 8usize].into_boxed_slice(); + crate::hacl::sha512_init(&mut block_state); + let s: streaming_types::state_64 = streaming_types::state_64 { + block_state, + buf, + total_len: 0u32 as u64, + }; + let p: Box<[streaming_types::state_64]> = vec![s].into_boxed_slice(); + p +} + +/** +Copies the state passed as argument into a newly allocated state (deep copy). +The state is to be freed by calling `free_512`. Cloning the state this way is +useful, for instance, if your control-flow diverges and you need to feed +more (different) data into the hash in each branch. +*/ +pub fn copy_512(state: &[streaming_types::state_64]) -> Box<[streaming_types::state_64]> { + let block_state0: &[u64] = &(state[0usize]).block_state; + let buf0: &[u8] = &(state[0usize]).buf; + let total_len0: u64 = (state[0usize]).total_len; + let mut buf: Box<[u8]> = vec![0u8; 128usize].into_boxed_slice(); + ((&mut buf)[0usize..128usize]).copy_from_slice(&buf0[0usize..128usize]); + let mut block_state: Box<[u64]> = vec![0u64; 8usize].into_boxed_slice(); + ((&mut block_state)[0usize..8usize]).copy_from_slice(&block_state0[0usize..8usize]); + let s: streaming_types::state_64 = streaming_types::state_64 { + block_state, + buf, + total_len: total_len0, + }; + let p: Box<[streaming_types::state_64]> = vec![s].into_boxed_slice(); + p +} + +pub fn reset_512(state: &mut [streaming_types::state_64]) { + let block_state: &mut [u64] = &mut (state[0usize]).block_state; + crate::hacl::sha512_init(block_state); + let total_len: u64 = 0u32 as u64; + (state[0usize]).total_len = total_len +} + +#[inline] +fn update_384_512( + state: &mut [streaming_types::state_64], + chunk: &[u8], + chunk_len: u32, +) -> streaming_types::error_code { + let block_state: &mut [u64] = &mut (state[0usize]).block_state; + let total_len: u64 = (state[0usize]).total_len; + if chunk_len as u64 > 18446744073709551615u64.wrapping_sub(total_len) { + streaming_types::error_code::MaximumLengthExceeded + } else { + let sz: u32 = if total_len.wrapping_rem(128u32 as u64) == 0u64 && total_len > 0u64 { + 128u32 + } else { + total_len.wrapping_rem(128u32 as u64) as u32 + }; + if chunk_len <= 128u32.wrapping_sub(sz) { + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(128u32 as u64) == 0u64 && total_len1 > 0u64 { + 128u32 + } else { + total_len1.wrapping_rem(128u32 as u64) as u32 + }; + let buf2: (&mut [u8], &mut [u8]) = buf.split_at_mut(sz1 as usize); + (buf2.1[0usize..chunk_len as usize]) + .copy_from_slice(&chunk[0usize..chunk_len as usize]); + let total_len2: u64 = total_len1.wrapping_add(chunk_len as u64); + (state[0usize]).total_len = total_len2 + } else if sz == 0u32 { + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(128u32 as u64) == 0u64 && total_len1 > 0u64 { + 128u32 + } else { + total_len1.wrapping_rem(128u32 as u64) as u32 + }; + if sz1 != 0u32 { + crate::hacl::sha512_update_nblocks(128u32, buf, block_state) + }; + let ite: u32 = if (chunk_len as u64).wrapping_rem(128u32 as u64) == 0u64 + && chunk_len as u64 > 0u64 + { + 128u32 + } else { + (chunk_len as u64).wrapping_rem(128u32 as u64) as u32 + }; + let n_blocks: u32 = chunk_len.wrapping_sub(ite).wrapping_div(128u32); + let data1_len: u32 = n_blocks.wrapping_mul(128u32); + let data2_len: u32 = chunk_len.wrapping_sub(data1_len); + let data1: (&[u8], &[u8]) = chunk.split_at(0usize); + let data2: (&[u8], &[u8]) = data1.1.split_at(data1_len as usize); + crate::hacl::sha512_update_nblocks( + data1_len.wrapping_div(128u32).wrapping_mul(128u32), + data2.0, + block_state, + ); + let dst: (&mut [u8], &mut [u8]) = buf.split_at_mut(0usize); + (dst.1[0usize..data2_len as usize]) + .copy_from_slice(&data2.1[0usize..data2_len as usize]); + (state[0usize]).total_len = total_len1.wrapping_add(chunk_len as u64) + } else { + let diff: u32 = 128u32.wrapping_sub(sz); + let chunk1: (&[u8], &[u8]) = chunk.split_at(0usize); + let chunk2: (&[u8], &[u8]) = chunk1.1.split_at(diff as usize); + let buf: &mut [u8] = &mut (state[0usize]).buf; + let total_len1: u64 = (state[0usize]).total_len; + let sz1: u32 = if total_len1.wrapping_rem(128u32 as u64) == 0u64 && total_len1 > 0u64 { + 128u32 + } else { + total_len1.wrapping_rem(128u32 as u64) as u32 + }; + let buf2: (&mut [u8], &mut [u8]) = buf.split_at_mut(sz1 as usize); + (buf2.1[0usize..diff as usize]).copy_from_slice(&chunk2.0[0usize..diff as usize]); + let total_len2: u64 = total_len1.wrapping_add(diff as u64); + (state[0usize]).total_len = total_len2; + let buf0: &mut [u8] = &mut (state[0usize]).buf; + let total_len10: u64 = (state[0usize]).total_len; + let sz10: u32 = if total_len10.wrapping_rem(128u32 as u64) == 0u64 && total_len10 > 0u64 + { + 128u32 + } else { + total_len10.wrapping_rem(128u32 as u64) as u32 + }; + if sz10 != 0u32 { + crate::hacl::sha512_update_nblocks(128u32, buf0, block_state) + }; + let ite: u32 = if (chunk_len.wrapping_sub(diff) as u64).wrapping_rem(128u32 as u64) + == 0u64 + && chunk_len.wrapping_sub(diff) as u64 > 0u64 + { + 128u32 + } else { + (chunk_len.wrapping_sub(diff) as u64).wrapping_rem(128u32 as u64) as u32 + }; + let n_blocks: u32 = chunk_len + .wrapping_sub(diff) + .wrapping_sub(ite) + .wrapping_div(128u32); + let data1_len: u32 = n_blocks.wrapping_mul(128u32); + let data2_len: u32 = chunk_len.wrapping_sub(diff).wrapping_sub(data1_len); + let data1: (&[u8], &[u8]) = chunk2.1.split_at(0usize); + let data2: (&[u8], &[u8]) = data1.1.split_at(data1_len as usize); + crate::hacl::sha512_update_nblocks( + data1_len.wrapping_div(128u32).wrapping_mul(128u32), + data2.0, + block_state, + ); + let dst: (&mut [u8], &mut [u8]) = buf0.split_at_mut(0usize); + (dst.1[0usize..data2_len as usize]) + .copy_from_slice(&data2.1[0usize..data2_len as usize]); + (state[0usize]).total_len = + total_len10.wrapping_add(chunk_len.wrapping_sub(diff) as u64) + }; + streaming_types::error_code::Success + } +} + +/** +Feed an arbitrary amount of data into the hash. This function returns 0 for +success, or 1 if the combined length of all of the data passed to `update_512` +(since the last call to `reset_512`) exceeds 2^125-1 bytes. + +This function is identical to the update function for SHA2_384. +*/ +pub fn update_512( + state: &mut [streaming_types::state_64], + input: &[u8], + input_len: u32, +) -> streaming_types::error_code { + crate::hacl::update_384_512(state, input, input_len) +} + +/** +Write the resulting hash into `output`, an array of 64 bytes. The state remains +valid after a call to `digest_512`, meaning the user may feed more data into +the hash via `update_512`. (The digest_512 function operates on an internal copy of +the state and therefore does not invalidate the client-held state `p`.) +*/ +pub fn digest_512(state: &[streaming_types::state_64], output: &mut [u8]) { + let block_state: &[u64] = &(state[0usize]).block_state; + let buf_: &[u8] = &(state[0usize]).buf; + let total_len: u64 = (state[0usize]).total_len; + let r: u32 = if total_len.wrapping_rem(128u32 as u64) == 0u64 && total_len > 0u64 { + 128u32 + } else { + total_len.wrapping_rem(128u32 as u64) as u32 + }; + let buf_1: (&[u8], &[u8]) = buf_.split_at(0usize); + let mut tmp_block_state: [u64; 8] = [0u64; 8usize]; + ((&mut tmp_block_state)[0usize..8usize]).copy_from_slice(&block_state[0usize..8usize]); + let buf_multi: (&[u8], &[u8]) = buf_1.1.split_at(0usize); + let ite: u32 = if r.wrapping_rem(128u32) == 0u32 && r > 0u32 { + 128u32 + } else { + r.wrapping_rem(128u32) + }; + let buf_last: (&[u8], &[u8]) = buf_multi.1.split_at(r.wrapping_sub(ite) as usize); + crate::hacl::sha512_update_nblocks(0u32, buf_last.0, &mut tmp_block_state); + let prev_len_last: u64 = total_len.wrapping_sub(r as u64); + crate::hacl::sha512_update_last( + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(prev_len_last), + fstar::uint128::uint64_to_uint128(r as u64), + ), + r, + buf_last.1, + &mut tmp_block_state, + ); + crate::hacl::sha512_finish(&tmp_block_state, output) +} + +/** +Hash `input`, of len `input_len`, into `output`, an array of 64 bytes. +*/ +pub fn hash_512(output: &mut [u8], input: &[u8], input_len: u32) { + let ib: &[u8] = input; + let rb: &mut [u8] = output; + let mut st: [u64; 8] = [0u64; 8usize]; + crate::hacl::sha512_init(&mut st); + let rem: u32 = input_len.wrapping_rem(128u32); + let len·: fstar::uint128::uint128 = fstar::uint128::uint64_to_uint128(input_len as u64); + crate::hacl::sha512_update_nblocks(input_len, ib, &mut st); + let rem1: u32 = input_len.wrapping_rem(128u32); + let b0: &[u8] = ib; + let lb: (&[u8], &[u8]) = b0.split_at(input_len.wrapping_sub(rem1) as usize); + crate::hacl::sha512_update_last(len·, rem, lb.1, &mut st); + crate::hacl::sha512_finish(&st, rb) +} + +pub fn malloc_384() -> Box<[streaming_types::state_64]> { + let buf: Box<[u8]> = vec![0u8; 128usize].into_boxed_slice(); + let mut block_state: Box<[u64]> = vec![0u64; 8usize].into_boxed_slice(); + crate::hacl::sha384_init(&mut block_state); + let s: streaming_types::state_64 = streaming_types::state_64 { + block_state, + buf, + total_len: 0u32 as u64, + }; + let p: Box<[streaming_types::state_64]> = vec![s].into_boxed_slice(); + p +} + +pub fn reset_384(state: &mut [streaming_types::state_64]) { + let block_state: &mut [u64] = &mut (state[0usize]).block_state; + crate::hacl::sha384_init(block_state); + let total_len: u64 = 0u32 as u64; + (state[0usize]).total_len = total_len +} + +pub fn update_384( + state: &mut [streaming_types::state_64], + input: &[u8], + input_len: u32, +) -> streaming_types::error_code { + crate::hacl::update_384_512(state, input, input_len) +} + +/** +Write the resulting hash into `output`, an array of 48 bytes. The state remains +valid after a call to `digest_384`, meaning the user may feed more data into +the hash via `update_384`. +*/ +pub fn digest_384(state: &[streaming_types::state_64], output: &mut [u8]) { + let block_state: &[u64] = &(state[0usize]).block_state; + let buf_: &[u8] = &(state[0usize]).buf; + let total_len: u64 = (state[0usize]).total_len; + let r: u32 = if total_len.wrapping_rem(128u32 as u64) == 0u64 && total_len > 0u64 { + 128u32 + } else { + total_len.wrapping_rem(128u32 as u64) as u32 + }; + let buf_1: (&[u8], &[u8]) = buf_.split_at(0usize); + let mut tmp_block_state: [u64; 8] = [0u64; 8usize]; + ((&mut tmp_block_state)[0usize..8usize]).copy_from_slice(&block_state[0usize..8usize]); + let buf_multi: (&[u8], &[u8]) = buf_1.1.split_at(0usize); + let ite: u32 = if r.wrapping_rem(128u32) == 0u32 && r > 0u32 { + 128u32 + } else { + r.wrapping_rem(128u32) + }; + let buf_last: (&[u8], &[u8]) = buf_multi.1.split_at(r.wrapping_sub(ite) as usize); + crate::hacl::sha384_update_nblocks(0u32, buf_last.0, &mut tmp_block_state); + let prev_len_last: u64 = total_len.wrapping_sub(r as u64); + crate::hacl::sha384_update_last( + fstar::uint128::add( + fstar::uint128::uint64_to_uint128(prev_len_last), + fstar::uint128::uint64_to_uint128(r as u64), + ), + r, + buf_last.1, + &mut tmp_block_state, + ); + crate::hacl::sha384_finish(&tmp_block_state, output) +} + +/** +Hash `input`, of len `input_len`, into `output`, an array of 48 bytes. +*/ +pub fn hash_384(output: &mut [u8], input: &[u8], input_len: u32) { + let ib: &[u8] = input; + let rb: &mut [u8] = output; + let mut st: [u64; 8] = [0u64; 8usize]; + crate::hacl::sha384_init(&mut st); + let rem: u32 = input_len.wrapping_rem(128u32); + let len·: fstar::uint128::uint128 = fstar::uint128::uint64_to_uint128(input_len as u64); + crate::hacl::sha384_update_nblocks(input_len, ib, &mut st); + let rem1: u32 = input_len.wrapping_rem(128u32); + let b0: &[u8] = ib; + let lb: (&[u8], &[u8]) = b0.split_at(input_len.wrapping_sub(rem1) as usize); + crate::hacl::sha384_update_last(len·, rem, lb.1, &mut st); + crate::hacl::sha384_finish(&st, rb) +} diff --git a/sha2/src/impl_hacl.rs b/sha2/src/impl_hacl.rs new file mode 100644 index 000000000..134cf544c --- /dev/null +++ b/sha2/src/impl_hacl.rs @@ -0,0 +1,147 @@ +use super::*; +use libcrux_traits::Digest; + +/// SHA2 224 +/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can +/// process it. +pub fn sha224(payload: &[u8]) -> [u8; SHA224_LENGTH] { + let mut digest = [0u8; SHA224_LENGTH]; + Sha224::hash(&mut digest, payload); + digest +} + +/// SHA2 256 +/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can +/// process it. +pub fn sha256(payload: &[u8]) -> [u8; SHA256_LENGTH] { + let mut digest = [0u8; SHA256_LENGTH]; + Sha256::hash(&mut digest, payload); + digest +} + +/// SHA2 384 +/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can +/// process it. +pub fn sha384(payload: &[u8]) -> [u8; SHA384_LENGTH] { + let mut digest = [0u8; SHA384_LENGTH]; + Sha384::hash(&mut digest, payload); + digest +} + +/// SHA2 512 +/// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can +/// process it. +pub fn sha512(payload: &[u8]) -> [u8; SHA512_LENGTH] { + let mut digest = [0u8; SHA512_LENGTH]; + Sha512::hash(&mut digest, payload); + digest +} + +// Streaming API - This is the recommended one. +// For implementations based on hacl_rs (over hacl-c) +macro_rules! impl_hash { + ($name:ident, $digest_size:literal, $state:ty, $malloc:expr, $reset:expr, $update:expr, $finish:expr, $copy:expr, $hash:expr) => { + #[allow(non_camel_case_types)] + pub struct $name { + state: $state, + } + + impl $name { + /// Initialize a new digest state for streaming use. + pub fn new() -> $name { + $name { state: $malloc() } + } + } + + impl libcrux_traits::Digest<$digest_size> for $name { + /// Return the digest for the given input byte slice, in immediate mode. + /// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can + /// process it. + fn hash(digest: &mut [u8; $digest_size], payload: &[u8]) { + let payload_len = payload.len().try_into().unwrap(); + $hash(digest, payload, payload_len) + } + + /// Add the `payload` to the digest. + /// Will panic if `payload` is longer than `u32::MAX` to ensure that hacl-rs can + /// process it. + fn update(&mut self, payload: &[u8]) { + let payload_len = payload.len().try_into().unwrap(); + $update(self.state.as_mut(), payload, payload_len); + } + + /// Get the digest. + /// + /// Note that the digest state can be continued to be used, to extend the + /// digest. + fn finish(&self, digest: &mut [u8; $digest_size]) { + $finish(self.state.as_ref(), digest); + } + + /// Reset the digest state. + fn reset(&mut self) { + $reset(self.state.as_mut()); + } + } + + impl Default for $name { + fn default() -> Self { + Self::new() + } + } + + impl Clone for $name { + fn clone(&self) -> Self { + Self { + state: $copy(self.state.as_ref()), + } + } + } + }; +} + +impl_hash!( + Sha256, + 32, + Box<[libcrux_hacl_rs::streaming_types::state_32]>, + crate::hacl::malloc_256, + crate::hacl::reset_256, + crate::hacl::update_256, + crate::hacl::digest_256, + crate::hacl::copy_256, + crate::hacl::hash_256 +); +impl_hash!( + Sha224, + 28, + Box<[libcrux_hacl_rs::streaming_types::state_32]>, + crate::hacl::malloc_224, + crate::hacl::reset_224, + crate::hacl::update_224, + crate::hacl::digest_224, + crate::hacl::copy_256, + crate::hacl::hash_224 +); + +impl_hash!( + Sha512, + 64, + Box<[libcrux_hacl_rs::streaming_types::state_64]>, + crate::hacl::malloc_512, + crate::hacl::reset_512, + crate::hacl::update_512, + crate::hacl::digest_512, + crate::hacl::copy_512, + crate::hacl::hash_512 +); +impl_hash!( + Sha384, + 48, + Box<[libcrux_hacl_rs::streaming_types::state_64]>, + crate::hacl::malloc_384, + crate::hacl::reset_384, + crate::hacl::update_384, + crate::hacl::digest_384, + crate::hacl::copy_512, + crate::hacl::hash_384 +); diff --git a/sha2/src/lib.rs b/sha2/src/lib.rs new file mode 100644 index 000000000..04264820e --- /dev/null +++ b/sha2/src/lib.rs @@ -0,0 +1,23 @@ +/// The length of a SHA224 hash in bytes. +pub const SHA224_LENGTH: usize = 28; + +/// The length of a SHA256 hash in bytes. +pub const SHA256_LENGTH: usize = 32; + +/// The length of a SHA384 hash in bytes. +pub const SHA384_LENGTH: usize = 48; + +/// The length of a SHA512 hash in bytes. +pub const SHA512_LENGTH: usize = 64; + +/// The generated hacl code +#[cfg(feature = "hacl")] +pub mod hacl; + +/// The implementation of our types using that hacl code +#[cfg(feature = "hacl")] +mod impl_hacl; + +/// use it if we want to use hacl +#[cfg(feature = "portable_hacl")] +pub use impl_hacl::*; diff --git a/src/digest.rs b/src/digest.rs index 3f8dc4a4e..dd60390e1 100644 --- a/src/digest.rs +++ b/src/digest.rs @@ -13,14 +13,7 @@ //! On x64 CPUs the libjade implementation is used and if AVX2 is available, the //! optimised libjade implementation is used. -use crate::hacl::{ - blake2, - sha2::{ - self, - streaming::{Sha224, Sha256, Sha384, Sha512}, - }, - sha3, -}; +use crate::hacl::{blake2, sha3}; use libcrux_platform::{simd128_support, simd256_support}; @@ -179,10 +172,10 @@ pub fn hash(alg: Algorithm, payload: &[u8]) -> Vec { // So we only use streaming. match alg { Algorithm::Sha1 => todo!(), - Algorithm::Sha224 => sha2::sha224(payload).into(), - Algorithm::Sha256 => sha2::sha256(payload).into(), - Algorithm::Sha384 => sha2::sha384(payload).into(), - Algorithm::Sha512 => sha2::sha512(payload).into(), + Algorithm::Sha224 => sha2_224(payload).into(), + Algorithm::Sha256 => sha2_256(payload).into(), + Algorithm::Sha384 => sha2_384(payload).into(), + Algorithm::Sha512 => sha2_512(payload).into(), Algorithm::Blake2s => blake2s(payload, &[]), Algorithm::Blake2b => blake2b(payload, &[]), Algorithm::Sha3_224 => sha3_224(payload).into(), @@ -234,66 +227,16 @@ fn blake2b(payload: &[u8], key: &[u8]) -> Vec { .into() } -/// SHA2 224 -pub fn sha2_224(payload: &[u8]) -> Sha2_224Digest { - sha2::sha224(payload) -} - -/// SHA2 256 -pub fn sha2_256(payload: &[u8]) -> Sha2_256Digest { - sha2::sha256(payload) -} - -/// SHA2 384 -pub fn sha2_384(payload: &[u8]) -> Sha2_384Digest { - sha2::sha384(payload) -} - -/// SHA2 512 -pub fn sha2_512(payload: &[u8]) -> Sha2_512Digest { - sha2::sha512(payload) -} - -// Streaming API - This is the recommended one. -macro_rules! impl_streaming { - ($name:ident, $state:ty, $result:ty) => { - #[derive(Clone)] - pub struct $name { - state: $state, - } - impl $name { - /// Initialize a new digest state. - pub fn new() -> Self { - Self { - state: <$state>::new(), - } - } +// import SHA2 +pub use libcrux_sha2::sha224 as sha2_224; +pub use libcrux_sha2::sha256 as sha2_256; +pub use libcrux_sha2::sha384 as sha2_384; +pub use libcrux_sha2::sha512 as sha2_512; - /// Add the `payload` to the digest. - pub fn update(&mut self, payload: &[u8]) { - self.state.update(payload); - } - - /// Get the digest. - /// - /// Note that the digest state can be continued to be used, to extend the - /// digest. - pub fn finish(&mut self) -> $result { - self.state.finish() - } - } - - impl Default for $name { - fn default() -> Self { - Self::new() - } - } - }; -} -impl_streaming!(Sha2_224, Sha224, Sha2_224Digest); -impl_streaming!(Sha2_256, Sha256, Sha2_256Digest); -impl_streaming!(Sha2_384, Sha384, Sha2_384Digest); -impl_streaming!(Sha2_512, Sha512, Sha2_512Digest); +pub use libcrux_sha2::Sha224 as Sha2_224; +pub use libcrux_sha2::Sha256 as Sha2_256; +pub use libcrux_sha2::Sha384 as Sha2_384; +pub use libcrux_sha2::Sha512 as Sha2_512; // SHAKE messages from SHA 3 diff --git a/src/hacl.rs b/src/hacl.rs index 3cd78a864..779b5472d 100644 --- a/src/hacl.rs +++ b/src/hacl.rs @@ -15,10 +15,9 @@ pub(crate) mod chacha20_poly1305; #[cfg(not(target_arch = "wasm32"))] pub(crate) mod drbg; -pub(crate) mod ed25519; +pub(crate) use libcrux_ed25519 as ed25519; pub(crate) mod p256; -pub(crate) mod sha2; pub(crate) mod sha3; /// Unified error type. diff --git a/src/hacl/curve25519.rs b/src/hacl/curve25519.rs deleted file mode 100644 index 8ee631669..000000000 --- a/src/hacl/curve25519.rs +++ /dev/null @@ -1,72 +0,0 @@ -use libcrux_hacl::{Hacl_Curve25519_51_ecdh, Hacl_Curve25519_51_secret_to_public}; - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum Error { - InvalidInput, -} - -/// Compute the ECDH with the `private_key` and `public_key`. -/// -/// Returns the 32 bytes shared key. -#[inline(always)] -pub fn ecdh( - private_key: impl AsRef<[u8; 32]>, - public_key: impl AsRef<[u8; 32]>, -) -> Result<[u8; 32], Error> { - let mut shared = [0u8; 32]; - let ok = unsafe { - Hacl_Curve25519_51_ecdh( - shared.as_mut_ptr(), - private_key.as_ref().as_ptr() as _, - public_key.as_ref().as_ptr() as _, - ) - }; - if !ok { - Err(Error::InvalidInput) - } else { - Ok(shared) - } -} - -/// Compute the public key for the provided `private_key` (scalar multiplication -/// with the base point). -/// -/// Returns the 32 bytes shared key. -#[must_use] -#[inline(always)] -pub fn secret_to_public(private_key: impl AsRef<[u8; 32]>) -> [u8; 32] { - let mut public = [0u8; 32]; - unsafe { - Hacl_Curve25519_51_secret_to_public(public.as_mut_ptr(), private_key.as_ref().as_ptr() as _) - }; - public -} - -#[cfg(all(bmi2, adx, target_arch = "x86_64"))] -pub mod vale { - use super::Error; - use libcrux_hacl::Hacl_Curve25519_64_ecdh; - - /// Compute the ECDH with the `private_key` and `public_key`. - /// - /// Returns the 32 bytes shared key. - #[inline(always)] - pub fn ecdh( - private_key: impl AsRef<[u8; 32]>, - public_key: impl AsRef<[u8; 32]>, - ) -> Result<[u8; 32], Error> { - let mut shared = [0u8; 32]; - let ok = unsafe { - Hacl_Curve25519_64_ecdh( - shared.as_mut_ptr(), - private_key.as_ref().as_ptr() as _, - public_key.as_ref().as_ptr() as _, - ) - }; - if !ok { - Err(Error::InvalidInput) - } else { - Ok(shared) - } - } -} diff --git a/src/hacl/ed25519.rs b/src/hacl/ed25519.rs deleted file mode 100644 index 1df534b6a..000000000 --- a/src/hacl/ed25519.rs +++ /dev/null @@ -1,45 +0,0 @@ -use libcrux_hacl::{Hacl_Ed25519_secret_to_public, Hacl_Ed25519_sign, Hacl_Ed25519_verify}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Error { - SigningError, - InvalidSignature, -} - -pub fn sign(payload: &[u8], private_key: &[u8; 32]) -> Result<[u8; 64], Error> { - let mut signature = [0u8; 64]; - unsafe { - Hacl_Ed25519_sign( - signature.as_mut_ptr(), - private_key.as_ptr() as _, - payload.len().try_into().map_err(|_| Error::SigningError)?, - payload.as_ptr() as _, - ); - } - - Ok(signature) -} - -pub fn verify(payload: &[u8], public_key: &[u8; 32], signature: &[u8; 64]) -> Result<(), Error> { - if unsafe { - Hacl_Ed25519_verify( - public_key.as_ptr() as _, - payload.len().try_into().map_err(|_| Error::SigningError)?, - payload.as_ptr() as _, - signature.as_ptr() as _, - ) - } { - Ok(()) - } else { - Err(Error::InvalidSignature) - } -} - -/// Compute the public point for the given secret key `sk`. -pub fn secret_to_public(sk: &[u8; 32]) -> [u8; 32] { - let mut out = [0u8; 32]; - unsafe { - Hacl_Ed25519_secret_to_public(out.as_mut_ptr(), sk.as_ptr() as _); - } - out -} diff --git a/src/hacl/sha2.rs b/src/hacl/sha2.rs deleted file mode 100644 index c824e2783..000000000 --- a/src/hacl/sha2.rs +++ /dev/null @@ -1,185 +0,0 @@ -use libcrux_hacl::{ - Hacl_Hash_SHA2_hash_224, Hacl_Hash_SHA2_hash_256, Hacl_Hash_SHA2_hash_384, - Hacl_Hash_SHA2_hash_512, -}; - -/// SHA2 224 -/// -/// Note the function panics when `payload` is larger than 2^32 bytes. -pub fn sha224(payload: &[u8]) -> [u8; 28] { - let mut digest = [0u8; 28]; - unsafe { - Hacl_Hash_SHA2_hash_224( - digest.as_mut_ptr(), - payload.as_ptr() as _, - payload.len().try_into().unwrap(), - ); - } - digest -} - -/// SHA2 256 -/// -/// Note the function panics when `payload` is larger than 2^32 bytes. -pub fn sha256(payload: &[u8]) -> [u8; 32] { - let mut digest = [0u8; 32]; - unsafe { - Hacl_Hash_SHA2_hash_256( - digest.as_mut_ptr(), - payload.as_ptr() as _, - payload.len().try_into().unwrap(), - ); - } - digest -} - -/// SHA2 384 -/// -/// Note the function panics when `payload` is larger than 2^32 bytes. -pub fn sha384(payload: &[u8]) -> [u8; 48] { - let mut digest = [0u8; 48]; - unsafe { - Hacl_Hash_SHA2_hash_384( - digest.as_mut_ptr(), - payload.as_ptr() as _, - payload.len().try_into().unwrap(), - ); - } - digest -} - -/// SHA2 512 -/// -/// Note the function panics when `payload` is larger than 2^32 bytes. -pub fn sha512(payload: &[u8]) -> [u8; 64] { - let mut digest = [0u8; 64]; - unsafe { - Hacl_Hash_SHA2_hash_512( - digest.as_mut_ptr(), - payload.as_ptr() as _, - payload.len().try_into().unwrap(), - ); - } - digest -} - -pub mod streaming { - use libcrux_hacl::{ - Hacl_Hash_SHA2_copy_256, Hacl_Hash_SHA2_copy_512, Hacl_Hash_SHA2_digest_224, - Hacl_Hash_SHA2_digest_256, Hacl_Hash_SHA2_digest_384, Hacl_Hash_SHA2_digest_512, - Hacl_Hash_SHA2_free_224, Hacl_Hash_SHA2_free_256, Hacl_Hash_SHA2_free_384, - Hacl_Hash_SHA2_free_512, Hacl_Hash_SHA2_malloc_224, Hacl_Hash_SHA2_malloc_256, - Hacl_Hash_SHA2_malloc_384, Hacl_Hash_SHA2_malloc_512, Hacl_Hash_SHA2_reset_224, - Hacl_Hash_SHA2_reset_256, Hacl_Hash_SHA2_reset_384, Hacl_Hash_SHA2_reset_512, - Hacl_Hash_SHA2_state_t_224, Hacl_Hash_SHA2_state_t_384, Hacl_Hash_SHA2_update_224, - Hacl_Hash_SHA2_update_256, Hacl_Hash_SHA2_update_384, Hacl_Hash_SHA2_update_512, - }; - - macro_rules! impl_streaming { - ($name:ident, $digest_size:literal, $state:ty, $malloc:expr, $reset:expr, $update:expr, $finish:expr, $free:expr, $copy:expr) => { - pub struct $name { - state: *mut $state, - } - - impl $name { - /// Initialize a new digest state. - pub fn new() -> $name { - let state = $name { - state: unsafe { $malloc() }, - }; - unsafe { $reset(state.state) }; - state - } - - /// Add the `payload` to the digest. - pub fn update(&mut self, payload: &[u8]) { - // Note that we don't really need mut here because the mutability is - // only in unsafe C code. - // But this way we force the borrow checker to do the right thing. - unsafe { $update(self.state, payload.as_ptr() as _, payload.len() as u32) }; - } - - /// Get the digest. - /// - /// Note that the digest state can be continued to be used, to extend the - /// digest. - pub fn finish(&mut self) -> [u8; $digest_size] { - // Note that we don't really need mut here because the mutability is - // only in unsafe C code. - // But this way we force the borrow checker to do the right thing. - let mut digest = [0u8; $digest_size]; - unsafe { - $finish(self.state, digest.as_mut_ptr()); - } - digest - } - } - - impl Drop for $name { - fn drop(&mut self) { - unsafe { $free(self.state) }; - } - } - - impl Clone for $name { - fn clone(&self) -> Self { - unsafe { - Self { - state: $copy(self.state), - } - } - } - } - - unsafe impl Send for $name {} - }; - } - - impl_streaming!( - Sha224, - 28, - Hacl_Hash_SHA2_state_t_224, - Hacl_Hash_SHA2_malloc_224, - Hacl_Hash_SHA2_reset_224, - Hacl_Hash_SHA2_update_224, - Hacl_Hash_SHA2_digest_224, - Hacl_Hash_SHA2_free_224, - Hacl_Hash_SHA2_copy_256 - ); - - impl_streaming!( - Sha256, - 32, - Hacl_Hash_SHA2_state_t_224, - Hacl_Hash_SHA2_malloc_256, - Hacl_Hash_SHA2_reset_256, - Hacl_Hash_SHA2_update_256, - Hacl_Hash_SHA2_digest_256, - Hacl_Hash_SHA2_free_256, - Hacl_Hash_SHA2_copy_256 - ); - - impl_streaming!( - Sha384, - 48, - Hacl_Hash_SHA2_state_t_384, - Hacl_Hash_SHA2_malloc_384, - Hacl_Hash_SHA2_reset_384, - Hacl_Hash_SHA2_update_384, - Hacl_Hash_SHA2_digest_384, - Hacl_Hash_SHA2_free_384, - Hacl_Hash_SHA2_copy_512 - ); - - impl_streaming!( - Sha512, - 64, - Hacl_Hash_SHA2_state_t_384, - Hacl_Hash_SHA2_malloc_512, - Hacl_Hash_SHA2_reset_512, - Hacl_Hash_SHA2_update_512, - Hacl_Hash_SHA2_digest_512, - Hacl_Hash_SHA2_free_512, - Hacl_Hash_SHA2_copy_512 - ); -} diff --git a/src/hpke/hpke.rs b/src/hpke/hpke.rs index 4d6343ed2..455343ec7 100644 --- a/src/hpke/hpke.rs +++ b/src/hpke/hpke.rs @@ -427,7 +427,7 @@ pub fn SetupBaseS( ); let ss = crate::kem::Ss::X25519MlKem768Draft00( ss2.as_slice().try_into().unwrap(), - libcrux_ecdh::X25519PublicKey(ss1.try_into().unwrap()), + libcrux_ecdh::X25519SharedSecret(ss1.try_into().unwrap()), ); (ss.encode(), ct.encode()) } @@ -523,7 +523,7 @@ pub fn SetupBaseR( let ss2 = Kyber768Draft00_Decap(kyber.as_ref(), &enc[32..])?; let ss = crate::kem::Ss::X25519MlKem768Draft00( ss2.as_slice().try_into().unwrap(), - libcrux_ecdh::X25519PublicKey(ss1.try_into().unwrap()), + libcrux_ecdh::X25519SharedSecret(ss1.try_into().unwrap()), ); ss.encode() } diff --git a/src/hpke/kdf.rs b/src/hpke/kdf.rs index dee6f875b..fcce60217 100644 --- a/src/hpke/kdf.rs +++ b/src/hpke/kdf.rs @@ -98,11 +98,10 @@ pub fn LabeledExtract( labeled_ikm.extend_from_slice(&label); labeled_ikm.extend_from_slice(ikm); - Ok(crate::hkdf::extract( - hkdf_algorithm(alg), - salt, - &labeled_ikm, - )) + crate::hkdf::extract(hkdf_algorithm(alg), salt, &labeled_ikm).map_err(|err| match err { + libcrux_hkdf::Error::OkmTooLarge => HpkeError::CryptoError, + libcrux_hkdf::Error::ArgumentsTooLarge => HpkeError::InvalidParameters, + }) } /// KDF: Labeled Expand diff --git a/src/signature.rs b/src/signature.rs index 4a140cccc..b8e7dbd9d 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -481,6 +481,8 @@ pub fn key_gen( Algorithm::Ed25519 => { const LIMIT: usize = 100; let mut sk = [0u8; 32]; + let mut pk = [0u8; 32]; + for _ in 0..LIMIT { rng.try_fill_bytes(&mut sk) .map_err(|_| Error::KeyGenError)?; @@ -498,7 +500,8 @@ pub fn key_gen( break; } - let pk = ed25519::secret_to_public(&sk); + + ed25519::secret_to_public(&mut pk, &sk); Ok((sk.to_vec(), pk.to_vec())) } diff --git a/sys/platform/proofs/fstar/extraction/Libcrux_platform.Platform.fsti b/sys/platform/proofs/fstar/extraction/Libcrux_platform.Platform.fsti index 95dad6932..e8713dad5 100644 --- a/sys/platform/proofs/fstar/extraction/Libcrux_platform.Platform.fsti +++ b/sys/platform/proofs/fstar/extraction/Libcrux_platform.Platform.fsti @@ -1,5 +1,5 @@ module Libcrux_platform.Platform -#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" open Core open FStar.Mul diff --git a/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fst b/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fst deleted file mode 100644 index 0e4db4e49..000000000 --- a/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fst +++ /dev/null @@ -1,69 +0,0 @@ -module Libcrux_platform.X86 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -open Core -open FStar.Mul - -(* item error backend: (reject_Unsafe) ExplicitRejection { reason: "a node of kind [Unsafe] have been found in the AST" } -Last available AST for this item: - -#[inline(never)] -#[inline(always)] -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -#[allow(non_upper_case_globals)] -#[no_std()] -#[feature(register_tool)] -#[register_tool(_hax)] -unsafe fn init__cpuid(leaf: int) -> core::core_arch::x86::cpuid::t_CpuidResult { - rust_primitives::hax::dropped_body -} - - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_platform"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "x86"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "init"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "cpuid"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) - -(* item error backend: (reject_Unsafe) ExplicitRejection { reason: "a node of kind [Unsafe] have been found in the AST" } -Last available AST for this item: - -#[inline(never)] -#[inline(always)] -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -#[allow(non_upper_case_globals)] -#[no_std()] -#[feature(register_tool)] -#[register_tool(_hax)] -unsafe fn init__cpuid_count( - leaf: int, - sub_leaf: int, -) -> core::core_arch::x86::cpuid::t_CpuidResult { - rust_primitives::hax::dropped_body -} - - -Last AST: -/** print_rust: pitem: not implemented (item: { Concrete_ident.T.def_id = - { Concrete_ident.Imported.krate = "libcrux_platform"; - path = - [{ Concrete_ident.Imported.data = (Concrete_ident.Imported.TypeNs "x86"); - disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "init"); disambiguator = 0 }; - { Concrete_ident.Imported.data = - (Concrete_ident.Imported.ValueNs "cpuid_count"); disambiguator = 0 } - ] - }; - kind = Concrete_ident.Kind.Value }) */ -const _: () = (); - *) diff --git a/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fsti b/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fsti index 968a5585c..0b77def1e 100644 --- a/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fsti +++ b/sys/platform/proofs/fstar/extraction/Libcrux_platform.X86.fsti @@ -1,5 +1,5 @@ module Libcrux_platform.X86 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 80" +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" open Core open FStar.Mul diff --git a/sys/pqclean/src/bindings.rs b/sys/pqclean/src/bindings.rs index 5f6602af9..9c1755073 100644 --- a/sys/pqclean/src/bindings.rs +++ b/sys/pqclean/src/bindings.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.69.4 */ +/* automatically generated by rust-bindgen 0.69.5 */ pub const SHAKE128_RATE: u32 = 168; pub const SHAKE256_RATE: u32 = 136; diff --git a/tests/ed25519.rs b/tests/ed25519.rs new file mode 100644 index 000000000..224897143 --- /dev/null +++ b/tests/ed25519.rs @@ -0,0 +1,38 @@ +use libcrux::signature::{Algorithm, Ed25519Signature, Signature}; + +#[test] +fn run_wycheproof() { + for test_name in wycheproof::eddsa::TestName::all() { + let _ = match test_name { + wycheproof::eddsa::TestName::Ed25519 => Algorithm::Ed25519, + _ => continue, + }; + let test_set = wycheproof::eddsa::TestSet::load(test_name) + .expect("error loading wycheproof test for name {test_name}"); + + println!("Test Set {test_name:?}"); + for test_group in test_set.test_groups { + let pk = &test_group.key.pk; + + for (i, test) in test_group.tests.into_iter().enumerate() { + let comment = &test.comment; + println!("Test {i}: {comment}"); + + match test.result { + wycheproof::TestResult::Valid => { + let sig = + Signature::Ed25519(Ed25519Signature::from_slice(&test.sig).unwrap()); + libcrux::signature::verify(&test.msg, &sig, pk).unwrap(); + } + wycheproof::TestResult::Invalid => { + Ed25519Signature::from_slice(&test.sig) + .map(Signature::Ed25519) + .and_then(|sig| libcrux::signature::verify(&test.msg, &sig, pk)) + .expect_err("expected error"); + } + _ => unreachable!(), + } + } + } + } +} diff --git a/tests/hkdf.rs b/tests/hkdf.rs new file mode 100644 index 000000000..9d57cfd8b --- /dev/null +++ b/tests/hkdf.rs @@ -0,0 +1,35 @@ +use libcrux_hkdf::Algorithm; +use wycheproof::TestResult; + +#[test] +fn run_wycheproof() { + for test_name in wycheproof::hkdf::TestName::all() { + let alg = match test_name { + wycheproof::hkdf::TestName::HkdfSha1 => continue, + wycheproof::hkdf::TestName::HkdfSha256 => Algorithm::Sha256, + wycheproof::hkdf::TestName::HkdfSha384 => Algorithm::Sha384, + wycheproof::hkdf::TestName::HkdfSha512 => Algorithm::Sha512, + }; + let test_set = wycheproof::hkdf::TestSet::load(test_name) + .expect("error loading wycheproof test for name {test_name}"); + + println!("Test Set {test_name:?}"); + for test_group in test_set.test_groups { + for (i, test) in test_group.tests.into_iter().enumerate() { + let comment = &test.comment; + println!("Test {i}: {comment}"); + + let result = libcrux_hkdf::hkdf(alg, &test.salt, &test.ikm, &test.info, test.size); + match (result, test.result) { + (Ok(okm), TestResult::Valid) => { + assert_eq!(okm.as_slice(), test.okm.as_ref()) + } + (Err(_), TestResult::Invalid) => {} + other => { + panic!("found failing test case: {test:?}, got {other:?}") + } + } + } + } + } +} diff --git a/tests/hmac.rs b/tests/hmac.rs new file mode 100644 index 000000000..930fae419 --- /dev/null +++ b/tests/hmac.rs @@ -0,0 +1,34 @@ +use libcrux_hmac::Algorithm; + +#[test] +fn run_wycheproof() { + for test_name in wycheproof::mac::TestName::all() { + let alg = match test_name { + wycheproof::mac::TestName::HmacSha1 => Algorithm::Sha1, + wycheproof::mac::TestName::HmacSha256 => Algorithm::Sha256, + wycheproof::mac::TestName::HmacSha384 => Algorithm::Sha384, + wycheproof::mac::TestName::HmacSha512 => Algorithm::Sha512, + _ => continue, + }; + let test_set = wycheproof::mac::TestSet::load(test_name) + .expect("error loading wycheproof test for name {test_name}"); + + println!("Test Set {test_name:?}"); + for test_group in test_set.test_groups { + for (i, test) in test_group.tests.into_iter().enumerate() { + let comment = &test.comment; + println!("Test {i}: {comment}"); + + let tag = libcrux_hmac::hmac(alg, &test.key, &test.msg, Some(test.tag.len())); + + match test.result { + wycheproof::TestResult::Valid => assert_eq!(tag.as_slice(), test.tag.as_ref()), + wycheproof::TestResult::Invalid => { + assert_ne!(tag.as_slice(), test.tag.as_ref()) + } + _ => unreachable!(), + } + } + } + } +} diff --git a/tests/sha2.rs b/tests/sha2.rs index 1e504ff3e..8fab5eb48 100644 --- a/tests/sha2.rs +++ b/tests/sha2.rs @@ -1,14 +1,17 @@ +use libcrux_traits::Digest as _; + // XXX: The tests in here are failing in wasm for some reason. // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] #[test] fn sha256_kat_streaming() { let mut digest = libcrux::digest::Sha2_256::new(); + let mut d = [0u8; 32]; digest.update(b"libcrux sha2 256 tests"); - let d = digest.finish(); + digest.finish(&mut d); let expected = "8683520e19e5b33db33c8fb90918c0c96fcdfd9a17c695ce0f0ea2eaa0c95956"; - assert_eq!(hex::encode(&d), expected); + assert_eq!(hex::encode(d), expected); } // #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)] @@ -17,7 +20,7 @@ fn sha256_kat_oneshot() { let d = libcrux::digest::sha2_256(b"libcrux sha2 256 tests"); let expected = "8683520e19e5b33db33c8fb90918c0c96fcdfd9a17c695ce0f0ea2eaa0c95956"; - assert_eq!(hex::encode(&d), expected); + assert_eq!(hex::encode(d), expected); } #[test] @@ -27,8 +30,10 @@ fn sha2_clone() { let mut hasher224_2 = hasher_224.clone(); hasher_224.update(b"more 224"); hasher224_2.update(b"more 224"); - let digest = hasher_224.finish(); - let digest_2 = hasher224_2.finish(); + let mut digest = [0u8; 28]; + let mut digest_2 = [0u8; 28]; + hasher_224.finish(&mut digest); + hasher224_2.finish(&mut digest_2); assert_eq!(digest, digest_2); assert_eq!(digest, libcrux::digest::sha2_224(b"test 224more 224")); @@ -38,8 +43,10 @@ fn sha2_clone() { let mut hasher256_2 = hasher_256.clone(); hasher_256.update(b"more 256"); hasher256_2.update(b"more 256"); - let digest = hasher_256.finish(); - let digest_2 = hasher256_2.finish(); + let mut digest = [0u8; 32]; + let mut digest_2 = [0u8; 32]; + hasher_256.finish(&mut digest); + hasher256_2.finish(&mut digest_2); assert_eq!(digest, digest_2); assert_eq!(digest, libcrux::digest::sha2_256(b"test 256more 256")); @@ -49,8 +56,10 @@ fn sha2_clone() { let mut hasher384_2 = hasher_384.clone(); hasher_384.update(b"more 384"); hasher384_2.update(b"more 384"); - let digest = hasher_384.finish(); - let digest_2 = hasher384_2.finish(); + let mut digest = [0u8; 48]; + let mut digest_2 = [0u8; 48]; + hasher_384.finish(&mut digest); + hasher384_2.finish(&mut digest_2); assert_eq!(digest, digest_2); assert_eq!(digest, libcrux::digest::sha2_384(b"test 384more 384")); @@ -60,8 +69,10 @@ fn sha2_clone() { let mut hasher512_2 = hasher_512.clone(); hasher_512.update(b"more 512"); hasher512_2.update(b"more 512"); - let digest = hasher_512.finish(); - let digest_2 = hasher512_2.finish(); + let mut digest = [0u8; 64]; + let mut digest_2 = [0u8; 64]; + hasher_512.finish(&mut digest); + hasher512_2.finish(&mut digest_2); assert_eq!(digest, digest_2); assert_eq!(digest, libcrux::digest::sha2_512(b"test 512more 512")); diff --git a/traits/Cargo.toml b/traits/Cargo.toml new file mode 100644 index 000000000..062bb9f67 --- /dev/null +++ b/traits/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "libcrux-traits" +description = "Traits for cryptographic algorithms" + +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +[dependencies] diff --git a/traits/src/lib.rs b/traits/src/lib.rs new file mode 100644 index 000000000..168fb3d8e --- /dev/null +++ b/traits/src/lib.rs @@ -0,0 +1,17 @@ +/// A Hash algorithm returning hashes of length `HASH_LEN`. +pub trait Digest { + /// Writes the digest for the given input byte slice, into `digest` in immediate mode. + fn hash(digest: &mut [u8; HASH_LEN], payload: &[u8]); + + /// Add the `payload` to the digest. + fn update(&mut self, payload: &[u8]); + + /// Writes the digest into `digest`. + /// + /// Note that the digest state can be continued to be used, to extend the + /// digest. + fn finish(&self, digest: &mut [u8; HASH_LEN]); + + /// Reset the digest state. + fn reset(&mut self); +}