Skip to content

ZIP 2005: Drop leadByte and AssetBase from H^{rcm,Orchard}; commit to deployment option 1#1275

Open
daira wants to merge 16 commits into
zcash:mainfrom
daira:zip-2005-drop-leadByte-from-hrcm
Open

ZIP 2005: Drop leadByte and AssetBase from H^{rcm,Orchard}; commit to deployment option 1#1275
daira wants to merge 16 commits into
zcash:mainfrom
daira:zip-2005-drop-leadByte-from-hrcm

Conversation

@daira
Copy link
Copy Markdown
Collaborator

@daira daira commented May 16, 2026

Follow-up to merged PR #1264. This branch makes the following changes:

Security argument

  • Use note-tuple terminology consistently in the Spendability arguments, correcting pre-existing imprecisions in the $\mathsf{notetuple}$ framing.
  • Drop $\mathsf{leadByte}$ from the input to $\mathsf{H^{rcm,Orchard}}$. $\mathsf{leadByte}$ versions the note plaintext, not the note. The previous design created a layering violation between the handling of note plaintexts vs notes. The $\mathsf{leadByte} = \mathtt{0x02}$ case retains the existing protocol-spec derivation; the $\mathsf{leadByte} = \mathtt{0x03}$ case uses the new $\mathsf{H^{rcm,Orchard}}$ directly.
  • ZIP 2005 is now specified to activate without ZSAs, so drop $\mathsf{AssetBase}$ from the input to $\mathsf{H^{rcm,Orchard}}$.
  • Inline $\mathsf{H^{rcm,Sapling}}$ (it was a wrapper around $\mathsf{ToScalar^{Sapling}}(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x04}]))$ with unused args); reduce the signature of $\mathsf{H^{esk,Sapling}}$ from (_, _) to (_) matching its Canopy-onward call shape; replace if Sapling and leadByte = ... / if Orchard and leadByte = ... with the explicit if protocol = Sapling and ... / if protocol = Orchard and ... form in the prose dispatches.
  • Define Derive_rcm^{Sapling,Orchard} helpers that bundle the $\mathsf{leadByte}$ case-split for $\mathsf{rcm}$ derivation. Call sites in §4.7.2 / §4.7.3 / §4.8.2 / §4.8.3 / §4.20.2 / §4.20.3 invoke these helpers instead of dispatching inline. The §4.20.2 / §4.20.3 decryption $\mathsf{rcm}$ derivation collapses from a 4-case case-split to a 2-case protocol-conditional call.
  • Pin $\mathsf{ak}$ (up to $y$-sign of $\mathsf{ak}^{\mathbb{P}}$) for Spend Authorization key-binding, in addition to $\mathsf{qk}$. The spend-authorization verification key is randomized from $\mathsf{ak}^{\mathbb{P}}$; the previous motivation enumeration listed only $\mathsf{qk}$. The formal key-binding predicate already pinned $\mathsf{ak}$ via $\mathsf{ivk} = \mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk})$; the enumeration was incomplete.
  • Make the key-binding algebraic setup explicit per §5.4.1.10 'Sinsemilla commitments': exhibit $\mathcal{S}$ as the rivk-randomization base, $M'$ as $\mathsf{SinsemillaHashToPoint}$ over the encoded $(\mathsf{ak}, \mathsf{nk})$, and the WLOG scalar-lift $M' = [h(\mathsf{ak}, \mathsf{nk})], \mathcal{S}$ for a Pedersen-like deterministic $h$. Resolves two duplicate TODOs.

Deployment

  • Commit to deployment option 1 (deploy in v5 transactions before the next NU, with a $\mathsf{ZIP2005ActivationHeight}$); restructure $\mathsf{allowedLeadBytes}$ accordingly.
  • Add a "Proactive movement of funds to recoverable notes" section: wallets SHOULD sweep all non-recoverable funds they control into recoverable Orchard notes once this proposal is deployed. Wallet-internal sends use $\mathtt{0x03}$ immediately; external sends use $\mathtt{0x02}$ until there is wider support for receiving $\mathtt{0x03}$.
  • Decouple ZIP 2005 from OrchardZSA in framing prose.

Terminology

  • FROST multisignaturesFROST threshold multisignatures (a multisignature scheme is not necessarily a threshold scheme).

