Skip to main content

Module verify

Module verify 

Source
Expand description

Partial-disclosure verification: prove and verify that a single path, chunk, or byte range belongs to a commit id, with proof bytes on the order of a few KiB regardless of repository size.

§Trust model

A verified Disclosed proves that its payload bytes are exactly the content the given commit_id commits to at path — nothing more. It does not prove:

  • that the disclosed path is the only thing at that location (no sibling-completeness claim — see the closure profile, issue #1015 PR 3, for that);
  • anything about who the signer is — signer/signature_valid report whether the embedded Ed25519 signature verifies against the embedded public key; binding that key to an identity or trust level is application policy (trust roots), exactly as crate::sign::verify_commit already documents.

Every function in this module verifies against an object id, never a bare (pre-domain-wrap) inner root or an unauthenticated byte range — see crate::merkle’s module docs for why that distinction matters.

Wire format, verification algorithm, and bounds are pinned in docs/specs/SPEC-DISCLOSURE.md; golden vectors live under rust/tests/golden/disclosure/. See issue #1015 (verifier kit) PR 2.

§Layering

verify_object_id, verify_path, verify_chunk_with_meta, verify_blob_slice, and verify_blob_len_proof are the small, independently-useful primitives (each corresponds to one hop of the authentication chain: commit → tree steps → leaf → chunk/slice). verify_disclosure decodes a self-contained wire bundle (§ below) and composes them into one call. build_disclosure_from is the producer side, generic over any verifying crate::store::ObjectSource (the on-disk store, an in-memory overlay, or a server-side index or object CAS); build_disclosure is its thin wrapper over crate::store::ObjectStore. The builder’s source trait is distinct from this module’s ObjectSource, the non-verifying fetch(&mut self) trait the closure walker reads through. Full disclosure — every reachable object against a commit id — is verify_closure, verify_closure_streaming, verify_closure_packs, and verify_closure_manifest, with verify_closure_store and export_closure as native store-backed operations (issue #1015 PR 3).

Everything here, the builder included, compiles with --no-default-features and targets wasm32-unknown-unknown; no separate feature gate is needed since mkit-core itself is a std crate (see the crate root docs).

§Wire bundle (verify_disclosure / build_disclosure)

magic   = "MKDP"            (4 raw bytes)
version: u8 = 2
commit_id: [u8; 32]
commit_bytes: Vec<u8>        <= 4 MiB
steps: Vec<Step>             <= MAX_TREE_DEPTH (128), root first
  Step { name: Vec<u8> (1..=255), mode: u8, child_id: [u8; 32],
         inner_root: [u8; 32], position: u32, proof: Proof (max_items = 1) }
payload_kind: u8
  0 Object { bytes: Vec<u8> <= MAX_RAW_OBJECT_SIZE }
  1 Chunk  { total_size: u64, chunk_size: u32, index: u32,
             inner_root: [u8; 32], proof: Proof (max_items = 2),
             bytes: Vec<u8> }
  2 Range  { chunk: Option<ChunkHdr>, offset_in_blob: u64, len: u64,
             slice: Vec<u8>, chunk_len_proofs: Vec<LenProof> }
    ChunkHdr { total_size: u64, chunk_size: u32, index: u32,
               inner_root: [u8; 32], chunk_id: [u8; 32],
               proof: Proof (max_items = 2) }
    LenProof { index: u32, chunk_id: [u8; 32],
               proof: Proof (max_items = 1), slice: Vec<u8> }

All integers are big-endian, every length is an LEB128 varint, arrays are raw — commonware-codec conventions (SPEC-CONVENTIONS §3; crate::transfer’s packlist node is the existing precedent for this house style). The whole bundle is capped at MAX_BUNDLE_BYTES; trailing bytes are rejected.

ChunkHdr.chunk_id is not literal to issue #1015’s original design note, which omitted it: without an explicit chunk id, a verifier reading a byte-range bundle would have no value to check the Bao slice against before folding it into the enclosing ChunkedBlob’s multi-proof (Bao’s SliceDecoder always requires the expected root up front — it cannot recover an unknown one from the slice, by construction). Adding this field closes that gap; it is exactly the value verify_chunk_with_meta’s multi-proof authenticates, so a forged chunk_id fails to fold to the enclosing ChunkedBlob’s id.

Modules§

proof_size
Exact proof wire-size planning from canonical object metadata. Exact MKDP/MKDS lengths from metadata, without constructing Merkle or Bao proofs. Chunk lengths describe canonical Blob content, excluding its ten header bytes. All results enforce the 64 MiB wire cap.
span
MKDS v1 multi-chunk range proofs (SPEC-DISCLOSURE §8).

Structs§

ClosureExport
Encoded closure plus the raw-only packs it indexes.
ClosureManifest
Convenience index of a closure export: magic "MKCL", version 1, root id, mode, and the pack_key of each pack in order.
ClosureReport
Outcome of walking a supplied object set from root in mode.
Disclosed
A verified partial disclosure: payload is exactly the content commit_id commits to at path, and nothing more. See the module docs for the precise trust model.
PathVerified
The result of walking and verifying a path from a commit’s tree_hash down to a leaf.
PushReport
What verify_push found. The push is acceptable only when Self::is_accepted holds.
Step
One authenticated hop of a path: the entry name/mode proven at position under its parent (a commit’s tree_hash, or the previous step’s child_id), via a single-leaf Proof.

Enums§

DisclosedPayload
The disclosed content of a Disclosed result.
Selector
What build_disclosure discloses about the leaf its path reaches.
VerifyError
Errors verifying (or, natively, building) a disclosure.

Constants§

MAX_BUNDLE_BYTES
Hard cap on a whole encoded disclosure bundle, checked before any decode work happens. mkit-wasm additionally caps decoded objects at 16 MiB; this 64 MiB ceiling is the wasm32-agnostic bound this crate itself enforces.
MAX_CLOSURE_PACKS
Hard cap on the number of packs a closure manifest may list.

Traits§

ObjectSource
Provides a pull-based source for canonical object bytes.

Functions§

build_disclosure
Build a disclosure bundle proving selector’s content at path under commit_id, reading only from store. path empty with Selector::Object discloses the root tree.
build_disclosure_from
Build a disclosure bundle proving selector’s content at path under commit_id, reading only through source: any crate::store::ObjectSource (the on-disk store, an crate::store::EphemeralSink, or a server-side repository index or object CAS). Not to be confused with ObjectSource, this module’s non-verifying closure-walker trait (fetch(&mut self)).
export_closure
Walk store in mode, write raw-only packs of the reachable objects in sorted id order, and return the encoded manifest plus packs. Native-only (ObjectStore).
verify_blob_len_proof
Verify a Bao slice over canonical bytes 0..10 of the object whose id is blob_id, and return the le32 length field at bytes 6..10 — the object’s own declared content length, authenticated by the first Bao leaf chunk (Bao’s encoding header is not what is trusted here; the canonical prologue bytes themselves are).
verify_blob_slice
Verify a Bao slice proving len content bytes at content_offset belong to the object (Blob, or one ChunkedBlob chunk) whose canonical-bytes BLAKE3 is blob_id. slice is expected in the format bao::encode::SliceExtractor produces over the object’s canonical bytes (prologue ‖ le32(len) ‖ data) — so a Bao-authenticated content offset o maps to Bao offset o + 10, and the returned root equals the object’s own id (SPEC-OBJECTS §3).
verify_chunk_with_meta
Verify that a ChunkedBlob’s claimed total_size/chunk_size and the chunk chunk_hash at index both belong to the ChunkedBlob whose id is chunked_id, via one multi-proof over BMT positions {0, index + 1}.
verify_closure
Re-hashes every supplied object and walks from root with children(obj, mode). Store-less: the caller provides the object bytes. This compatibility path is implemented by the same pull-based walker as verify_closure_streaming, with an in-memory source keyed by each successfully derived id, followed by the legacy supplied-set unreferenced pass.
verify_closure_manifest
Decode the manifest, reject it if its root is not expected_root, check pack count and pack_key equality in order, then verify_closure_packs. mode comes from the manifest (it only widens or narrows the walk; the report carries it). The caller supplies the trusted root; the manifest is a locator, never a trust anchor.
verify_closure_packs
Iterates each pack with PackEntries. Any delta or compressed entry is a profile violation — the closure profile is raw-only so a wasm verifier (no pack-zstd) can consume it. Raw payloads are indexed by their derived ids and served as borrowed slices into the original pack buffers.
verify_closure_store
Verifies a closure by reading the local ObjectStore on demand.
verify_closure_streaming
Walks a closure by fetching each requested id only when the BFS reaches it. Bytes are deserialized, re-hashed, and discarded after their child ids are extracted, so the walk retains object ids rather than the complete object set. A fetch-by-id source that returns bytes whose derived id differs from the requested id reports corrupt under the requested id; this is intentionally different from the map path’s legacy missing + unreferenced classification for a parsable bit flip.
verify_disclosure
Decode and fully verify a disclosure bundle against commit_id.
verify_object_id
verify_path
Verify a path of Steps from a commit/remix’s tree_hash down to a leaf id, checking each step’s proof against the previous step’s child_id (the first against tree_hash itself).
verify_push
Verify the history a push introduces, before refs move.