Verbatim clone of integritychain/fips205 (pure-Rust FIPS 205 / SLH-DSA), pinned at 30bac08 for the SLH-DSA formal-verification campaign. Aeneas-compat patches land here as transparent commits. Independent snapshot: no affiliation with, and no changes prop
Find a file
mrwulf c945821bf9 vectors: make the extraction re-derivable and the provenance claim literally true
Round-7 review (both reviewers, independently) found that the ACVP provenance
note said "the per-test private key `sk` dropped ... Nothing else altered" while
the extraction had in fact also dropped `additionalRandomness` and `deferred`
from all 42 tests, plus the top-level `isSample`. No field the tests consume was
affected and no verdict changed — but the provenance block is the audit trail a
third party diffs against, and as written it would have produced a false alarm
or taught the next reviewer to wave differences through.

Rather than reword the note, the transformation is now executable and pinned:
tests/nist_acvp_vectors/extract_sha2_128s.py re-derives the file, verifies the
upstream sha256 before doing anything, requires exactly 3 groups x 14 tests,
removes exactly ONE field (`sk`) and asserts that invariant, carries every other
per-test, group and top-level key through untouched, and writes canonical
output. Run with no arguments it VERIFIES the committed file against a fresh
extraction; --write regenerates. The file was regenerated with it, so
"only `sk` removed" is now literally true and machine-checkable.

Also from round 7, precision in the tests themselves:
- exact assertions replace floors: `points == 108` (was >= 100),
  `with_ctx == 9` (was > 0), and prehash `3/4/7` (was `checked > 0`). With 7 of
  14 prehash vectors skipped for unimplemented hash functions, a floor would
  have let real coverage fall from 3 to 1 while the total still summed to 14.
- the randomized bridge's doc comment claimed corruption "across the WHOLE
  signature"; measured, the schedule hits 72 distinct positions in 11..=7779,
  never bytes 0-10 or 7780-7855. Corrected to the measured statement.

Verified on stable Rust (rustc 1.95) as well as the pinned nightly: the bridge
needs no nightly feature, so a third party can run all of it with cargo alone.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 13:01:13 +02:00
benches docs, bench stats 2024-10-03 14:48:53 -05:00
dudect v0.4.0 RC1 2024-10-04 11:02:10 -05:00
ffi audit/coverage/ffi 2024-10-03 12:39:25 -05:00
fuzz 0.4.1 RC1 2024-12-22 20:46:43 -06:00
src vectors: make the extraction re-derivable and the provenance claim literally true 2026-07-28 13:01:13 +02:00
tests vectors: make the extraction re-derivable and the provenance claim literally true 2026-07-28 13:01:13 +02:00
wasm Update package.json 2025-09-01 18:34:31 -05:00
.gitignore reproducibility: commit Cargo.lock + pin rust-toolchain (review round 2) 2026-07-24 19:08:47 +02:00
Cargo.lock reproducibility: commit Cargo.lock + pin rust-toolchain (review round 2) 2026-07-24 19:08:47 +02:00
Cargo.toml fuzz up 2024-12-22 18:32:27 -06:00
CHANGELOG.md fuzz up 2024-12-22 18:32:27 -06:00
deny.toml 0.4.1 RC1 2024-12-22 20:46:43 -06:00
LICENSE-APACHE init 1 2023-11-26 14:18:22 -06:00
LICENSE-MIT init 1 2023-11-26 14:18:22 -06:00
README.md docs, bench stats 2024-10-03 14:48:53 -05:00
rust-toolchain.toml reproducibility: commit Cargo.lock + pin rust-toolchain (review round 2) 2026-07-24 19:08:47 +02:00
rustfmt.toml docs, bench stats 2024-10-03 14:48:53 -05:00
SECURITY.md fips205 prep 2024-02-09 17:43:59 -06:00

IntegrityChain: FIPS 205 Stateless Hash-Based Digital Signature Standard

crate Docs Build Status Apache2/MIT licensed Rust Version

FIPS 205 Stateless Hash-Based Digital Signature Standard written in pure Rust for server, desktop, browser and embedded applications. The source repository includes examples demonstrating benchmarking, constant-time statistical measurements, and WASM execution.

This crate implements the FIPS 205 final/released standard in pure Rust with minimal and mainstream dependencies, and without any unsafe code. All twelve (!!) security parameter sets are fully functional. The implementation's key- and signature-generation functionality operates in constant-time, does not require the standard library, e.g. #[no_std], has no heap allocations, e.g. no alloc needed, and exposes the RNG so it is suitable for the full range of applications from server down to the bare-metal. The API is stabilized and the code is heavily biased towards safety and correctness; further performance optimizations will be implemented as the standard matures. This crate will quickly follow any changes to FIPS 204 standard/vectors as they become available.

See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.205.pdf for a full description of the target functionality.

The functionality is extremely simple to use, as demonstrated by the following example.

use fips205::slh_dsa_shake_128s; // Could use any of the twelve security parameter sets. 
use fips205::traits::{SerDes, Signer, Verifier};
# use std::error::Error;
#
# fn main() -> Result<(), Box<dyn Error>> {

let msg_bytes = [0u8, 1, 2, 3, 4, 5, 6, 7];

  
// Generate both public and secret keys. This only fails when the OS rng fails.
let (pk1, sk) = slh_dsa_shake_128s::try_keygen()?; 
// Use the secret key to generate a signature. The second parameter is the
// context string (often just an empty &[]), and the last parameter selects
// the preferred hedged variant. This only fails when the OS rng fails.
let sig_bytes = sk.try_sign(&msg_bytes, b"context", true)?;  

  
// Serialize the public key, and send with message and signature bytes. These
// statements model sending byte arrays over the wire.
let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), msg_bytes, sig_bytes);
let (pk_recv, msg_recv, sig_recv) = (pk_send, msg_send, sig_send);

  
// Deserialize the public key. This only fails on a malformed key.
let pk2 = slh_dsa_shake_128s::PublicKey::try_from_bytes(&pk_recv)?;
// Use the public key to verify the msg signature
let v = pk2.verify(&msg_recv, &sig_recv, b"context");
assert!(v); 
# Ok(())
# }

The detailed Rust Documentation lives under each Module corresponding to the desired security parameter below.

Notes

  • This crate is fully functional and corresponds to the final/released FIPS 205 (August 13, 2024), including the pre-hash variants which formalize methods for signing a hash of the message instead of the message itself (along with metadata about the hasher used).
  • Constant-time assurances target the source-code level only, with confirmation via manual review/inspection, the embedded target, and the dudect dynamic tests.
  • Note that FIPS 205 places specific requirements on randomness per section 3.1, hence the exposed RNG.
  • Requires Rust 1.70 or higher. The minimum supported Rust version may be changed in the future, but it will be done with a minor version bump (when the major version is larger than 0).
  • All on-by-default features of this library are covered by SemVer.
  • The FIPS 205 standard and this software should be considered experimental -- USE AT YOUR OWN RISK!

License

Contents are licensed under either the Apache License, Version 2.0 or MIT license at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.