Cross-ZIP

  • ZIPs 226 / 230 / 231: replace explicit 0x03 references with placeholders ({{ZSALEADBYTE}} / {{LEADBYTE}} / {{MBLEADBYTE}}) since 0x03 is now reserved for ZIP 2005.
  • Withdraw ZIP 230 (obsoleted by ZIP 248).

Housekeeping

  • Move ZIP 2005 from Draft to Proposed; update Credits and Pull-Request fields.
  • Update the BLAKE3 reference to cite Zooko Wilcox's current name.

Suggested checks

  • Spot-check that Derive_rcm^{Sapling} and Derive_rcm^{Orchard} dispatch correctly and cover the relevant leadByte values.
  • The $\mathsf{allowedLeadBytes}$ matrix covers all valid (protocol, height, txVersion) combinations.
  • The key-binding algebraic-setup paragraph matches §5.4.1.10 'Sinsemilla commitments' (domain strings, encoding).

🤖 Filed with Claude Code

@daira daira requested review from a team and ValarDragon May 16, 2026 14:53
@daira daira force-pushed the zip-2005-drop-leadByte-from-hrcm branch 4 times, most recently from 818be5c to 9489d77 Compare May 16, 2026 15:55
daira and others added 13 commits May 16, 2026 17:22
…uments.

* Adopt notetuple, which is currently (rseed, leadByte, noterepr), as the
  named tuple feeding H^{rcm} and f, replacing "underlying note" or
  "note fields" framings in the binding and Spendability arguments.
* Rename the Spendability theorem and its "Distinct ..." condition to use
  "note tuple(s)" instead of "underlying notes".
* Fix an error where NoteCommit^rcm(noterepr) was defined in terms of
  leadByte, which it can't be because noterepr does not contain leadByte.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
leadByte versions the note plaintext, not the note. The previous design
took leadByte as a parameter of H^{rcm,Orchard} (with internal dispatch
on its value), which created a layering violation between the handling
of note plaintexts vs notes.

* Redefine H^{rcm,Orchard} to take only (rseed, noterepr) and define
  it only for the recoverable-note (leadByte = 0x03) case.
  The leadByte = 0x02 case uses the existing derivation
  rcm = ToScalar^{Orchard}(PRF^{expand}_{rseed}([0x05] || ρ)) unchanged.
* Drop the leadByte byte from the hashed prefix: pre_rcm = [0x0B] || ...
  instead of [0x0B, leadByte] || ....
* At each call site (§4.7.3 Sending Notes, §4.8.3 Dummy Notes,
  §4.20.2/§4.20.3 Decryption), dispatch on leadByte explicitly to choose
  between the legacy and recoverable derivations.
* Simplify the Spendability proof's notetuple to (rseed, noterepr); drop
  the leadByte_i index from notetuple_i in the theorem's "Distinct note
  tuples" condition.
* Add a sentence before the flow diagram noting that it shows the
  recoverable-note case (leadByte = 0x03) and that the legacy case uses
  the existing simpler derivation. Drop the leadByte → pre_rcm edge.
* Update the rationale and the specialised import in the Spendability
  setup to match the new signature.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A multisignature scheme is a signature scheme that supports signing by
multiple parties with public key aggregation, but does not necessarily
support signing by a threshold of parties.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
… 0x03.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
…ion.

Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
The 0x03 note plaintext format now does not include AssetBase. Drop
AssetBase from:

* the H^{rcm,Orchard} definition (signature and pre_rcm body) in §4.7.3
  and in the specialised import in the Spendability proof;
* the Sending Notes (Orchard) and Dummy Notes (Orchard) procedures: drop
  the "Let AssetBase = V^Orchard" preludes, the "AssetBase★ = ..."
  inline-let lines, and AssetBase★ from the H^{rcm,Orchard} call sites;
  also drop AssetBase★ from "use ... in the inputs to NoteCommit";
* the Decryption procedures (§4.20.2 and §4.20.3): drop the
  "Let AssetBase = V^Orchard" prelude, AssetBase★ from the inline let,
  and from the H^{rcm,Orchard} call sites;
* the Recovery Statement witness's noterepr;
* the rationale's "Repairing note commitments" noterepr;
* the flow diagram (drop AssetBase from the "v, AssetBase" pre_rcm input).

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per the deployment-option-1 decision (ZIP 2005 deploys Orchard-only,
without ZSAs), reframe places that implied ZIP 2005's scope included
OrchardZSA:

