Skip to main content

metamorphic_log/
lib.rs

1//! # metamorphic-log
2//!
3//! Tamper-evident, append-only **transparency log** engine and verification SDK
4//! for the Metamorphic platform. It implements the cryptographic *verification*
5//! core (RFC 6962 / RFC 9162 Merkle inclusion + consistency proofs over an
6//! ecosystem-fixed SHA-256 tree), wraps the [C2SP `tlog-tiles`] substrate for
7//! storage/serving, supports externally witnessed `checkpoint` / `signed-note`
8//! co-signing, layers in **hybrid post-quantum** checkpoint signatures, and adds
9//! CONIKS-style index privacy via a swappable VRF.
10//!
11//! ## Single source of truth for primitives
12//!
13//! This crate contains **no cryptographic primitives of its own**. Every hash,
14//! signature, KEM, and KDF comes from [`metamorphic_crypto`] — the audited,
15//! RustCrypto-only core. There is no parallel crypto stack here.
16//!
17//! ## What a transparency log does (and does not) provide
18//!
19//! - **Provides:** post-pin *continuity*, *anti-equivocation* (via independent
20//!   witnesses co-signing checkpoints), and *tamper-evidence* over an
21//!   append-only Merkle log.
22//! - **Does NOT provide:** first-contact / bootstrap trust. A transparency log
23//!   cannot tell you whether the *first* key you ever saw for a peer is
24//!   genuine — that is a Trust-On-First-Use (TOFU) problem your application
25//!   must handle separately from this library (e.g. out-of-band fingerprint or
26//!   safety-number verification).
27//!
28//! These layers state their PQ posture plainly: integrity, authentication,
29//! confidentiality, and commitments are post-quantum from day one; only
30//! index-privacy (the CONIKS VRF) defaults to a classical construction with a
31//! designed-in hybrid path. The primitives are not FIPS-validated, and this
32//! project does not claim FIPS validation.
33//!
34//! ## Standards spine
35//!
36//! - RFC 6962 / RFC 9162 — Merkle log + inclusion/consistency proofs
37//! - C2SP `tlog-tiles`, `tlog-witness`, `checkpoint` / `signed-note`
38//! - RFC 9381 — ECVRF-edwards25519 (CONIKS index privacy)
39//! - FIPS 203 / 204 + CNSA 2.0 — post-quantum primitives (via
40//!   [`metamorphic_crypto`])
41//! - NIST SP 800-56C / 800-108 — KDF roles
42//!
43//! [C2SP `tlog-tiles`]: https://github.com/C2SP/C2SP/blob/main/tlog-tiles.md
44//!
45//! ## Status
46//!
47//! Slices 1–5 are implemented.
48//!
49//! **Slice 1 (#327) — conformance core:** the canonical Layer-0 leaf encoding
50//! ([`leaf`]), the fixed RFC 6962 Merkle hashing ([`merkle`]), and RFC 6962 /
51//! RFC 9162 inclusion + consistency proof *verification* ([`proof`]). The leaf
52//! layer is application-agnostic: any app defines its own opaque record type
53//! under a versioned context label. As a worked, byte-locked conformance
54//! instance it ships [`leaf::key_history_v1`] (the format used by Mosslet, the
55//! first consumer).
56//!
57//! **Slice 2 (#329) — C2SP substrate (WRAP):** the [`tile`] module wraps the
58//! `tlog-tiles` substrate (tile coordinates, `tile/<L>/<N>[.p/<W>]` paths, and
59//! recompute-from-tiles consistent with [`merkle`]); [`checkpoint`] parses and
60//! serializes the `tlog-checkpoint` signed-tree-head body and wires it to the
61//! Slice-1 inclusion/consistency verifier; and [`note`] parses/serializes the
62//! `signed-note` format and verifies **classical Ed25519** witness co-signature
63//! lines via [`metamorphic_crypto::ed25519_verify`].
64//!
65//! **Slice 3 (#331) — additive hybrid post-quantum checkpoint signing (Layer
66//! 2):** [`note`] gains an additive [`note::SignatureType::MetamorphicHybrid`]
67//! line — the metamorphic-crypto **ML-DSA + classical composite** (strict-AND),
68//! assigned via the C2SP `0xff` escape with a versioned identifier so it never
69//! squats an assigned type. Classical Ed25519 stays byte-identical, so a
70//! checkpoint can be co-signed by both a witness-compatible Ed25519 key and our
71//! forward-secure PQ key; a verifier accepts any mix of trusted key types. The
72//! CONIKS VRF layer lands in Slice 4.
73//!
74//! **Slice 4 (#332) — CONIKS index privacy (Layer 3):** a swappable VRF
75//! ([`vrf`]) with a classical ECVRF-edwards25519-SHA512-TAI default (RFC 9381,
76//! via [`metamorphic_crypto`]) and a designed-in — not yet built — hybrid/PQ
77//! path; SHA3-512 hash-based [`commitment`]s binding an index to a value; and a
78//! per-namespace [`coniks`] directory whose lookups yield independently
79//! verifiable **presence** and **absence** (index-hiding) proofs over a sparse
80//! SHA3-512 prefix tree. Index privacy is the *only* classical property here;
81//! the commitments and everything below are post-quantum.
82//!
83//! **Slice 5 (#333) — per-namespace policy + declared == observed enforcement
84//! (Layer 0):** [`policy`] adds the signed, in-log, versioned
85//! [`policy::NamespacePolicy`] record that declares a namespace's selectable PQ
86//! posture (checkpoint suite/level, commitment-hash strength, VRF privacy mode)
87//! within the #324 safe menu — never touching the audited Layer-1 canonical
88//! bytes. A [`policy::SignedPolicy`] binds the record under the namespace root
89//! key via the Slice-3 composite primitive; a [`policy::PolicyChain`] enforces
90//! immutability-by-versioning and only-legal-strengthening migration. The
91//! headline is **declared == observed**: a verifier hard-rejects any checkpoint
92//! signature, CONIKS VRF suite, or commitment parameter whose *observed* posture
93//! disagrees with the *declared* one — using the metamorphic-crypto v0.8.1
94//! typed posture accessors, re-deriving no private wire tags. This makes posture
95//! *verifiable*, not stronger.
96
97#![forbid(unsafe_code)]
98#![warn(missing_docs)]
99
100pub mod checkpoint;
101pub mod commitment;
102pub mod coniks;
103mod encoding;
104pub mod error;
105pub mod leaf;
106pub mod merkle;
107pub mod note;
108pub mod policy;
109pub mod proof;
110pub mod tile;
111pub mod vrf;
112
113/// Browser **verification + monitor** SDK (`wasm-bindgen`), Slice 6.
114///
115/// A thin personality over the rlib core: every export base64/text-marshals its
116/// arguments and delegates straight to the verification functions in [`proof`],
117/// [`checkpoint`], [`note`], [`coniks`], and [`policy`]. It contains **no**
118/// parallel log or crypto logic, so the bytes it produces and the verifications
119/// it performs are identical to the native crate (proven by the cross-language
120/// byte-parity KAT). Only compiled for `wasm32`.
121#[cfg(target_arch = "wasm32")]
122pub mod wasm;
123
124pub use error::{Error, Result};
125pub use proof::{verify_consistency, verify_inclusion};