Layer 2/3 · The self-defending module
Canonical reference:
digstore-compiler(pipeline.rs,inject.rs,filler.rs,config.rs) for the module;digstore-guest::content+digstore-hostfor the serving guest. The data it carries is the DIGS data section.
Fixed-size obfuscation
Every module's injected DIGS blob is padded to exactly uniform_blob_len (default FIXED_BLOB_LEN = 128 MiB), so all production stores compile to the same module size — leaking nothing about content size (config.rs:11-15,38-44; override DIGSTORE_UNIFORM_BLOB_LEN for tests).
Pipeline math (pipeline.rs:106-136): encode the blob with an empty Filler body → blob_len_without_filler; reject if it exceeds the budget (never truncate); filler_len = budget − blob_len_without_filler. Filler (id 11, unreferenced) is the ONLY variable section — it never touches leaves or CurrentRoot, so padding changes nothing served or proven.
Filler bytes are deterministic: a ChaCha20 keystream with seed = SHA-256(store_id || roothash || "digstore-filler-v1"), key = seed, nonce = 12 zero bytes, positional (so a shorter request is a prefix of a longer one) — filler.rs:7-28. Determinism is what makes compilation byte-identical.