Last updated: 2026-06-16
This is the engineering guide for completing, validating, and releasing
pqcrypto's SHA-3 / SHAKE and SHA-3-derived function surface:
- FIPS 202: SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256, and the Keccak-p[1600, 24] permutation used by those functions.
- NIST SP 800-185: cSHAKE, KMAC, KMACXOF, TupleHash, TupleHashXOF, ParallelHash, and ParallelHashXOF.
This document is deliberately more comprehensive than the current implementation state. The package already vendors part of FIPS 202 for ML-KEM, ML-DSA, and future SLH-DSA work, but it has not yet been treated as a standalone standards-complete release surface. This guide is the A-to-Z plan for doing that without overclaiming.
This document is not a CMVP/FIPS 140 validation certificate. It is a release plan for algorithm conformance, corpus provenance, security hardening, API design, test evidence, issue tracking, and public claim discipline. The exact acceptable wording lives in FIPS_140_BOUNDARY.md.
Release train: 0.6.0 is the target for the first complete FIPS 202 / SP 800-185 release scope. 0.7.0 is reserved for spillover if the full standards surface or its validation evidence cannot close in 0.6.0 without weakening the claim boundary.
Not complete. The repo contains the byte-oriented FIPS 202 function family, but it has not yet closed the complete official corpus/non-byte evidence gate or implemented any SP 800-185 functions.
Current implementation:
lib/src/common/keccak.dartimplements Keccak-f[1600] using portable 32-bit lane halves.- The exposed one-shot functions are
sha3224,sha3256,sha3384,sha3512,shake128, andshake256. - Incremental SHAKE output is available through
shake128Xofandshake256Xof. test/keccak_test.dartpins SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, and SHAKE256 against known-answer values, including multi-block input, direct Keccak parameter tables, and XOF prefix stability.test/fips202_examples_test.dartruns the selected official byte-aligned FIPS 202 example corpus undertest/data/FIPS202.- The package has zero runtime dependencies.
Missing before any complete FIPS 202 claim:
- A public or test-only bit-string representation for non-byte-aligned NIST examples.
- Complete checked-in FIPS 202 example-corpus coverage beyond the selected byte-aligned subset.
- Coverage of non-byte NIST examples such as 5-bit, 30-bit, 1605-bit, and 1630-bit messages for all six FIPS 202 functions, or an explicit scoped deferral for byte-only APIs.
Missing before any SP 800-185 claim:
left_encode,right_encode,encode_string,bytepad, and substring helpers.- cSHAKE128 and cSHAKE256.
- KMAC128, KMAC256, KMACXOF128, and KMACXOF256.
- TupleHash128, TupleHash256, TupleHashXOF128, and TupleHashXOF256.
- ParallelHash128, ParallelHash256, ParallelHashXOF128, and ParallelHashXOF256.
- A checked-in SP 800-185 example corpus with provenance.
- API-level validation for length limits, block-size limits, customization strings, key length guidance, and unsupported bit-level inputs.
- VM, dart2js, and dart2wasm tests for the implemented byte-oriented surface.
The release strategy uses a standards-first, evidence-gated program rather than a narrow patch that only fills SHA3-224/SHA3-384.
Controlling decisions:
- Target the current final standards first. FIPS 202 (August 2015) and SP 800-185 (December 2016) remain the current final publications. NIST has announced future update/revision work, but those future drafts are not the implementation baseline until NIST finalizes replacements.
- Split implementation into evidence-backed stages. Complete FIPS 202 first, then SP 800-185 encodings and cSHAKE, then KMAC, TupleHash, and ParallelHash.
- Use 0.6.0 as the release target and 0.7.0 as disciplined spillover. Incomplete surfaces move forward as tracked scope; they do not become undocumented partial claims.
- Do not imply full support from partial evidence. Current SHA3-224/256/ 384/512, SHAKE128, and SHAKE256 support is valuable, but complete FIPS 202 public wording still depends on the remaining corpus/non-byte evidence gate; none of this is SP 800-185.
- Use official NIST example values as the authoritative corpus source. Every checked-in vector file needs provenance, source URL, retrieval date, and hash.
- Separate byte-oriented public APIs from bit-oriented conformance tests. SP 800-185 permits limited implementations that reject unsupported input shapes. A first supported release may expose byte-oriented APIs only, but non-byte NIST examples still need a test harness or documented deferral before broad conformance wording.
- Keep zero runtime dependencies. The package should continue to vendor the required Keccak/SP 800-185 logic in pure Dart.
- No CMVP/FIPS 140 language. The output of this program is algorithm and vector evidence, not a validated cryptographic module certificate.
| Source | URL / path | How this guide uses it |
|---|---|---|
| FIPS 202 final publication page | https://csrc.nist.gov/pubs/fips/202/final | Publication status, date, planning note, known Appendix B typo, official document links. |
| FIPS 202 final PDF | https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.202.pdf | Normative Keccak-p, sponge, SHA3, SHAKE, conformance, security, and appendices. |
| FIPS 202 DOI | https://doi.org/10.6028/NIST.FIPS.202 | Stable citation target. |
| SP 800-185 final publication page | https://csrc.nist.gov/pubs/sp/800/185/final | Publication status, date, planning note, official document links. |
| SP 800-185 final PDF | https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf | Normative definitions for cSHAKE, KMAC, TupleHash, ParallelHash, encodings, and security considerations. |
| SP 800-185 DOI | https://doi.org/10.6028/NIST.SP.800-185 | Stable citation target. |
| NIST March 2025 SHA-3 review decision | https://www.nist.gov/news-events/news/2025/03/sha-3-nist-update-fips-202-and-revise-special-publication-800-185 | Future-revision watch item and release-claim caution. |
| NIST example values | https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values | Authoritative source for FIPS 202 and SP 800-185 vectors. |
| Current Keccak code | lib/src/common/keccak.dart |
Baseline implementation and portability constraints. |
| Current Keccak tests | test/keccak_test.dart |
Existing evidence and gap analysis. |
| Existing release-guide precedent | MLDSA_FIPS204_RELEASE_GUIDE.md, SLHDSA_FIPS205_RELEASE_GUIDE.md | Structure, claim boundary, issue map, release gates. |
Local source-provenance snapshot taken on 2026-06-06:
| File | Pages | SHA-256 |
|---|---|---|
NIST.FIPS.202.pdf |
37 | 1592607831ff0908cc590632ce371c6c95e94025bb1a0c8ae90a4d0ec1ed025e |
NIST.SP.800-185.pdf |
32 | 0ebcdfb5b145bcb6a8a0f49737a201e8fb30dce06951595a07010774d402d7c5 |
NIST added planning notes to both publication pages in March 2025.
The current interpretation for this repo:
- FIPS 202 update: treat as editorial and standards-maintenance watch until a new final FIPS is published. The current implementation target remains the August 2015 final standard, with the published non-normative Appendix B typo tracked in docs/tests.
- SP 800-185 revision: treat streaming SHAKE/cSHAKE behavior as a future compatibility requirement, not as a reason to delay current final-standard conformance. Any future draft must be evaluated separately before code is changed.
- No public claim may say "latest revised SP 800-185" until a final revision is published, implemented, and tested.
Add a recurring release checklist item: before any SHA-3-derived function release, re-check the FIPS 202 and SP 800-185 CSRC pages for new drafts, errata, planning notes, or final revisions.
pqcrypto cannot claim full FIPS 202 plus SP 800-185 support until all of the
following are true for the surfaces being claimed:
- FIPS 202 functions SHA3-224/256/384/512 and SHAKE128/256 are implemented with correct rates, capacities, suffixes, output lengths, and padding.
- Existing SHA3-224/256/384/512 and SHAKE128/256 APIs remain byte-for-byte compatible.
- SHA3-224 and SHA3-384 remain covered by focused tests before public docs call the FIPS 202 family complete.
- NIST FIPS 202 example vectors are checked in or fetched through a reproducible, hash-pinned tool.
- Byte-oriented NIST examples pass for every implemented public API.
- Non-byte-oriented NIST examples are either supported in a test-only bit-string harness or explicitly documented as unsupported by the byte API.
- SP 800-185 helper encodings match the Recommendation exactly:
left_encode,right_encode,encode_string,bytepad, and substring. - cSHAKE falls back to SHAKE when both function-name string and customization string are empty.
- KMAC and KMACXOF encode output length correctly: fixed-output KMAC uses
right_encode(L), while XOF mode usesright_encode(0). - TupleHash and TupleHashXOF encode every tuple element with
encode_stringand include fixed-output vs XOF output-length separation. - ParallelHash and ParallelHashXOF honor block-size
B, inner cSHAKE output lengths, block count encoding, and fixed-output vs XOF separation. - Unsupported input shapes and sizes signal errors and never produce partial output.
- Security guidance for KMAC key length and output length is surfaced in API docs and release notes.
- All new functions run on Dart VM, dart2js, and dart2wasm with no runtime dependencies.
- README, changelog, pubspec metadata, and docs claim only what the checked-in evidence proves.
Acceptable wording after the relevant gates pass:
pqcryptoprovides a FIPS 202-aligned SHA-3/SHAKE implementation and SP 800-185-aligned SHA-3-derived functions for the surfaces listed in this release, with checked-in NIST example-vector evidence and VM/web regression tests.
Acceptable staged wording:
pqcryptocurrently implements SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, and SHAKE256 from FIPS 202. Complete FIPS 202 evidence and SP 800-185 coverage are tracked indoc/FIPS202_SP800185_RELEASE_GUIDE.md.
Forbidden without a validation certificate:
- "FIPS validated"
- "CMVP validated"
- "FIPS 140 compliant module"
- "certified"
- "constant-time Dart implementation" as a hard guarantee
- "securely erases memory" as a hard guarantee
FIPS 202/SP 800-185 algorithm conformance and FIPS 140 module validation are different claims. This package can provide source, vector, and regression evidence. It cannot claim a validated cryptographic module unless a separate module is validated through CMVP.
FIPS 202 defines the SHA-3 family over binary data using Keccak-p permutations, the sponge construction, and the Keccak multi-rate padding rule.
The FIPS 202 implementation target for this repo is byte-oriented public use, with test-only bit-string support sufficient to evaluate official examples that are not byte-aligned.
FIPS 202 defines Keccak-p[b, nr] over seven widths. The SHA-3 family uses Keccak-p[1600, 24].
Implementation expectations:
| Element | Requirement | Current repo |
|---|---|---|
| State width | 1600 bits, 25 lanes of 64 bits. | Stored as 50 32-bit halves for web portability. |
| Round count | 24 rounds for Keccak-p[1600, 24]. | Present. |
| Step mappings | theta, rho, pi, chi, iota. | Present in _permute. |
| Rho offsets | FIPS 202 Table 2. | Present and directly tested through KeccakF1600Parameters. |
| Round constants | Iota constants for 24 rounds. | Present and directly tested through KeccakF1600Parameters. |
| Padding | Keccak pad10*1 plus domain suffixes. |
Present through domain byte and final 0x80; profile tests cover suffix/rate/capacity. |
| Function | Capacity | Rate bytes | Domain suffix bits | Digest/output | Current status |
|---|---|---|---|---|---|
| SHA3-224 | 448 | 144 | 01 |
28 bytes | Present |
| SHA3-256 | 512 | 136 | 01 |
32 bytes | Present |
| SHA3-384 | 768 | 104 | 01 |
48 bytes | Present |
| SHA3-512 | 1024 | 72 | 01 |
64 bytes | Present |
| SHAKE128 | 256 | 168 | 1111 |
caller-selected | Present |
| SHAKE256 | 512 | 136 | 1111 |
caller-selected | Present |
For byte-oriented implementation, the existing domain bytes are:
- SHA3:
0x06 - SHAKE:
0x1f
The guide requires a test explaining this translation from FIPS bit suffixes to byte-oriented Keccak padding, because suffix mistakes are catastrophic and hard to notice from API tests alone.
FIPS 202 defines RawSHAKE128 and RawSHAKE256 as intermediate functions for alternate SHAKE definitions. They are not ordinary public hash APIs.
Repo rule:
- Do not export RawSHAKE as a top-level user API unless an explicit consumer requires it.
- If implemented, keep it internal/test-only and pin its domain suffix separately from SHAKE.
FIPS 202 gives SHA-3 HMAC block sizes:
| Hash | HMAC block size |
|---|---|
| SHA3-224 | 144 bytes |
| SHA3-256 | 136 bytes |
| SHA3-384 | 104 bytes |
| SHA3-512 | 72 bytes |
These are not needed for SP 800-185 KMAC, but they matter if the package later adds HMAC-SHA3. Keep them out of KMAC implementation to avoid mixing two different MAC constructions.
SP 800-185 defines SHA-3-derived functions with two security strengths:
| Security strength | cSHAKE | KMAC | TupleHash | ParallelHash | Rate |
|---|---|---|---|---|---|
| 128 bits | cSHAKE128 | KMAC128/KMACXOF128 | TupleHash128/TupleHashXOF128 | ParallelHash128/ParallelHashXOF128 | 168 bytes |
| 256 bits | cSHAKE256 | KMAC256/KMACXOF256 | TupleHash256/TupleHashXOF256 | ParallelHash256/ParallelHashXOF256 | 136 bytes |
All SP 800-185 public APIs should accept byte strings first. Test-only bit-string support may be added for official examples and edge cases.
All SP 800-185 implementations depend on the same encoding primitives.
| Helper | Purpose | Release rule |
|---|---|---|
left_encode(x) |
Self-delimiting integer, length byte first. | Validate boundary values and examples, including 0. |
right_encode(x) |
Self-delimiting integer, length byte last. | Validate boundary values and examples, including 0. |
encode_string(S) |
left_encode(len(S)) followed by S. |
Length is in bits, not bytes. |
bytepad(X, w) |
left_encode(w) followed by X, then zero-padded to a multiple of w. |
Reject non-positive w; test rates 168 and 136. |
substring(X, a, b) |
Bit substring helper. | Needed for bit-level and ParallelHash conformance tests. |
Implementation detail:
- Use
BigIntonly where needed for the formal2^2040validity ceiling. Public byte APIs may reasonably reject lengths that exceed Dart memory orintcapabilities before attempting allocation. - Internal length variables must be named in bits where the standard uses
bits (
len(S),L) and bytes where the standard uses bytes (B, rates).
Definitions:
cSHAKE128(X, L, N, S)cSHAKE256(X, L, N, S)
Rules:
- If
NandSare both empty, return SHAKE with the same input and output length. - Otherwise absorb
bytepad(encode_string(N) || encode_string(S), rate) || Xwith cSHAKE's domain separation. Nis a function-name string. Ordinary users should generally leave it empty. Standard-derived functions use fixed names such asKMAC.Sis the customization string. API docs must say different customization strings produce unrelated outputs for the same input, within the standard's security model.
API target:
final out = CShake128.hash(
message,
outputLength: 64,
functionName: Uint8List(0),
customization: ascii.encode('tenant-a'),
);Definitions:
KMAC128(K, X, L, S)KMAC256(K, X, L, S)KMACXOF128(K, X, L, S)KMACXOF256(K, X, L, S)
Rules:
Kis encoded withbytepad(encode_string(K), rate).- Fixed-output KMAC appends
right_encode(L). - KMACXOF appends
right_encode(0)and then squeezes the requested output. - The function-name string is
KMAC. - API docs must warn that applications should not select a key shorter than the required security strength.
- API docs must warn that short MAC tags reduce online forgery resistance.
API target:
final tag = Kmac256.mac(
key,
message,
outputLength: 32,
customization: ascii.encode('pqcrypto:v1'),
);Recommended public behavior:
- Throw
ArgumentErrorfor empty keys only if the chosen API policy forbids them. The standard allows arbitrary key lengths, but secure use guidance requires sufficient key length. If empty keys are allowed for test vectors, the safe API should still offer a checked mode. - Provide
minimumRecommendedKeyBytesconstants: 16 for 128-bit security and 32 for 256-bit security. - Provide
minimumRecommendedTagBytesguidance, but do not hardcode one tag size into the primitive.
Definitions:
TupleHash128(X, L, S)TupleHash256(X, L, S)TupleHashXOF128(X, L, S)TupleHashXOF256(X, L, S)
Rules:
- Encode each tuple element with
encode_string. - Preserve empty elements. The tuple
[A, empty, B]is different from[A, B]. - Fixed-output TupleHash appends
right_encode(L). - TupleHashXOF appends
right_encode(0). - The function-name string is
TupleHash.
API target:
final digest = TupleHash256.hash(
[firstField, secondField, Uint8List(0)],
outputLength: 64,
customization: ascii.encode('record-hash'),
);Tests must prove that tuple boundary changes alter output:
[ab, c]differs from[a, bc].[a, empty, b]differs from[a, b].- fixed-output and XOF mode differ for the same visible output length.
Definitions:
ParallelHash128(X, B, L, S)ParallelHash256(X, B, L, S)ParallelHashXOF128(X, B, L, S)ParallelHashXOF256(X, B, L, S)
Rules:
Bis the block size in bytes and must be greater than 0.- Each input block is hashed with cSHAKE using empty
NandS. - Inner block digest length is 256 bits for the 128-bit function and 512 bits for the 256-bit function.
- The final input starts with
left_encode(B), includes each inner digest, then appendsright_encode(n)and eitherright_encode(L)orright_encode(0)for XOF mode. - The function-name string is
ParallelHash.
API target:
final digest = ParallelHash128.hash(
largeMessage,
blockSize: 8192,
outputLength: 32,
);Implementation strategy:
- First release may use sequential processing while preserving the exact ParallelHash transcript.
- A later optimization can parallelize block hashing behind the same tests.
- Do not imply the first release is faster than SHAKE for all inputs. Benchmark before making performance claims.
Target package structure:
lib/src/common/
keccak.dart # Keccak-f[1600], SHA3-224/256/384/512, SHAKE128/256, XOF
shake.dart # Compatibility wrappers for SHAKE users
sp800_185.dart # cSHAKE, KMAC, TupleHash, ParallelHash public/internal APIs
test/
data/
FIPS202/
README.md
manifest.json
examples/... # hash-pinned NIST example files or normalized vectors
SP800185/
README.md
manifest.json
examples/... # hash-pinned cSHAKE/KMAC/TupleHash/ParallelHash vectors
keccak_test.dart
fips202_examples_test.dart
sp800_185_encoding_test.dart
sp800_185_cshake_test.dart
sp800_185_kmac_test.dart
sp800_185_tuplehash_test.dart
sp800_185_parallelhash_test.dart
Guidance:
- Keep
keccak.dartas the primitive owner. Avoid duplicating sponge logic insp800_185.dart. - Add a private constructor or internal helper that can initialize Keccak with a preabsorbed customization block if profiling proves it matters.
- Keep public APIs byte-oriented unless and until a bit-string abstraction has a clear user story.
- Keep test-only bit support small and isolated. Do not contaminate normal APIs with bit-level complexity if the package cannot ergonomically support it.
- Continue avoiding runtime dependencies. Dev-only vector tooling is acceptable
if it is isolated from
lib/and documented.
The final public API should make standard use obvious and unsafe ambiguity harder to express.
final digest224 = sha3224(message);
final digest384 = sha3384(message);
final xof = Shake256.xof(seed);
final block = xof.squeeze(64);
final customized = CShake256.hash(
message,
outputLength: 64,
customization: Uint8List.fromList('app-domain'.codeUnits),
);
final tag = Kmac256.mac(
key,
message,
outputLength: 32,
customization: Uint8List.fromList('mac-domain'.codeUnits),
);
final tupleDigest = TupleHash128.hash(
[header, payload, trailer],
outputLength: 32,
);
final parallelDigest = ParallelHash256.hash(
largeMessage,
blockSize: 8192,
outputLength: 64,
);Proposed exports:
export 'src/common/keccak.dart'
show sha3224, sha3256, sha3384, sha3512, shake128, shake256;
export 'src/common/shake.dart' show Shake128, Shake256;
export 'src/common/sp800_185.dart'
show
CShake128,
CShake256,
Kmac128,
Kmac256,
KmacXof128,
KmacXof256,
TupleHash128,
TupleHash256,
TupleHashXof128,
TupleHashXof256,
ParallelHash128,
ParallelHash256,
ParallelHashXof128,
ParallelHashXof256;API design rules:
- All output lengths in public byte APIs are bytes.
- Any lower-level internal helper that takes bits must include
Bitsin the name, for exampleoutputLengthBits. - Reject negative output lengths.
- For KMAC, distinguish fixed-output and XOF mode with separate methods or
classes. Do not use a boolean that silently changes
right_encode(L)toright_encode(0). - For ParallelHash, reject
blockSize <= 0. - For tuple inputs, copy or consume
Uint8Listdefensively according to the existing repo style. Do not store caller-owned mutable buffers in reusable keyed objects unless documented.
FIPS 202 and SP 800-185 are defined on bit strings, and NIST publishes non-byte-aligned examples. Dart APIs naturally operate on bytes. This mismatch must be explicit.
Recommended policy:
- Public v1 APIs accept only byte strings and output whole bytes.
- If a caller requests non-byte behavior through a future API, the type must represent both bytes and bit length.
- The test suite includes a small internal
BitStringhelper for NIST example parsing. - The documentation says byte-only public APIs are a deliberate limited implementation choice permitted by SP 800-185, not an oversight.
- Broad "full standard" wording is withheld until non-byte examples are either supported in public APIs or the claim is narrowed to byte-oriented inputs.
Internal helper sketch:
final class BitString {
const BitString(this.bytes, this.bitLength);
final Uint8List bytes;
final int bitLength;
}The helper should be used only in tests unless product requirements justify a public bit-string API.
The corpus must be reproducible and source-scoped.
NIST lists example files for each of:
- SHA3-224
- SHA3-256
- SHA3-384
- SHA3-512
- SHAKE128
- SHAKE256
The listed input lengths are:
- 0 bits
- 5 bits
- 30 bits
- 1600 bits
- 1605 bits
- 1630 bits
There is also a SHAKE truncation sample for output bit lengths not divisible by 8.
Release expectation:
- Check in normalized
.jsonor.rspvectors undertest/data/FIPS202/, or check in a manifest plus a tool that fetches, hashes, and normalizes the NIST PDFs. - Include the original NIST URLs and retrieval date in
test/data/FIPS202/README.md. - Include SHA-256 hashes for source files and normalized vectors.
- Run a discovered
test/fips202_examples_test.dartby default underdart test. - VM-only tests are allowed for PDF/file parsing tools, but the normalized vector tests should run on web where practical.
NIST lists example files for:
- cSHAKE
- KMAC
- KMACXOF
- TupleHash
- TupleHashXOF
- ParallelHash
- ParallelHashXOF
Release expectation:
- Check in normalized vectors under
test/data/SP800185/. - Cover both 128-bit and 256-bit security strength variants.
- Cover fixed-output vs XOF mode separation.
- Cover empty customization strings and non-empty customization strings.
- Cover tuple-boundary edge cases beyond official examples.
- Cover ParallelHash with more than one block.
Add tests for:
- negative output lengths;
- unsupported non-byte inputs through public byte APIs;
- invalid
bytepadwidth; - invalid ParallelHash block size;
- KMAC keys below recommended length in checked/safe mode;
- fixed-output KMAC vs KMACXOF distinction;
- fixed-output TupleHash/ParallelHash vs XOF distinction;
- cSHAKE fallback to SHAKE when
NandSare empty; - different cSHAKE customization strings yielding different outputs;
- tuple-boundary ambiguity resistance;
- no accidental mutation of caller inputs.
FIPS 202 and SP 800-185 primitives are mostly fixed-control-flow transforms, but the repo still needs disciplined handling.
Security rules:
- Do not claim hard constant-time behavior for Dart.
- Keep Keccak round control flow independent of secret data.
- Avoid secret-dependent branches in KMAC keyed object reuse paths where practical.
- Do not log KMAC keys, intermediate sponge state, customization strings that may contain secrets, or derived output.
- If reusable KMAC contexts are added, document whether keys are copied, retained, and zeroized.
- Zeroize temporary key-encoding buffers with best-effort
secureZerowhere possible. - Treat output length as a security parameter in docs.
- For KMAC, document that applications should choose key length at least equal to the required security strength.
Misuse language:
- SHAKE and cSHAKE are XOFs. Short requested output lengths reduce available collision and preimage strength.
- KMAC is a MAC/PRF construction, not HMAC-SHA3.
- TupleHash is for unambiguous tuple encoding. Do not replace it with raw concatenation.
- ParallelHash is not automatically faster in a sequential implementation.
Portability is release-blocking:
- Dart VM
- dart2js
- dart2wasm
Performance gates:
- Benchmark SHA3-256, SHAKE256, KMAC256, TupleHash256, and ParallelHash256 on small, medium, and large inputs.
- Compare ParallelHash sequential implementation against SHAKE/SHA3 for large inputs before making performance claims.
- Preserve the current 32-bit lane-half arithmetic unless a replacement is proven by the FIPS 202 corpus and web tests.
- Add benchmarks under the existing performance plan rather than mixing them into functional KAT tests.
The roadmap target is 0.6.0. Milestones M0-M6 are ordered so that FIPS 202 can be completed before SP 800-185 derived functions depend on it. Any unfinished standards surface that misses 0.6.0 moves to 0.7.0 with the same evidence requirements; no issue may be closed by downgrading public wording to hide a partial implementation.
Status: this guide.
Deliverables:
- Publish this document.
- Add GitHub issues SHA3-00 through SHA3-12.
- Add
sha3label. - Sync INDEX.md, ROADMAP.md, PROGRESS_TRACKER.md, FIPS_COMPLIANCE.md, and ARCHITECTURE.md.
Deliverables:
- Preserve SHA3-224 and SHA3-384 coverage while closing the remaining corpus and non-byte examples.
- Add rate/capacity/suffix table tests.
- Add Keccak round constant and rho-offset tests.
- Normalize and check in FIPS 202 examples.
- Add byte-oriented example tests and test-only bit-string harness.
- Update docs to say "FIPS 202 family complete" only after corpus gates pass.
Deliverables:
- Add
sp800_185.dart. - Implement and test encodings.
- Implement cSHAKE128/256.
- Add cSHAKE NIST vectors.
- Add cSHAKE fallback and customization tests.
Deliverables:
- Implement KMAC128/256 and KMACXOF128/256.
- Add NIST KMAC/KMACXOF vectors.
- Add safe-use key/tag length guidance.
- Add best-effort zeroization around temporary key encodings.
Deliverables:
- Implement TupleHash128/256 and TupleHashXOF128/256.
- Add NIST TupleHash vectors.
- Add tuple-boundary and empty-element tests.
Deliverables:
- Implement sequential ParallelHash128/256 and XOF variants.
- Add NIST ParallelHash vectors.
- Add block-size validation and multi-block tests.
- Add benchmarks before claiming any speed advantage.
Deliverables:
- All child issues closed for the surfaces being released.
dart format --output=none --set-exit-if-changed .dart analyzedart test test/keccak_test.dart test/fips202_examples_test.dartdart test test/sp800_185_encoding_test.dart test/sp800_185_cshake_test.dart test/sp800_185_kmac_test.dart test/sp800_185_tuplehash_test.dart test/sp800_185_parallelhash_test.dartdart testdart test -p chromedart test -p chrome --compiler dart2wasmdart pub publish --dry-run- README, changelog,
pubspec.yaml, docs, and issue tracker agree on the exact supported surfaces.
| ID | GitHub | Title | Priority | Gate |
|---|---|---|---|---|
| SHA3-00 | #48 | Epic: FIPS 202 and SP 800-185 to release | P0 | All child issues closed. |
| SHA3-01 | #36 | Source corpus and NIST example-vector provenance | P0 | test/data/FIPS202 and test/data/SP800185 manifests. |
| SHA3-02 | #37 | Complete FIPS 202 SHA3-224/SHA3-384 APIs | P0 | Done: SHA3-224/384 NIST vectors pass. |
| SHA3-03 | #38 | FIPS 202 conformance harness for bit-level examples | P0 | 0/5/30/1600/1605/1630-bit examples covered or explicitly scoped. |
| SHA3-04 | #39 | Keccak constants, suffix, rate, and capacity tests | P0 | Direct table and suffix tests pass. |
| SHA3-05 | #40 | SP 800-185 encoding helpers | P0 | left_encode, right_encode, encode_string, bytepad tests pass. |
| SHA3-06 | #41 | cSHAKE128/cSHAKE256 | P0 | NIST cSHAKE vectors and SHAKE fallback pass. |
| SHA3-07 | #42 | KMAC128/KMAC256 and KMACXOF | P0 | NIST KMAC/KMACXOF vectors plus misuse tests pass. |
| SHA3-08 | #43 | TupleHash and TupleHashXOF | P1 | NIST vectors plus tuple-boundary tests pass. |
| SHA3-09 | #44 | ParallelHash and ParallelHashXOF | P1 | NIST vectors plus multi-block tests pass. |
| SHA3-10 | #45 | Security, zeroization, and API misuse docs | P1 | KMAC key/tag guidance and no-overclaim docs complete. |
| SHA3-11 | #46 | VM/web portability and performance benchmarks | P1 | VM, dart2js, dart2wasm gates and benchmark report complete. |
| SHA3-12 | #47 | Release docs, changelog, and package metadata | P0 | Release wording matches evidence and pub publish --dry-run is clean. |
Update these files whenever the implementation state changes:
README.mdCHANGELOG.mdpubspec.yamldescription/topics if needed- INDEX.md
- ROADMAP.md
- PROGRESS_TRACKER.md
- FIPS_COMPLIANCE.md
- ARCHITECTURE.md
- ENGINEERING_GUIDE.md
- SECURITY_AUDIT.md
- PERFORMANCE.md
Documentation must always say which surfaces are implemented and tested. Avoid "full SHA-3" shorthand unless both FIPS 202 and SP 800-185 context makes the meaning unambiguous.
The complete FIPS 202/SP 800-185 release is done only when:
- all issue-map tasks for the release scope are closed;
- all implemented functions are backed by checked-in NIST examples;
- byte-oriented public APIs are documented precisely;
- any non-byte limitation is explicit;
- VM and web compiler tests pass;
- no runtime dependency is added;
- KMAC security guidance is in API docs and README;
- no public wording exceeds algorithm/vector evidence;
dart pub publish --dry-runhas zero warnings; and- the release tag points to the same commit that was published.
| Surface | Current status | Required next action |
|---|---|---|
| Keccak-f[1600] | Present | Direct constants/table tests are present; preserve coverage. |
| SHA3-224 | Present | Preserve rate 144 bytes and 28-byte output coverage. |
| SHA3-256 | Present | Expand official vector coverage. |
| SHA3-384 | Present | Preserve rate 104 bytes and 48-byte output coverage. |
| SHA3-512 | Present | Expand official vector coverage. |
| SHAKE128 | Present | Expand official vector coverage and non-byte output handling. |
| SHAKE256 | Present | Expand official vector coverage and non-byte output handling. |
| cSHAKE | Missing | Implement after encoding helpers. |
| KMAC/KMACXOF | Missing | Implement after cSHAKE. |
| TupleHash | Missing | Implement after cSHAKE. |
| ParallelHash | Missing | Implement after cSHAKE and benchmark sequential baseline. |
Before any release announcement:
- Which FIPS 202 functions are implemented?
- Which SP 800-185 functions are implemented?
- Are all claimed functions covered by checked-in NIST examples?
- Are byte-only limitations documented?
- Did
dart test -p chromeanddart test -p chrome --compiler dart2wasmpass? - Did
dart pub publish --dry-runreport zero warnings? - Does README avoid CMVP/FIPS 140 language?
- Does CHANGELOG list exact surfaces, not broad claims?
- Does
doc/FIPS_COMPLIANCE.mddistinguish algorithm evidence from module validation? - Did the release owner re-check NIST FIPS 202 and SP 800-185 pages for updated planning notes or final revisions?