URNs & Encryption
The byte-exact grammar, the rootless retrieval_key invariant, and the HKDF/GCM-SIV constants are in the Protocol section: URN & addressing and Cryptography.
The URN is the heart of dig-store. It is both the address that locates a resource and the secret that decrypts it.
URN format
urn:dig:<chain>:<storeId>[:<rootHash>][/<resourceKey>]
| Part | Role | Required |
|---|---|---|
urn:dig: | Scheme + namespace | Required (literal) |
<chain> | Chain identifier, e.g. chia | Required |
<storeId> | 64-hex store id | Required |
<rootHash> | Pin a specific generation; omit for the current one | Optional |
<resourceKey> | Which resource (content-root-relative path); omit for store-level | Optional |
Examples:
urn:dig:chia:285539…aade/readme.txt # current generation
urn:dig:chia:285539…aade:1a2b3c…/readme.txt # pinned to a generation
Preview the exact URN a file will have before you commit:
digs urn readme.txt
digs urn -A # every staged file
Two values, one string
When a client resolves a URN, it canonicalizes the string and derives two values from it — and from nothing else:
retrieval_key = SHA-256(canonical_urn) # WHERE the bytes are
decryption_key = HKDF-SHA256(ikm = canonical_urn, …) # WHAT decrypts them
- The retrieval key is the only address that leaves the client. It locates the encrypted chunks via the module's key table. The URN itself never goes to the host.
- The decryption key is an AES-256 key derived locally. The host never sees it and performs no decryption.
This split is what makes the URN a capability: possessing it is necessary and sufficient to both find and read a resource in a public store.
A URN without a rootHash derives a root-independent key, so the same key locates the resource across generations. You can list every resource's retrieval key with digs keys. This matters for the cipher choice below.