* "It can optionally be done at the same time as changes necessary to
  implement ... ZSAs" -> "It is compatible with ... ZSAs".
* Rename "Flow diagram for the Orchard and OrchardZSA protocols" to
  "Flow diagram for the Orchard protocol" (the diagram shows the 0x03
  recoverable-note case, which is Orchard-only). Update the cross-reference
  to match.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Daira-Emma Hopwood <daira@jacaranda.org>
…-conditionalise dispatch.

Three follow-ups to the leadByte case-split refactoring:

* Remove the named H^{rcm,Sapling} function (it was a wrapper with two
  unused args around ToScalar^Sapling(PRF^expand_rseed([0x04]))) and
  inline the right-hand side at the call sites in §4.7.2, §4.8.2, §4.20.2,
  and §4.20.3.
* Reduce H^{esk,Sapling}'s signature from (_, _) to (_), matching its
  Canopy-onward call shape H^{esk,protocol}_{rseed}(ρ) at §4.20.2's
  decryption step.
* Replace prose conditions "if Sapling and leadByte = ..." /
  "if Orchard and leadByte = ..." with
  "if protocol = Sapling and leadByte = ..." /
  "if protocol = Orchard and leadByte = ..." in the §4.20.2 and §4.20.3
  rcm dispatches.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-derivation sites.

Define protocol-specific helpers that bundle the leadByte case-split for
rcm derivation:

* Derive_rcm^{Sapling}_{rseed}(leadByte) dispatches between
  LEOS2IP_{256}(rseed) (leadByte=0x01) and
  ToScalar^Sapling(PRF^expand_rseed([0x04])) (leadByte=0x02).
* Derive_rcm^{Orchard}_{rseed}(leadByte, g★_d, pk★_d, v, ρ, ψ) dispatches
  between the existing legacy derivation
  ToScalar^Orchard(PRF^expand_rseed([0x05] || ρ)) (leadByte=0x02) and
  the new H^{rcm,Orchard}_{rseed}(g★_d, pk★_d, v, ρ, ψ) (leadByte=0x03).

Update the call sites in §4.7.2 / §4.7.3 / §4.8.2 / §4.8.3 / §4.20.2 /
§4.20.3 to invoke the helpers. The §4.20.2 / §4.20.3 decryption dispatch
collapses from a 4-case rcm case-split to a 2-case protocol-conditional
call.

Drop the now-redundant parenthetical noting that H^{rcm,Orchard} is
defined only for the leadByte=0x03 case (H^{rcm,Orchard} is now only
referenced inside Derive_rcm^{Orchard}'s definition).

Update the "which define ..." cross-reference at the order-of-operations
note to name Derive_rcm^{\{Sapling,Orchard\}} rather than H^{rcm,Orchard},
since Derive_rcm is now the primary export of the affected sections.

Harmonize the notation for H^ψ in the rationale: ψ = H^ψ(rseed, ρ) becomes
ψ = H^ψ_{rseed}(ρ). The two forms are equivalent under the protocol-spec
convention; the subscripted form is preferred for consistency.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@daira daira force-pushed the zip-2005-drop-leadByte-from-hrcm branch from c21c12d to d49b900 Compare May 16, 2026 16:23
daira and others added 3 commits May 16, 2026 17:47
…ing.

The Spend Authorization argument needs ak (up to y-sign of ak^P)
uniquely determined by ivk, because the verification key
rk = ak^P + [alpha] G depends on ak. The formal key-binding predicate
already pins ak via ivk = Commit^{ivk}_{rivk}(ak, nk); the motivation
enumeration in the key-binding section was incomplete.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the abstract ShortHash([h(ak,nk)+rivk] S) form with the
explicit Sinsemilla-commitment definition from § 5.4.1.10:
exhibit S as the rivk-randomization base via GroupHash^P, M' as
SinsemillaHashToPoint over LEBSP(ak) || LEBSP(nk), and the WLOG
scalar-lift M' = [h(ak,nk)] S using a Pedersen-like deterministic h.
Drops two duplicate "verify the exact form" TODOs.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lift.

Extract_P is a deterministic 2-to-1 map on non-identity Pallas points
and does not query any random oracle, so it composes the same way
classically and quantumly. The factor of 2 from the 2-to-1 reduction
is already absorbed into the break-probability bound.

Co-authored-by: Claude Opus 4.7 (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

None yet

Development

Successfully merging this pull request may close these issues.

1 participant