design: Shielded outputs#104
Conversation
| scan_pubkey(33) || hash(spend_pubkey)(20) | ||
| ``` | ||
|
|
||
| The spend pubkey is represented as a 20-byte hash (like a standard P2PKH address). Shorter addresses, but the full spend pubkey is not recoverable from the address alone — it must be obtained from the blockchain (from a prior spend) or out-of-band. |
There was a problem hiding this comment.
but the full spend pubkey is not recoverable from the address alone — it must be obtained from the blockchain (from a prior spend) or out-of-band.
Who must obtain it? The receiver already has it and the sender does not need it, correct?
There was a problem hiding this comment.
The sender. But the previous text was misleading and was updated. Let me explain here: For shielded outputs, the compact address is enough and nothing has to be recovered by the sender. But it imposes a limitation for silent payments.
|
|
||
| ### Rule 4 Compliance | ||
|
|
||
| When all inputs are transparent, the wallet must automatically ensure at least 2 shielded outputs (or include a transparent output). This is typically satisfied naturally (payment + change), but the wallet may need to create a zero-value absorber output in edge cases. |
There was a problem hiding this comment.
or include a transparent output
In this case, won't we still know the amount in the shielded output? In other words, won't we require still 2 shielded outputs?
There was a problem hiding this comment.
Also, this rule will be enforced on the wallet, correct? From the protocol side, should be possible to do it even if it "leaks" information.
There was a problem hiding this comment.
Indeed. I added this rule to open the discussion whether the protocol should require at least two shielded outputs or not.
When there are two or more shielded outputs and all inputs are transparent, observers can determine the total value of the outputs, but not how that value is distributed among them.
If there's at least one shielded input, observers can only infer that sum(outputs) > sum(transparent_inputs).
There was a problem hiding this comment.
Got it. I believe we should not enforce it at the protocol level. We should probably make it standard in the wallet library, though.
f033ceb to
4bb0b7e
Compare
4bb0b7e to
57c7958
Compare
| ### Sending Shielded Payments | ||
|
|
||
| 1. **Choose privacy tier** per output (`AmountShieldedOutput` or `FullShieldedOutput`). | ||
| 2. **Generate ephemeral keypair** `(e, E = e*G)` for each output. |
There was a problem hiding this comment.
How do you generate it? Do you take some info from the output to make it unique?
There was a problem hiding this comment.
No, you generate a random number e and multiply by G.
Extends the shielded outputs RFC with token creation, mint, and melt support via two new headers (MintHeader, MeltHeader) carrying public (token_index, amount) entries that bind into the homomorphic balance equation. Replaces parent Rule 8 and lifts the prohibition on shielded outputs in TokenCreationTransaction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a Disclosure model subsection clarifying that the token reference is always transparent (authority outputs already leak it; the verifier needs the version for deposit/fee logic) while amount visibility is a pending business decision. Adds worked examples for DEPOSIT-version mint, melt and FEE-version mint with concrete deposit/fee math. Reframes Rule M3 as "one direction per token" and elevates the transparent-vs-shielded amount trade-off into Unresolved Questions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Charge one FEE_PER_OUTPUT per MintHeader/MeltHeader entry on a FEE-version token, folded into the augmented homomorphic balance equation directly (mirroring the DEPOSIT 1% mechanism). The charge is per header entry, not per shielded recipient, so it preserves the FEE-token-specific knob without leaking the recipient count. Update Rule M4 to add the fee_token_charge term and Rule M6 to clarify that per-entry FEE-token charges go through the balance equation, not FeeHeader. Adjust §3.5 to reflect the split between FeeHeader (transparent + shielded outputs) and the augmented balance equation (per-entry FEE-token charge). Refine the disclosure-model drawback note to describe the chosen policy.
| ``` | ||
| scan_pubkey(33) || hash(spend_pubkey)(20) | ||
| ``` |
Extends ShieldedOutputsHeader with a per-tx kernel-excess point and Schnorr binding signature, enabling network-wide supply auditability across the shielded pool. Removes the wallet-side "force e_tx = 0" construction in favor of independently random output blindings, unlocking receiver-chosen blindings and multi-party tx construction. Folds the role of UnshieldBalanceHeader into ShieldedOutputsHeader and retires the standalone header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rewrite 0000-shielded-outputs.md as a single self-contained spec matching the feat/shielded-outputs-rebased implementation, and remove the satellite mint/melt and audit RFCs (folded in). Key corrections to match the code: - Range proofs are secp256k1-zkp Borromean at fixed 40 bits ([1, 2^40), ~3213 B), not Bulletproofs; output sizes and fees updated accordingly. - Fold in MintHeader (0x14) / MeltHeader (0x15): entry format, Rule M4 augmented balance, DEPOSIT 1% deposit/withdraw, FEE-token per-entry charge, surjection-domain extension, and TCT rules. - No binding signatures: full-unshield uses UnshieldBalanceHeader carrying a 32-byte scalar excess. Binding-signature proposals moved to Future possibilities; document the scalar-based network-wide supply audit that works today. - Single SHIELDED_TRANSACTIONS feature flag (no SHIELDED_MINT_MELT); max headers 5 when enabled. - Crypto layout htr-ct-crypto -> htr-lib -> hathorlib/crypto/shielded with real domain separators; exact data model, header IDs, constants, sighash coverage, and exception names. - Rule 4 enforced unconditionally (>=2 shielded outputs); add Rules M5/M6. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rendered