1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
//! # dig-capsule — the `.dig` capsule data plane, one curated API
//!
//! A **capsule** is one immutable store generation — the pair `(store_id, root_hash)`
//! — packaged as the `.dig` / DIGS artifact. This crate is the SINGLE front door to
//! everything that creates, manages, reads, or serves that artifact. Depend on just
//! `dig-capsule`; the internal implementation modules under `imp` are `pub(crate)`
//! plumbing you never name directly.
//!
//! This is a PURE facade over the inlined implementation: it re-exports and organizes
//! the modules by concept. It adds no `.dig` format logic and changes no format bytes
//! — the golden fixtures read byte-identically. The on-chain anchor (the CHIP-0035
//! singleton, storeId minting, generations/anti-rollback) and the CLI live in
//! [`dig-store`](https://github.com/DIG-Network/digs), which depends on this crate.
//!
//! ## Where to look — the concept modules
//!
//! Everything below reads without opening any implementation module.
//!
//! | Module | Covers | Feature |
//! |--------|--------|---------|
//! | [`capsule`] | Capsule identity, the size ladder, visibility, generations | base |
//! | [`urn`] | The canonical `urn:dig:chia:…` scheme (`dig-urn-protocol`) + key derivation | `std` |
//! | [`format`] | The DIGS data section, codec, wire types, ABI, hashing | base |
//! | [`merkle`] | The ciphertext-leaf merkle tree + inclusion proofs | base |
//! | [`chunk`] | Content-defined (FastCDC) chunking | base |
//! | [`metadata`] | The metadata + public manifest | base |
//! | [`crypto`] | Native AEAD + Chia-BLS signing/verification | `crypto` |
//! | [`store`] | The local chunk-store / generation / staging model | `store` |
//! | [`compile`] | Files → self-serving `.dig` WASM module | `compile` |
//! | [`stage`] | The stage → compile build pipeline (the files→capsule entry) | `compile` |
//! | [`host`] | The wasmtime runtime that serves a module BLIND | `serve` |
//! | [`prover`] | Serving/execution proofs (§13) + Chia chain anchoring | `serve` |
//! | [`guest`] | The in-module served logic (low-level escape hatch) | `serve` |
//!
//! For the common path, `use dig_capsule::prelude::*;` pulls the most-used items.
//!
//! ## Feature flags — which consumer uses which
//!
//! The base surface (read / format / merkle / chunk / metadata) is always on and pulls
//! no wasmtime and no `blst`, and is `no_std + alloc`-clean so a slim consumer stays
//! light. The canonical URN scheme ([`urn`]) sits just above it under `std` (its
//! `dig-urn-protocol` owner is a `std` crate).
//!
//! - **`default = ["full"]`** — the whole API (`crypto + store + compile + serve`). What
//! `dig-store` and `dig-node` want.
//! - **`std`** — enables `std` (and the canonical [`urn`] module + `chunk::chunk_stream`).
//! - **`crypto`** — native AES-256-GCM-SIV AEAD + Chia-BLS (implies `std`).
//! - **`store`** — the on-disk generation / staging model (implies `std`).
//! - **`compile`** — the files→capsule pipeline (implies `store` + `crypto`).
//! - **`serve`** — the blind serve triad + serving proofs (implies `crypto`).
//! - **`risc0`** — the real RISC0 serving-proof circuit; OFF by default (needs the
//! RISC0 toolchain), implies `serve`.
//! - **`guest-wasm`** — the wasm32, no_std self-serving guest cdylib (exports the guest
//! ABI). Used by the build to produce the embedded guest wasm; not for consumers.
//!
//! A slim reader uses `dig-capsule = { version = "0.3", default-features = false }`
//! → the no_std base only.
//!
//! ## The browser counterpart
//!
//! The browser + Node read-crypto is the [`wasm_browser`] module, gated on the
//! **`wasm`** feature and shipped as the **`@dignetwork/dig-capsule-wasm`** npm
//! package (built with `wasm-pack build --no-default-features --features wasm`). Its
//! surface (`reconstructUrn`, `retrievalKey`, `deriveKey`, `verifyInclusion`,
//! `decryptResource`, `decryptResourceToText`, `readPublicManifest`, `version`) is
//! installed on `globalThis.digClient`. It produces byte-identical KDF/AEAD/URN/merkle
//! output to the native [`crypto`] path here — the two are the same contract on two
//! runtimes (§7 conformance, `tests/parity.rs`).
//!
//! ## A light read (no I/O)
//!
//! ```
//! use dig_capsule::prelude::*;
//!
//! // The default capsule size class is 128 MB (the single canonical size, #130).
//! let spec = CapsuleClass::DEFAULT.spec();
//! assert_eq!(spec.content_cap_bytes, 128_000_000);
//!
//! // A resource URN derives a stable, root-independent content key.
//! let urn = DigUrn::parse("urn:dig:chia:0000000000000000000000000000000000000000000000000000000000000000").unwrap();
//! let _key = urn.content_key();
//! ```
//!
//! ## The full build path (default features)
//!
//! ```no_run
//! // The files→capsule pipeline and the blind serve entry both resolve through the
//! // facade under the default (full) features — no implementation module is ever named.
//! use dig_capsule::stage::stage_and_compile;
//! use dig_capsule::host::serve_blind;
//! use dig_capsule::compile::Compiler;
//! ```
// no_std applies to the wasm32 no-`std`-feature build (the guest-wasm cdylib + any
// wasm consumer). On a native host the `cdylib` crate-type needs a panic handler and
// the release profile unwinds (neither is available in native no_std), so the crate
// stays `std`-the-language there even when the `std` FEATURE is off — the base is
// still no_std-CLEAN (its code uses only `core`/`alloc`), proven by the wasm32 guest
// build. Feature gates (`#[cfg(feature = "std")]`) are unaffected by this.
extern crate alloc;
// The inlined implementation (former `dig-capsule-*` member crates). PLUMBING —
// consumers use the curated facade modules below, never `imp::*` directly.
pub
/// The browser + Node read-crypto surface (the `@dignetwork/dig-capsule-wasm` npm
/// package): the wasm-bindgen exports installed on `globalThis.digClient`.
///
/// Compiled ONLY under the `wasm` feature (a `std` build with no chia-bls/wasmtime/
/// blst — see the feature docs above). The `#[wasm_bindgen]` exports are crate-global
/// regardless of this module nesting, so the JS surface + `globalThis.digClient` are
/// identical to the former standalone crate. The read crypto is byte-identical to the
/// native [`crypto`] path (§7 conformance, `tests/parity.rs`).
// ---------------------------------------------------------------------------
// Base concept modules (always compiled).
// ---------------------------------------------------------------------------
/// Capsule identity + the size ladder.
///
/// A capsule is the pair `(store_id, root_hash)` ([`Capsule`]); its canonical string
/// is `storeId:rootHash`. Each capsule is padded to a uniform blob sized by a
/// [`CapsuleClass`] so its size reveals nothing about the plaintext — the
/// [`CapsuleClass::DEFAULT`] is 128 MB, the single canonical size.
/// The DIG content URN scheme and its frozen retrieval-key derivation.
///
/// `urn:dig:chia:<store_id>[:<root>][/<resource_key>]` ([`DigUrn`]). The canonical
/// scheme, grammar, and key derivation are owned by the `dig-urn-protocol` crate —
/// the ONE ecosystem definition — and re-exported here so consumers reach them
/// through the facade. Two keys are derived from a URN, both FROZEN and shared
/// byte-for-byte with the browser verifier:
///
/// - [`DigUrn::retrieval_key`] = `SHA-256(canonical())` — the URN-identity key that
/// PINS the root (what the frozen conformance corpus fixes);
/// - [`DigUrn::content_key`] = `SHA-256(canonical_rootless())` — the root-INDEPENDENT
/// key a resolver uses to fetch and to seed the AES key (stable across generations).
///
/// Gated on `std`: `dig-urn-protocol` is a `std` crate (its errors implement
/// `std::error::Error`), so this module is unavailable in the no_std base — every
/// non-base feature (`crypto`/`store`/`compile`/`serve`) implies `std`.
///
/// [`Bytes32`]: crate::format::Bytes32
/// The DIGS on-disk/on-wire format: data section, codec, wire types, ABI, hashing.
///
/// The byte-exact layout is the normative contract (see the repo `SPEC.md`); every
/// change is additive (CLAUDE.md §5.1) so older `.dig` artifacts stay readable. The
/// submodules are re-exported whole so the entire section registry, codec, and wire
/// shapes are reachable here.
/// The content-commitment merkle tree over sealed chunk leaves + inclusion proofs.
///
/// A served [`MerkleProof`] verifies the served ciphertext to the capsule root; a
/// leaf is domain-separated by [`LEAF_TAG`]/[`NODE_TAG`].
/// Deterministic content-defined (FastCDC-line) chunking.
///
/// Chunk boundaries are byte-identical across platforms so content-addressed dedup is
/// stable. [`ChunkerConfig`] carries the commit defaults.
/// The store metadata manifest and the public file manifest.
/// The lightweight, wasmtime-free capsule reader.
///
/// [`Capsule::from_module_bytes`](crate::capsule::Capsule::from_module_bytes)
/// recovers the canonical `(store_id, root_hash)` from compiled `.dig` module
/// bytes using ONLY `wasmparser` + the no_std core — no wasmtime, no chia-bls,
/// no store. FAIL-CLOSED: it recomputes the merkle root from the embedded
/// `MerkleNodes` and rejects a forged `CurrentRoot` ([`ModuleReadError::RootMismatch`]).
///
/// SECURITY: `store_id` is the on-chain launcher id and is NOT self-verifiable
/// from module bytes — the caller MUST cross-check it against a trusted anchor
/// (URN / on-chain singleton / verified `ChainState`).
// ---------------------------------------------------------------------------
// Feature-gated concept modules.
// ---------------------------------------------------------------------------
/// Native capsule crypto: the AES-256-GCM-SIV chunk seal, HKDF key derivation, and
/// Chia-BLS signing/verification (blst-backed).
///
/// This is the AUTHORITATIVE native crypto. The pure, `blst`-free primitives that the
/// wasm-clean read path uses live under [`crypto::primitives`] — use those only when
/// you specifically need the no-`blst` variants.
/// The local store model: the chunk store, generation + history model, staging, and
/// diff — the on-disk model a capsule is committed from.
///
/// Note: [`store::Clock`] and its `FixedClock`/`SystemClock` are the STORE's clock
/// trait, distinct from [`host::Clock`].
/// The compiler: transform a generation's staged content into a single self-serving
/// `.dig` WASM module (deterministic, byte-identical).
///
/// Note: [`compile::CompilerError`] is the compiler's error enum, distinct from the
/// config-level `crate::capsule` compiler error.
/// The stage → compile build pipeline — the primary "files → capsule" entry point.
///
/// [`stage::stage_and_compile`] seals + chunks a file set, builds the ciphertext-leaf
/// merkle tree, persists the generation, and compiles a real self-serving module.
/// The wasmtime host runtime that serves a compiled module BLIND (it never decrypts or
/// inspects the served payload).
///
/// Note: [`host::Clock`] and its `FixedClock`/`SystemClock` are the HOST's clock trait,
/// distinct from [`store::Clock`].
/// Serving/execution proofs (§13) and Chia chain anchoring: the [`prover::Prover`] /
/// [`prover::Verifier`] pair, the [`prover::ChainSource`] abstraction with its live
/// [`prover::CoinsetChainSource`], and the mock backends used while the RISC0 circuit
/// matures. `program_hash = SHA-256(module_bytes)`.
/// The in-module served logic (the guest half of the serve triad) — the low-level
/// escape hatch for `get_content` / `get_proof` internals. Kept OUT of the [`prelude`]
/// on purpose; most callers use [`host`] instead.
// ---------------------------------------------------------------------------
// The curated, collision-free prelude.
// ---------------------------------------------------------------------------
/// The most-used items for `use dig_capsule::prelude::*;`.
///
/// Curated to be COLLISION-FREE: where a name exists in more than one module (e.g.
/// `Clock`, `CompilerError`, `Result`, `DecodeError`), the prelude picks none and you
/// reach for the module-scoped item instead.