Algorithm-agile signing: Ed25519 / ML-DSA-65 (FIPS 204) / hybrid
| Tier | foundation |
| Role | unclassified (baselined) |
| Path | crates/foundation/crypto-sign |
| Edition | 2021 |
| Targets | foundation_crypto_sign, conformance |
| Public items | 0 across 0 modules |
| Tests | 33 |
What it is for
Algorithm-agile signing library crate.
foundation-crypto-sign makes the signing algorithm a datum instead of a hardcoded curve, so a call site can migrate from classical Ed25519 to post-quantum ML-DSA-65 (FIPS 204) — or run both at once in a hybrid signature — without changing its shape. See docs/userstories/sprint-3.22-crypto-sign.md for the full design and the NIST IR 8547 migration timeline this exists to serve.
# Non-goals
KMS/key custody, ML-DSA-44/-87, SLH-DSA, ML-DSA context strings, and PEM/PKCS#8 interop are explicitly out of scope for this crate.
Capabilities
No public items.
How to use it
No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.
Module structure
No public modules: the crate root is its whole surface.
Public surface
No public items.
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
Error | error::Error |
SigAlg | alg::SigAlg |
Signature | sig::Signature |
{SigningKey,VerifyingKey} | keys::{SigningKey,VerifyingKey} |
Boundary
Depends on no other workspace tier.
Shares tier foundation with 27 other crates: foundation-audit-log, foundation-basemodels, foundation-bounded-io, foundation-conversation-closure, foundation-decisioning, foundation-encounter-vocabulary, foundation-fs-metadata, foundation-i18n, … (27 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | foundation |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/foundation/crypto-sign |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
base64 | ^0.22 | — | no | always |
ed25519-dalek | ^2 | zeroize | no | always |
ml-dsa | =0.1.1 | alloc, zeroize | no | always |
rand_core | ^0.6 | getrandom | yes | always |
serde | ^1 | derive | no | always |
signature | ^2 | — | no | always |
thiserror | ^2 | — | no | always |
zeroize | ^1 | derive | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
serde_json | ^1 | — | no | always |
Build. None.
Depended on by. 5 workspace crates.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_foundation_audit_log["foundation-audit-log"] -->|uses| SELF n_foundation_license["foundation-license"] -->|uses| SELF n_operations_block_imaging["operations-block-imaging"] -->|uses| SELF n_platform_privacy_scan_api["platform-privacy-scan-api"] -->|uses| SELF n_tools_ir_triage["tools-ir-triage"] -->|uses| SELF SELF["foundation-crypto-sign"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
| Feature | Enables | On by default |
|---|---|---|
default | — | yes |
keygen | dep:rand_core, ed25519-dalek/rand_core | no |
flowchart LR n_default["default"] n_keygen["keygen"] --> n_dep_rand_core["dep:rand_core"] n_keygen["keygen"] --> n_ed25519_dalek_rand_core["ed25519-dalek/rand_core"]
Targets
| Kind | Name | Source |
|---|---|---|
| lib | foundation_crypto_sign | `src/lib.rs` |
| test | conformance | `tests/conformance.rs` |
Error model
No public error type was detected: no public item declares a type named *Error, and no public signature returns one.
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | none detected |
| async runtime | none detected |
| database access | none detected |
| network I/O | none detected |
| unsafe code | none detected |
| environment variables | none detected |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
5 workspace crates depend on this one: foundation-audit-log, foundation-license, operations-block-imaging, platform-privacy-scan-api, tools-ir-triage.
Verification
| Kind | Count |
|---|---|
| Unit tests | 7 |
| Integration tests | 26 |
| Examples | 0 |
| Doctests | 0 |
What the tests establish, by name:
fips_204_and_rfc_8032_size_constants_are_exact—tests/conformance.rsfrom_bytes_rejects_oversized_signature_material—tests/conformance.rsfrom_bytes_rejects_wrong_length_signing_key_material—tests/conformance.rshybrid_verification_fails_when_the_ed25519_half_is_invalid—tests/conformance.rshybrid_verification_fails_when_the_ml_dsa_half_is_invalid—tests/conformance.rshybrid_verification_fails_with_invalid_signature_when_both_halves_are_invalid—tests/conformance.rsround_trip_succeeds_for_every_algorithm—tests/conformance.rssignature_from_bytes_ed25519_has_no_length_correct_invalid_input—tests/conformance.rssignature_from_bytes_rejects_invalid_ml_dsa_65_encoding—tests/conformance.rssignature_from_encoded_rejects_garbage—tests/conformance.rssignature_serde_round_trips_for_every_algorithm—tests/conformance.rssignature_text_encoding_round_trips_for_every_algorithm—tests/conformance.rssigning_an_empty_message_is_valid_for_every_algorithm—tests/conformance.rstampering_with_the_message_fails_verification_for_every_algorithm—tests/conformance.rstampering_with_the_signature_fails_verification_for_every_algorithm—tests/conformance.rsverifying_hybrid_key_against_plain_ed25519_signature_returns_typed_error—tests/conformance.rsverifying_key_from_bytes_ml_dsa_65_has_no_length_correct_invalid_input—tests/conformance.rsverifying_key_from_bytes_rejects_invalid_ed25519_curve_point—tests/conformance.rsverifying_key_from_encoded_rejects_garbage—tests/conformance.rsverifying_key_from_encoded_rejects_unknown_tag—tests/conformance.rsverifying_key_from_encoded_rejects_wrong_length_payload—tests/conformance.rsverifying_key_from_encoded_tag_is_case_sensitive—tests/conformance.rsverifying_key_serde_round_trips_for_every_algorithm—tests/conformance.rsverifying_key_text_encoding_round_trips_for_every_algorithm—tests/conformance.rsverifying_with_mismatched_algorithms_returns_typed_error—tests/conformance.rsverifying_with_the_wrong_key_fails_for_every_algorithm—tests/conformance.rsdecode_tagged_does_not_misfire_on_the_largest_legitimate_encoded_form—src/alg.rsdecode_tagged_rejects_oversized_input_before_split_once—src/alg.rsfrom_tag_rejects_unknown_and_wrong_case—src/alg.rstag_round_trips_through_from_tag—src/alg.rs- _… 3 more_
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 0 | 0 |
Public modules with a //! block | 0 | 0 |
Metrics
| Metric | Value |
|---|---|
| Rust source files | 5 |
| Source lines | 979 |
| Code lines | 589 |
| Public API items | 0 |
| Public modules | 0 |
| Tests | 33 |
| Examples | 0 |
| Cargo features | 2 |
| Direct runtime dependencies | 8 |
| Workspace reverse dependencies | 5 |
pie showData
title Rust source composition
"Code" : 589
"Blank or comment" : 390
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.