mldsa-native v1.0.0-beta2
We are pleased to announce the v1.0.0-beta2 release of mldsa-native, the second beta release.
As in the previous release, the C backend of mldsa-native is production-ready: it is formally verified with CBMC for memory safety, type safety, and the absence of (certain types of) undefined behavior. On the AArch64 and x86_64 backends, a growing set of assembly routines carries HOL Light proofs of functional correctness, memory safety, and secret-independent execution. The "beta" designation does not reflect project maturity: it will be dropped once HOL-Light proof coverage of the AArch64 and x86_64 backends is complete. See SOUNDNESS.md for the full verification scope, and the AArch64 and x86_64 coverage trackers for the remaining work.
Memory optimizations
The MLD_CONFIG_REDUCE_RAM build mode introduced as experimental in v1.0.0-beta is no longer experimental: it is now fully covered by CBMC, and substantial further reductions have landed on top of it. The MLD_TOTAL_ALLOC_{44,65,87}_{KEYPAIR,SIGN,VERIFY} constants exposed in mldsa_native.h report the maximum cumulative MLD_ALLOC size for each parameter set and operation (note that on top of that a small amount of stack memory is needed); the figures for v1.0.0-beta2 are:
| Parameter set | Operation | Default (bytes) | MLD_CONFIG_REDUCE_RAM (bytes) |
|---|---|---|---|
| ML-DSA-44 | keypair | 26,912 | 11,584 |
| ML-DSA-44 | sign | 44,704 | 13,120 |
| ML-DSA-44 | verify | 24,448 | 9,120 |
| ML-DSA-65 | keypair | 44,320 | 14,656 |
| ML-DSA-65 | sign | 69,312 | 17,248 |
| ML-DSA-65 | verify | 39,872 | 10,208 |
| ML-DSA-87 | keypair | 75,040 | 18,752 |
| ML-DSA-87 | sign | 108,224 | 21,344 |
| ML-DSA-87 | verify | 68,800 | 12,512 |
New configuration options
MLD_CONFIG_NO_KEYPAIR_API- excludescrypto_sign_keypair,crypto_sign_keypair_internal,crypto_sign_pk_from_sk, and all internal APIs only needed by keypair generation.MLD_CONFIG_NO_SIGN_API- excludescrypto_sign,crypto_sign_signature{,_extmu,_internal,_pre_hash_internal,_pre_hash_shake256}and the internal APIs only they need.MLD_CONFIG_NO_VERIFY_API- excludescrypto_sign_open,crypto_sign_verify{,_extmu,_internal,_pre_hash_internal,_pre_hash_shake256}and the internal APIs only they need.MLD_CONFIG_MAX_SIGNING_ATTEMPTS- upper bound on the rejection-sampling iterations performed by signing (FIPS 204 Algorithm 7). When exhausted, signing returns the newMLD_ERR_SIGN_ATTEMPTS_EXHAUSTEDerror code.
SOUNDNESS.md
This release introduces SOUNDNESS.md (#1112), a written account of the scope, assumptions, trusted computing base, and residual risks of mldsa-native's formal-verification effort. It covers the shared methodology with mlkem-native (CBMC for the C code and HOL Light + s2n-bignum for the AArch64 and x86_64 assembly), points at the underlying mlkem-native and s2n-bignum soundness documents for the shared analysis, and enumerates the gaps specific to mldsa-native, in particular the assembly routines that do not yet have HOL Light specifications. It is intended as a living document; feedback is welcome via GitHub issues or, for potential vulnerabilities, private vulnerability reporting.
Other noteworthy changes
- Wycheproof test vectors are now exercised against ML-DSA in CI (#1063).
- The AArch64 backend is now CI-tested on a baremetal AArch64 target where any unaligned data access raises an Alignment fault (#1094). The same trap would fire under an OS that sets
SCTLR_ELn.A, but in typical configurations that bit is cleared and unaligned accesses to Normal memory silently succeed. Several assembly routines that had relied on unaligned memory accesses were updated to use alignment-safe accesses. - CI gains RISC-V runners provided by the RISE project (#1034).
What's Changed
- CI: lint: output errors by @L-series in #1004
- Refactor keccak_squeezeblocks_x4() to simplify proof by @rod-chapman in #1012
- Sign: Unpack
s1,s2, andt0on the fly inREDUCE_RAMmode by @mkannwischer in #1002 - x86_64: Eliminate caddq intrinsics by @willieyz in #905
- MAINTAINERS.md: Remove affiliations by @mkannwischer in #1017
- simpasm: Move .note.GNU-stack outside preprocessor guards by @mkannwischer in #1021
- nix: Bump cbmc-viewer from 3.11 to 3.12 by @mkannwischer in #1020
- HOL-Light/AArch64: Port proofs from mlkem-native by @willieyz in #965
- CI: Add clang22 tests and constant-time tests by @mkannwischer in #1024
- Add HOL Light pointwise multiplication proofs for AArch64 and x86_64 by @jakemas in #1006
- lowram: Compute h incrementally in signing by @mkannwischer in #1015
- aarch64/src/polyz_unpack_table.c: Disable unused tables by @flynd in #1029
- Add HOL Light pointwise-acc multiplication proofs for AArch64 and x86_64 by @jakemas in #1010
- CT: Update comment on valgrind issue by @hanno-becker in #1035
- FIPS202/x86_64: Don't use native x4 backend on x86_64 when not needed by @flynd in #1032
- Add README to mldsa/ by @hanno-becker in #1036
- Fix context-length validation in ACVP test binary by @hanno-becker in #1038
- CI: Sync with mlkem-native (RISC-V runners, fork guards, examples, benchmarking) by @mkannwischer in #1034
- CBMC: Restore polyvecl_pointwise_acc_montgomery_c proof flags by @hanno-becker in #1039
- CBMC: Update to v6.9.0 by @hanno-becker in #1041
- poly_ntt_c add --slice-formula to stabilize proof by @rod-chapman in #1042
- Add configs to disable unused APIs [full CI] by @mkannwischer in #1000
- Sign: Set smlen to 0 in case of failure by @mkannwischer in #959
- CBMC: Remove MLD_UNION_OR_STRUCT by @hanno-becker in #1044
- Lowram: Share buffers with non-overlapping lifetimes in keygen by @mkannwischer in #1011
- native: Allow tables to be declared static by @flynd in #1043
- Update s2n-bignum and HOL Light pins by @jakemas in #1045
- Lint: Replace
blackwithruffby @mkannwischer in #1047 - Armv8.1-M: Add CFI directives for stack unwinding by @mkannwischer in #1048
- lowram: Stream matrix A element-by-element to reduce memory by @mkannwischer in #1019
- Remove --slice-formula from all Makefiles and set in Makefile.common by @rod-chapman in #1049
- check-contracts: Detect contracts separated from prototype by a comment by @mkannwischer in #1051
- Port: Format: Don't allow tabs by @mkannwischer in #1022
- CBMC: Run proofs with MLD_CONFIG_REDUCE_RAM in CI by @mkannwischer in #1050
- CI: Bump ACVP, liboqs, expo, and AWS-LC versions by @mkannwischer in #1057
- HOL-Light: Add x86 AVX2 nttunpack proof by @jakemas in #955
- nix: Pull CBMC 6.9.0 from nixos-unstable binary cache by @mkannwischer in #1062
- CI: Re-enable RISE RISC-V runner by @mkannwischer in #1061
- CBMC: Cover
MLD_CONFIG_REDUCE_RAMmode by @mkannwischer in #1060 - lowram: Eliminate y vector in REDUCE_RAM mode in sign by @mkannwischer in #1031
- Port: Add ACVP test Windows support (C backend) by @willieyz in #1064
- CBMC: Add contracts and proofs for yvec init/get_poly by @mkannwischer in #1066
- Fix various reduced-API gates in REDUCED_RAM config by @mkannwischer in #1072
- Make poly_pointwise_montgomery destructive by @mkannwischer in #1067
- CI: Add zig 0.16 compiler tests by @mkannwischer in #1071
- Correct size of rnd buffer for CT testing by @rod-chapman in #1075
- x86_64: Fix wrong qbound 87q -> 31q in use_hint_32 by @mkannwischer in #1076
- HOL-Light: Add HOL Light proof for aarch64
polyz_unpack_{17,19}by @mkannwischer in #971 - Test: Add Wycheproof tests for ML-DSA by @mkannwischer in #1063
- HOL-Light: Add HOL Light poly_use_hint proofs for AArch64 by @jakemas in #1037
- Make poly_use_hint destructive by @mkannwischer in #1070
- CBMC: Auto-derive lazy/eager suffix in proof Makefiles by @hanno-becker in #1065
- Test: Use Wycheproof signing tests to validate pk_from_sk by @hanno-becker in #1087
- CI: Update Github action dependencies by @mkannwischer in #1083
- HOL-Light/x86_64: Replace Keccakx4 intrinsics with AVX2 assembly and prove correct by @mkannwischer in #989
- Lowram: Share buffers with non-overlapping lifetimes in verify by @mkannwischer in #1007
- Use heap allocation + valgrind in backend unit test by @hanno-becker in #1089
- CI: Enable Wycheproof tests on aarch64-virt baremetal by @mkannwischer in #1094
- HOL-Light: Prefix imports to separate mldsa-native from s2n-bignum by @hanno-becker in #1088
- sign: Use MLD_ALLOC for all secret buffers in sign.c by @mkannwischer in #1077
- HOL-Light: Add AArch64 poly_decompose_{32,88} correctness proofs by @mkannwischer in #977
- Lowram: Refactor verify into per-row loop, drop polyveck w1/t1/h by @mkannwischer in #1095
- native: Unify asm backend symbol naming by @mkannwischer in #1058
- sign: Add MLD_CONFIG_MAX_SIGNING_ATTEMPTS and dedicated error code by @hanno-becker in #1059
- lowram: Per-row t0/t1 computation in keygen by @mkannwischer in #1030
- Add AArch64 ML-DSA Inverse NTT HOL Light proof and CBMC contract by @dkostic in #1069
- HOL-Light: Add missing safety proofs by @mkannwischer in #1101
- Doc: Improve documentation of externalmu and relax its CBMC contract by @mkannwischer in #1107
- nix: Anchor HOL-Light shellHook to repo root, not $PWD by @hanno-becker in #1105
- sign: Consolidate make_hint and pack_sig_h_poly by @mkannwischer in #1028
- README: Note other side-channel and fault attacks are currently out of scope by @mkannwischer in #1111
- Documentation: Convert to Doxygen-style function headers and lint by @mkannwischer in #1106
- CI: Re-enable nix compatibility tests by @mkannwischer in #1110
- Doc: Drop "REDUCE_RAM not covered by CBMC" warning and EXPERIMENTAL tag by @mkannwischer in #1098
- sign: Drop CBMC performance workaround in attempt_signature_generation by @mkannwischer in #1100
- Add SOUNDNESS.md by @mkannwischer in #1112
- Armv8.1-M: Add native Keccak x4 XORBytes and ExtractBytes by @mkannwischer in #972
- CBMC: Introduce separate proofs for Keccak XXX_c() functions by @mkannwischer in #1113
- CBMC: Document and enforce 4 GiB limit of forall/exists quantifiers by @hanno-becker in #1120
- CBMC: Introduce MLD_ANY_ERROR helper for error disjunctions by @hanno-becker in #1117
- Align bench iteration macros between component and API benchmarks by @hanno-becker in #1121
- ML-DSA aarch64 rejection sampling proof by @dkostic in #997
- x86_64: 32-byte align Keccak x4 AVX2 stack frame by @hanno-becker in #1124
- HOL-Light: Add HOL Light proof and CBMC contracts for x86 poly_caddq by @jakemas in #1068
- scripts/cfify: don't re-anchor CFA on scratch
movq %rsp, %REGby @hanno-becker in #1128
Full Changelog: v1.0.0-beta...v1.0.0-beta2