Use
The spend-key holder signs a policy for a fresh session key and writes a session file:
The delegate holds the session file and the viewing key. It makes the proofs, then issues the
receipt with no spend key:
--max,
is refused with outside its delegation; the regtest end-to-end run covers both.
How it works
The spend key signs a certificate underrk_c = ak + [alpha_c]G: the session key S, the
policy, and nothing else. For each spend the delegate:
- proves
rk_i − rk_c = [alpha_i − alpha_c]Gwith a Schnorr proof, as in same payer, so all the spends are under the sameak; - signs the receipt’s digest and the links with
S.
What it proves
The spend key’s holder authorizedS under this policy; the payment’s spends are under that
key; S vouched for this receipt within the policy.
Limits
- The delegate can’t spend, but it can decline to answer.
- There is no revocation mechanism. Bound a delegation with
--until. - Every receipt under one certificate carries it, so they are linkable to each other (not to the wallet’s other payments).
zip311a1 (the delegated receipt) and zip311g1 (the certificate). Code:
crates/zceipt-core/src/delegated.rs. Test:
roundtrip.rs::delegated_receipts_stay_within_their_policy. The decoders are fuzzed, and the
spec verifier checks conformance/delegated.json.