Initial dev - #1
Merged
Merged
Conversation
…ry. This commit includes core modules for error handling, key encapsulation mechanisms (KEMs), digital signatures, hash functions, authenticated encryption, and zero-knowledge proofs (ZKPs). Additionally, it sets up configuration files for Cargo, Clippy, and Rustfmt, establishing a foundation for development and testing.
…bQ. This commit introduces GitHub Actions workflows for continuous integration, continuous deployment, and security validation, along with a pre-commit configuration file to enforce code quality checks. Additionally, it includes scripts for building WASM and performing security checks, enhancing the development and release process.
…ws. This commit modifies the `build.rs` to set the correct configuration for WASM targets, updates the `Cargo.toml` and `Cargo.lock` to use newer versions of dependencies, and improves CI workflows by adding installations for `cargo-audit` and `cargo-outdated`. Additionally, it introduces constant-time verification and timing analysis tests to ensure cryptographic operations are secure and consistent.
…tests. This commit modifies the CI configuration to include ARM64 cross-compilation, updates the `proc-macro2` dependency to version 1.0.100, and improves constant-time verification tests by ensuring consistent timing across various cryptographic operations. Additionally, it cleans up whitespace in several files for better readability.
…mpilation support; bump `proc-macro2` dependency to version 1.0.101. This commit enhances the CI configuration by adding network connectivity checks and retry logic for Rust installation, while also introducing a separate job for Windows builds.
…move unnecessary steps. This commit updates the CI configuration by consolidating Rust installation steps, adding `rustfmt` and `clippy` components, and simplifying test commands. Additionally, it standardizes the runner environment to `ubuntu-latest` for consistency across builds.
…ss. This commit modifies the CI workflows to upgrade the caching action to version 4, improves the WASM build steps by separating nodejs and web targets, and adds verification for WASM artifacts. Additionally, it removes an unnecessary dependency from the Cargo.toml file, streamlining the project configuration.
… ARM64/macOS target support.
Nexlab-One
added a commit
that referenced
this pull request
Jul 29, 2026
…2/armv7 that nothing ever ran (#74) * test(fn-dsa): execute flr_emu.rs, the float backend that ships to wasm/armv7 WHY --- `fn-dsa-sign/src/flr.rs` picks the floating-point backend by `target_arch` alone: flr_native.rs on x86_64/aarch64/arm64ec/riscv64, flr_emu.rs (software binary64) on everything else -- wasm32, armv7, 32-bit x86. Nothing in this repo executed flr_emu.rs. It is not a feature: `--features no_avx2` switches the portable *vector* path and leaves the float backend native, so no x86_64 job could reach it however configured. The wasm rows are `cargo check` / `wasm-pack build` only, and the aarch64/armv7 rows never run at all on PRs. FN-DSA signing is decided bit-for-bit by these rounding rules, so a defect here would have shipped as wrong or non-verifying signatures on wasm and armv7 rather than as a clean failure. The correctness of that backend was unknown in both directions. It is now measured, on both axes: 1. flr_emu_diff.rs (new, test-only). flr.rs compiles flr_emu.rs a SECOND time under #[cfg(test)] on the native-backend arches, and the tests diff the two backends bit-for-bit -- via encode(), so +0.0 and -0.0 are distinguished -- over every operation of the Flr surface. This runs in the ordinary `cargo test --workspace` rows; no emulator required. Production dispatch is untouched: a non-test x86_64 build still compiles flr_native.rs and only flr_native.rs. 2. A new `fn-dsa-emulated-float` CI job runs this crate's existing suite on wasm32-wasip1 under wasmtime. wasm32 selects flr_emu.rs *and* the generic variants of its four arch-gated helpers (lzcnt_nz/ursh/ulsh/irsh) -- the same combination armv7 ships, and the part a host build cannot reach. The job asserts the build really compiled flr_emu.rs before trusting a green run, so it cannot decay into a silent no-op the way `self_test` did when has_avx2() sent it down the AVX2 branch. RESULT: no defect. The emulated backend agrees with the native one on every in-domain input tested. WHAT THE DIFFERENTIAL FOUND --------------------------- Four inputs, all involving a negative zero, on which the two backends do NOT agree. Every one is inherited verbatim from upstream fn-dsa v0.3.0; neither backend is modified here. They are PINNED, not fixed -- changing either side would change signature bytes on some target, which is not a test's call: abs(-0.0) emu +0.0, native -0.0 (emu is the IEEE-correct one; abs() is test-only in both backends) sqrt(-0.0) emu +0.0, native -0.0 (native is IEEE-correct) floor(-0.0) emu -1, native 0 (deliberate upstream behaviour, see the comment in flr_emu.rs) (+/-0.0) / x emu forces the quotient sign to +, native follows IEEE Only floor() reaches production code (sampler.rs `let s = mu.floor()`); every division in this crate is `Flr::ONE / x`, so a zero dividend cannot occur, and abs() is called only from tests. Whether `mu` can be exactly -0.0 is NOT established here and is left as an open question on the record. Also pinned: expm_p63 with ccs == 1 exactly, where the implementations differ because `Flr::ONE.mul2p63().trunc()` applies trunc() to 2^63, one past the top of its own documented input range. A precondition violation, not a defect. A NOTE ON THE MULTIPLICATION-TIE VECTORS ---------------------------------------- The first version of this test did not catch a one-bit change to the rounding table inside `Flr::make()` (0xC8 -> 0x88, i.e. dropping the round-half-to-EVEN "round up" case). That bit is reachable only through set_mul and set_div, and a division can never produce an exact tie: with a = a0*2^u and b = b0*2^v, a0 and b0 odd, the quotient (a0/b0)*2^(u-v) has an odd denominator in lowest terms, so it either terminates within 53 bits (exact, no rounding) or never terminates (sticky = 1, not a tie). Multiplication is the only route, and random operands essentially never land on an exact tie. The 16 hardcoded operand pairs in `flr_emu_matches_native_multiplication_ties` were searched for explicitly and cross-checked against an arbitrary-precision model; without them that mutation left all 18 other tests in this crate green. DETERMINISM: every randomized input is SHAKE256-derived from a hardcoded seed. Nothing reads the clock or system entropy. The two `#[allow]`s on the test-only `mod emu_ref` are deliberate and are documented in flr.rs. They exist because flr_emu.rs raises two clippy findings when compiled on x86_64 -- findings the repo's own `cargo clippy --workspace --all-targets --all-features -- -D warnings` gate has never surfaced, precisely because it never compiles that file. Silencing them at the module declaration keeps flr_emu.rs byte-faithful to upstream. * fix(fn-dsa): flr_emu_diff pinned the wrong native answer under div_emu/sqrt_emu WHY --- The differential added in 8e37de4 was RED under two of this crate's own features. `cargo test -p lib-q-fn-dsa-sign --lib --features sqrt_emu` panicked at flr_emu_diff.rs:529 (`bits_nat(Nat::NZERO.sqrt()) == NZ`), and `--features div_emu` panicked at :562; `--all-features` failed at :529. Both are regressions introduced by that commit -- flr_emu_diff.rs does not exist on origin/main (b68ed13), so the test could not have been red before. ROOT CAUSE ---------- The comment 8e37de4 put in flr.rs claimed the float backend "is *not* influenced by any Cargo feature". That is true of module SELECTION -- which of flr_native.rs / flr_emu.rs is compiled is `target_arch`-only -- and false of the selected backend's BEHAVIOUR. `div_emu` swaps flr_native's `self.0 /= other.0` for the integer `Flr::div_emu()`, and `sqrt_emu` swaps its SSE2/NEON/RISC-V sqrt opcode for `Flr::sqrt_emu()`; both exist for targets whose FPU divide/sqrt is not constant-time. Those two routines are line-for-line ports of flr_emu.rs's own `set_div`/`sqrt`: `sqrt_emu` ends in the same `make_z(0, ..)` that cannot emit a sign bit, and `div_emu` carries the same `s &= dm` zero-dividend clamp. So under those features the native side ADOPTS flr_emu's signed-zero behaviour and two of the four pinned divergences vanish -- while the test hard-coded the opposite for the native side. Believing that comment is what produced the bug, so the comment is fixed too, in the same commit. WHAT CHANGED ------------ flr.rs: the backend-selection comment now separates SELECTION (target_arch only, unchanged) from BEHAVIOUR (div_emu/sqrt_emu, native side only), names exactly what each feature swaps and what that does to signed zeros, and warns that no CI row sets either feature so a native-side claim that only holds without them will not be caught. flr_emu_diff.rs: no assertion is deleted or cfg'd out. The two feature-sensitive expectations become cfg-selected constants -- NAT_SQRT_NZERO (NZ without sqrt_emu, PZ with) and NAT_ZERO_DIV ([PZ,NZ,NZ,PZ] without div_emu, all-PZ with) -- so every pin still runs under every feature combination, and under the emu features the test now additionally asserts that the divergence really is GONE rather than merely not looking. Cfg-ing the assertions away instead would have left `--features div_emu,sqrt_emu` -- the configuration a constant-time-conscious integrator actually ships -- with the signed-zero contract unchecked. The assert messages now print the observed bits, the pinned bits and the feature state, so a future failure names its own cause. VERIFIED -------- `cargo test -p lib-q-fn-dsa-sign --lib -- --test-threads=1` under no features / div_emu / sqrt_emu / div_emu,sqrt_emu: `ok. 19 passed` each. `cargo test -p lib-q-fn-dsa-sign -p lib-q-fn-dsa-comm --all-features --lib`: `ok. 15 passed` + `ok. 6 passed` (was 14 passed; 1 failed). `cargo clippy -p lib-q-fn-dsa-sign -p lib-q-fn-dsa-comm --all-targets --all-features -- -D warnings` and `cargo fmt -p lib-q-fn-dsa-sign -- --check`: clean. The differential still bites, checked by mutation and reverted after each: * flr_emu `make()` 0xC8 -> 0x88 (drop the round-half-to-EVEN round-up case): multiplication_ties FAILED under all four feature combinations, `emu=0x46802F73BAFEB827 native=0x46802F73BAFEB828`. * flr_emu `sqrt` `make_z(0, ..)` -> `make_z(self.0 >> 63, ..)`: pinned test FAILED, "emu sqrt(-0.0) != +0.0", with and without sqrt_emu. * flr_native `sqrt_emu` made to keep the sign bit: pinned test FAILED under --features sqrt_emu, "native sqrt(-0.0) = 0x8000000000000000, pinned 0x0000000000000000 (sqrt_emu = true)" -- i.e. the new feature-branch expectation is a live check, not a rubber stamp. * flr_native `div_emu` `s & dm` -> `s & u64::MAX` (drop the clamp): pinned test FAILED under --features div_emu, "native zero-dividend div #1 = 0x8000000000000000, pinned 0x0000000000000000 (div_emu = true)". BLAST RADIUS of the original defect, stated honestly: no CI job sets either feature (`grep -rn "div_emu\|sqrt_emu" .github/ scripts/` returns nothing) and no crate forwards them (only fn-dsa-sign/Cargo.toml declares them), so this was never CI-red. It was a latent trap for anyone building the crate under its own constant-time divide/sqrt features. NOT FIXED HERE: `cargo clippy -p lib-q-fn-dsa-sign --all-targets --all-features` (that crate alone) still fails to compile at lib.rs:819, `no SHAKE256x4 in shake` -- fn-dsa-comm's `shake256x4` feature is not enabled by selecting only the dependent crate. Pre-existing, in a file this commit does not touch, and owned by the fix/shake256x4-feature branch. * fix(fn-dsa-sign): correct false CI-coverage claim in flr.rs/flr_emu_diff.rs comments The comments claimed no CI row sets div_emu/sqrt_emu, so a claim that only holds without them "will not be caught by CI." That's false: ci.yml's workspace-root `cargo clippy --all-targets --all-features` step is not `-p`-scoped, so it does compile-check both features. The accurate nuance is that no CI row actually *runs tests* under either feature -- clippy type-checks but doesn't execute -- so a runtime/behavioral claim could still slip through untested.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.