Skip to content

design: Shielded outputs#104

Open
msbrogli wants to merge 6 commits into
masterfrom
feat/shielded-outputs
Open

design: Shielded outputs#104
msbrogli wants to merge 6 commits into
masterfrom
feat/shielded-outputs

Conversation

@msbrogli

@msbrogli msbrogli commented Mar 3, 2026

Copy link
Copy Markdown
Member

@msbrogli msbrogli self-assigned this Mar 3, 2026
@msbrogli msbrogli moved this from Todo to In Progress (Done) in Hathor Network Mar 3, 2026
Comment thread text/0000-shielded-outputs.md Outdated
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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread text/0000-shielded-outputs.md Outdated

### 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. I believe we should not enforce it at the protocol level. We should probably make it standard in the wallet library, though.

@msbrogli msbrogli force-pushed the feat/shielded-outputs branch from f033ceb to 4bb0b7e Compare March 4, 2026 18:58
@msbrogli msbrogli moved this from In Progress (Done) to In Review (Done) in Hathor Network Mar 5, 2026
@msbrogli msbrogli force-pushed the feat/shielded-outputs branch from 4bb0b7e to 57c7958 Compare March 13, 2026 15:56
@msbrogli msbrogli moved this from In Review (Done) to In Progress (Done) in Hathor Network Mar 13, 2026
### Sending Shielded Payments

1. **Choose privacy tier** per output (`AmountShieldedOutput` or `FullShieldedOutput`).
2. **Generate ephemeral keypair** `(e, E = e*G)` for each output.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you generate it? Do you take some info from the output to make it unique?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you generate a random number e and multiply by G.

@msbrogli msbrogli moved this from In Progress (Done) to In Review (Done) in Hathor Network Mar 18, 2026
msbrogli and others added 3 commits April 27, 2026 00:38
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.
Comment on lines +173 to +175
```
scan_pubkey(33) || hash(spend_pubkey)(20)
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comeback later.

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>
@msbrogli msbrogli moved this from In Review (Done) to In Progress (WIP) in Hathor Network Jun 24, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress (WIP)

Development

Successfully merging this pull request may close these issues.

3 participants