Skip to content
ZIP.tools

ZIP 2005

Ironwood Quantum Recoverability

  • Proposed
Proposal metadata
ID
2005
Status
Proposed
Category
Consensus
Owners
  • Daira-Emma Hopwood
  • Jack Grigg
Created
2025-03-31
License
MIT
Contents
  1. Rationale
  2. Cryptographic background
  3. Proposed Recovery Protocol
  4. Security analysis

Define Derive_rcmrseedSapling(leadByte)={LEOS2IP256(rseed), ⁣ ⁣ ⁣if leadByte=0x01ToScalarSapling(PRFrseedexpand([0x04])), ⁣ ⁣ ⁣if leadByte=0x02\mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}) = \begin{cases} \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\textsf{if } \mathsf{leadByte} = \mathtt{0x01} \\ \mathsf{ToScalar^{Sapling}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x04}])\kern-0.1em\big),&\!\!\!\textsf{if } \mathsf{leadByte} = \mathtt{0x02} \end{cases}

Define Hrseedesk,Sapling(_)=ToScalarSapling(PRFrseedexpand([0x05]))\mathsf{H^{esk,Sapling}_{rseed}}(\_) = \mathsf{ToScalar^{Sapling}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}])\kern-0.1em\big).

(Hesk,Sapling\mathsf{H^{esk,Sapling}} intentionally takes an argument that is unused.)

Replace the lines deriving rcm\mathsf{rcm} and esk\mathsf{esk} with

Derive rcm=Derive_rcmrseedSapling(leadByte)\mathsf{rcm} = \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte})

Derive esk=Hrseedesk,Sapling(⊥)\mathsf{esk} = \mathsf{H^{esk,Sapling}_{rseed}}(\bot)

§ 4.7.3 ‘Sending Notes (Orchard)’

Add before "For each Action description":

Define Hrseedrcm,Orchard(g⋆d,pk⋆d,v,ρ‾,ψ)=\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) = ToScalarOrchard(PRFrseedexpand(pre_rcm))\mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big)

where pre_rcm=[0x0B] ∣∣ LEBS2OSP256(g⋆d) ∣∣ LEBS2OSP256(pk⋆d) ∣∣ I2LEOSP64(v) ∣∣ ρ‾ ∣∣ I2LEOSP256(ψ)\mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{g}\star_{\mathsf{d}}) \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{pk}\star_{\mathsf{d}}) \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \underline{\text{ρ}} \,||\, \mathsf{I2LEOSP}_{256}(\text{ψ}).

Define Derive_rcmrseedOrchard(leadByte,g⋆d,pk⋆d,v,ρ‾,ψ)={ToScalarOrchard(PRFrseedexpand([0x05] ∣∣ ρ‾)), ⁣ ⁣ ⁣if leadByte=0x02Hrseedrcm,Orchard(g⋆d,pk⋆d,v,ρ‾,ψ), ⁣ ⁣ ⁣if leadByte=0x03\mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) = \begin{cases} \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x05}] \,||\, \underline{\text{ρ}})\kern-0.1em\big),&\!\!\!\textsf{if } \mathsf{leadByte} = \mathtt{0x02} \\ \mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\textsf{if } \mathsf{leadByte} = \mathtt{0x03} \end{cases}

Define Hrseedesk,Orchard(ρ‾)=ToScalarOrchard(PRFrseedexpand([0x04] ∣∣ ρ‾))\mathsf{H^{esk,Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x04}] \,||\, \underline{\text{ρ}})\kern-0.1em\big).

Define Hrseedψ,Orchard(ρ‾)=ToBaseOrchard(PRFrseedexpand([0x09] ∣∣ ρ‾))\mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x09}] \,||\, \underline{\text{ρ}})\kern-0.1em\big).

The first-byte domain separator 0x0A\mathtt{0x0A} for PRFexpand\mathsf{PRF^{expand}} is reserved by this ZIP for use by split notes in ZIP 226 26.

Insert before the derivation of esk\mathsf{esk}:

Let g⋆d=reprP(gd)\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), and pk⋆d=reprP(pkd)\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}).

and use these in the inputs to NoteCommitOrchard\mathsf{NoteCommit^{Orchard}}.

Replace the lines deriving esk\mathsf{esk}, rcm\mathsf{rcm}, and ψ\text{ψ} with

Derive esk=Hrseedesk,Orchard(ρ‾)\mathsf{esk} = \mathsf{H^{esk,Orchard}_{rseed}}(\underline{\text{ρ}})

Derive ψ=Hrseedψ,Orchard(ρ‾)\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})

Derive rcm=Derive_rcmrseedOrchard(leadByte,g⋆d,pk⋆d,v,ρ‾,ψ)\mathsf{rcm} = \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ})

(The order of derivation has to be changed because the inputs to Derive_rcm\mathsf{Derive\_rcm} include ψ\text{ψ}.)

§ 4.8.2 ‘Dummy Notes (Sapling)’

Add

Let Derive_rcmSapling\mathsf{Derive\_rcm^{Sapling}} be as defined in § 4.7.2 ‘Sending Notes (Sapling)’.

Replace the line deriving rcm\mathsf{rcm} with

Derive rcm=Derive_rcmrseedSapling(leadByte)\mathsf{rcm} = \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte})

§ 4.8.3 ‘Dummy Notes (Orchard)’

Insert before "The spend-related fields ...":

Let Derive_rcmOrchard\mathsf{Derive\_rcm^{Orchard}} and Hψ,Orchard\mathsf{H^{\text{ψ},Orchard}} be as defined in § 4.7.3 ‘Sending Notes (Orchard)’.

Replace the lines deriving rcm\mathsf{rcm} and ψ\text{ψ} with

Let g⋆d=reprP(gd)\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), and pk⋆d=reprP(pkd)\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}).

Derive ψ=Hrseedψ,Orchard(ρ‾)\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}})

Derive rcm=Derive_rcmrseedOrchard(leadByte,g⋆d,pk⋆d,v,ρ‾,ψ)\mathsf{rcm} = \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ})

and use g⋆d\mathsf{g}\star_{\mathsf{d}}, pk⋆d\mathsf{pk}\star_{\mathsf{d}}, in the inputs to NoteCommitOrchard\mathsf{NoteCommit^{Orchard}}.

(The order of derivation has to be changed because the inputs to Derive_rcm\mathsf{Derive\_rcm} include ψ\text{ψ}.)

The choice of leadByte\mathsf{leadByte}, as specified in § 3.2.1, is identical between dummy and non-dummy notes.

§ 4.20.2 and § 4.20.3 ‘Decryption using an Incoming/Full Viewing Key (Sapling and Orchard)’

For both § 4.20.2 and § 4.20.3, add before the decryption procedure:

Let Derive_rcmSapling\mathsf{Derive\_rcm^{Sapling}} and Hesk,Sapling\mathsf{H^{esk,Sapling}} be as defined in § 4.7.2 ‘Sending Notes (Sapling)’.

Let Derive_rcmOrchard\mathsf{Derive\_rcm^{Orchard}}, Hesk,Orchard\mathsf{H^{esk,Orchard}}, and Hψ,Orchard\mathsf{H^{\text{ψ},Orchard}} be as defined in § 4.7.3 ‘Sending Notes (Orchard)’.

For § 4.20.3, replace

\hspace{1.0em} if esk≥rG\mathsf{esk} \geq r_{\mathbb{G}} or pkd=⊥\mathsf{pk_d} = \bot, return ⊥\bot

with

\hspace{1.0em} if esk≥rG\mathsf{esk} \geq r_{\mathbb{G}} or pkd=⊥\mathsf{pk_d} = \bot or (for Sapling) pkd∉J(r)∗\mathsf{pk_d} \not\in \mathbb{J}^{(r)*} (see note below), return ⊥\bot

and in the note containing "However, this is technically redundant with the later check that returns ⊥\bot if pkd∉J(r)∗\mathsf{pk_d} \not\in \mathbb{J}^{(r)*}", delete the word "later".

For both § 4.20.2 and § 4.20.3, replace

\hspace{1.0em} for Sapling, let pre_rcm=[4]\mathsf{pre\_rcm} = [4] and pre_esk=[5]\mathsf{pre\_esk} = [5]
\hspace{1.0em} for Orchard, let ρ‾=I2LEOSP256(nfold\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}} from the same Action description  ⁣)\!), pre_rcm=[5] ∣∣ ρ‾\mathsf{pre\_rcm} = [5] \,||\, \underline{\text{ρ}}, and pre_esk=[4] ∣∣ ρ‾\mathsf{pre\_esk} = [4] \,||\, \underline{\text{ρ}}

with

\hspace{1.0em} let ρ‾=I2LEOSP256(nfold\underline{\text{ρ}} = \mathsf{I2LEOSP}_{256}(\mathsf{nf^{old}} from the same Action description  ⁣)\!)

For § 4.20.2, replace

\hspace{1.0em} let rcm={LEOS2IP256(rseed), ⁣ ⁣ ⁣if leadByte=0x01ToScalar(PRFrseedexpand(pre_rcm)), ⁣ ⁣ ⁣otherwise\mathsf{rcm} = \begin{cases} \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\textsf{if } \mathsf{leadByte} = \mathtt{0x01} \\ \mathsf{ToScalar}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big),&\!\!\!\textsf{otherwise} \end{cases}
\hspace{1.0em} if rcm≥rG\mathsf{rcm} \geq r_{\mathbb{G}}, return ⊥\bot
\hspace{1.0em} let gd=DiversifyHash(d)\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d}). if (for Sapling) gd=⊥\mathsf{g_d} = \bot, return ⊥\bot
\hspace{1.0em} [Canopy onward] if leadByte≠0x01\mathsf{leadByte} \neq \mathtt{0x01}:
\hspace{2.5em} esk=ToScalarprotocol(PRFrseedexpand(pre_esk))\mathsf{esk} = \mathsf{ToScalar^{protocol}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_esk})\kern-0.1em\big)
\hspace{2.5em} if reprG(KA.DerivePublic(esk,gd))≠ephemeralKey\mathsf{repr}_{\mathbb{G}}\big(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})\kern-0.1em\big) \neq \mathtt{ephemeralKey}, return ⊥\bot

\hspace{1.0em} let pkd=KA.DerivePublic(ivk,gd)\mathsf{pk_d} = \mathsf{KA.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})

with

\hspace{1.0em} let gd=DiversifyHash(d)\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d}). if (for Sapling) gd=⊥\mathsf{g_d} = \bot, return ⊥\bot
\hspace{1.0em} [Canopy onward] if leadByte≠0x01\mathsf{leadByte} \neq \mathtt{0x01}:
\hspace{2.5em} let esk=Hrseedesk,protocol(ρ‾)\mathsf{esk} = \mathsf{H^{esk,protocol}_{rseed}}(\underline{\text{ρ}})
\hspace{2.5em} if reprG(KA.DerivePublic(esk,gd))≠ephemeralKey\mathsf{repr}_{\mathbb{G}}\big(\mathsf{KA.DerivePublic}(\mathsf{esk}, \mathsf{g_d})\kern-0.1em\big) \neq \mathtt{ephemeralKey}, return ⊥\bot

\hspace{1.0em} let pkd=KA.DerivePublic(ivk,gd)\mathsf{pk_d} = \mathsf{KA.DerivePublic}(\mathsf{ivk}, \mathsf{g_d})
\hspace{1.0em} let g⋆d=reprP(gd)\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), pk⋆d=reprP(pkd)\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})
\hspace{1.0em} let ψ=Hrseedψ,Orchard(ρ‾)\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) for Orchard or ⊥\bot for Sapling
\hspace{1.0em} let rcm={Derive_rcmrseedSapling(leadByte), ⁣ ⁣ ⁣if protocol=SaplingDerive_rcmrseedOrchard(leadByte,g⋆d,pk⋆d,v,ρ‾,ψ), ⁣ ⁣ ⁣if protocol=Orchard\mathsf{rcm} = \begin{cases} \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}),&\!\!\!\textsf{if } \mathsf{protocol} = \mathsf{Sapling} \\ \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\textsf{if } \mathsf{protocol} = \mathsf{Orchard} \end{cases}
\hspace{1.0em} if rcm≥rG\mathsf{rcm} \geq r_{\mathbb{G}}, return ⊥\bot

The order of operations has to be altered because the derivation of rcm\mathsf{rcm} can depend on gd\mathsf{g_d} and pkd\mathsf{pk_d}. The definitions of pre_rcm\mathsf{pre\_rcm} and pre_esk\mathsf{pre\_esk} are moved or inlined into § 4.7.2 ‘Sending Notes (Sapling)’ and § 4.7.3 ‘Sending Notes (Orchard)’ which define Derive_rcm{Sapling,Orchard}\mathsf{Derive\_rcm^{\{Sapling,Orchard\}}} and Hesk,{Sapling,Orchard}\mathsf{H^{esk,\{Sapling,Orchard\}}}.

For § 4.20.3, replace

\hspace{1.0em} let rcm={LEOS2IP256(rseed), ⁣ ⁣ ⁣if leadByte=0x01ToScalar(PRFrseedexpand(pre_rcm)), ⁣ ⁣ ⁣otherwise\mathsf{rcm} = \begin{cases} \mathsf{LEOS2IP}_{256}(\mathsf{rseed}),&\!\!\!\textsf{if } \mathsf{leadByte} = \mathtt{0x01} \\ \mathsf{ToScalar}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big),&\!\!\!\textsf{otherwise} \end{cases}
\hspace{1.0em} if rcm≥rG\mathsf{rcm} \geq r_{\mathbb{G}}, return ⊥\bot
\hspace{1.0em} let gd=DiversifyHash(d)\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d}). if (for Sapling) gd=⊥\mathsf{g_d} = \bot or pkd∉J(r)∗\mathsf{pk_d} \not\in \mathbb{J}^{(r)*} (see note below), return ⊥\bot

with

\hspace{1.0em} let gd=DiversifyHash(d)\mathsf{g_d} = \mathsf{DiversifyHash}(\mathsf{d}). if (for Sapling) gd=⊥\mathsf{g_d} = \bot, return ⊥\bot
\hspace{1.0em} let g⋆d=reprP(gd)\mathsf{g}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), pk⋆d=reprP(pkd)\mathsf{pk}\star_{\mathsf{d}} = \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d})
\hspace{1.0em} let ψ=Hrseedψ,Orchard(ρ‾)\text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) for Orchard or ⊥\bot for Sapling
\hspace{1.0em} let rcm={Derive_rcmrseedSapling(leadByte), ⁣ ⁣ ⁣if protocol=SaplingDerive_rcmrseedOrchard(leadByte,g⋆d,pk⋆d,v,ρ‾,ψ), ⁣ ⁣ ⁣if protocol=Orchard\mathsf{rcm} = \begin{cases} \mathsf{Derive\_rcm^{Sapling}_{rseed}}(\mathsf{leadByte}),&\!\!\!\textsf{if } \mathsf{protocol} = \mathsf{Sapling} \\ \mathsf{Derive\_rcm^{Orchard}_{rseed}}(\mathsf{leadByte}, \mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}),&\!\!\!\textsf{if } \mathsf{protocol} = \mathsf{Orchard} \end{cases}
\hspace{1.0em} if rcm≥rG\mathsf{rcm} \geq r_{\mathbb{G}}, return ⊥\bot

and delete "where ψ=ToBaseOrchard(PRFrseedexpand([9] ∣∣ ρ‾))\text{ψ} = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([9] \,||\, \underline{\text{ρ}})\kern-0.1em\big)".

§ 5.3 ‘Constants’

Add the definitions

ℓqsk  ⦂  N:=256\ell_{\mathsf{qsk}} \;{\small ⦂}\; \mathbb{N} := 256
ℓqk  ⦂  N:=256\ell_{\mathsf{qk}} \;{\small ⦂}\; \mathbb{N} := 256

Changes to ZIPs

ZIP 32

Add a ∗\ast to the arrows leading to ask\mathsf{ask} and rivk\mathsf{rivk} in the diagram in section ‘Orchard internal key derivation’ 12, with the following note:

∗\ast The derivations of ask\mathsf{ask} and rivk\mathsf{rivk} shown in the diagram are not the only possibility. For further detail see § 4.2.3 ‘Orchard Key Components’ in the protocol specification. However, if ask\mathsf{ask}, ak\mathsf{ak}, nk\mathsf{nk}, rivk\mathsf{rivk}, and rivk_internal\mathsf{rivk\_internal} are not generated as in the diagram, then it may not be possible to recover the resulting notes as specified in [ZIP 2005] in the event that attacks using quantum computers become practical.

ZIP 212

Add a note before the Abstract:

This ZIP reflects the changes made to note encryption for the Canopy upgrade. It does not include subsequent changes in [ZIP 2005].

Rationale

Cryptographic background

This rationale is written primarily for cryptologists and protocol designers familiar with the Zcash shielded protocols. It is recommended to first read the slides of, and/or watch the following presentations:

  • Understanding Zcash Security at Zcon3 27
  • Post-Quantum Zcash at ZconVI 8

To understand the modelling of hash function and commitment security against a quantum adversary we also recommend 28 and 29.

Proposed Recovery Protocol

The details of the protocol in this section are subject to change. This description is meant to facilitate analysis of whether the specification changes to be adopted now are likely to be sufficient to securely support a Recovery Protocol.

The proposed Recovery Protocol works, roughly speaking, by enforcing the derivations given in the [Flow diagram for the Orchard protocol], and we suggest having that diagram open in another window to refer to it.

Proposed Recovery Statement

Import this definition from § 4.2.3 ‘Orchard Key Components’ 15:

Define Hqkrivk_ext(ak,nk)=ToScalarOrchard(PRFqkexpand([0x0D] ∣∣ I2LEOSP256(ak) ∣∣ I2LEOSP256(nk)))\mathsf{H}^{\mathsf{rivk\_ext}}_{\mathsf{qk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{qk}}\big([\mathtt{0x0D}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big).

Import this definition from ZIP 32 12:

Hrivk_extrivk_int(ak,nk)=ToScalarOrchard(PRFrivk_extexpand([0x83] ∣∣ I2LEOSP256(ak) ∣∣ I2LEOSP256(nk)))\mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rivk\_ext}}\big([\mathtt{0x83}] \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{ak}) \,||\, \mathsf{I2LEOSP}_{256}(\mathsf{nk})\kern-0.1em\big)\kern-0.15em\big)

Import these definitions from § 4.7.3 ‘Sending Notes (Orchard)’ 30:

Define Hrseedrcm,Orchard(g⋆d,pk⋆d,v,ρ‾,ψ)=\mathsf{H^{rcm,Orchard}_{rseed}}(\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}) = ToScalarOrchard(PRFrseedexpand(pre_rcm))\mathsf{ToScalar^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm})\kern-0.1em\big)

where pre_rcm=[0x0B] ∣∣ LEBS2OSP256(g⋆d) ∣∣ LEBS2OSP256(pk⋆d) ∣∣ I2LEOSP64(v) ∣∣ ρ‾ ∣∣ I2LEOSP256(ψ)\mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{g}\star_{\mathsf{d}}) \,||\, \mathsf{LEBS2OSP}_{256}(\mathsf{pk}\star_{\mathsf{d}}) \,||\, \mathsf{I2LEOSP}_{64}(\mathsf{v}) \,||\, \underline{\text{ρ}} \,||\, \mathsf{I2LEOSP}_{256}(\text{ψ}).

Define Hrseedψ,Orchard(ρ‾)=ToBaseOrchard(PRFrseedexpand([0x09] ∣∣ ρ‾))\mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) = \mathsf{ToBase^{Orchard}}\big(\mathsf{PRF^{expand}_{rseed}}([\mathtt{0x09}] \,||\, \underline{\text{ρ}})\kern-0.1em\big).

Import this definition from § 5.4.7.1 ‘Spend Authorization Signature (Sapling and Orchard)’ 31:

Define GOrchard=GroupHashP(“z.cash:Orchard”,“G”)\mathcal{G}^{\mathsf{Orchard}} = \mathsf{GroupHash}^{\mathbb{P}}(\texttt{“z.cash:Orchard”}, \texttt{“G”}).

A valid instance of a Recovery Statement assures that given a primary input:

(rtOrchard ⁣ ⁣ ⁣ ⁣⦂  {0 .. qP−1},rk ⁣ ⁣ ⁣ ⁣⦂  SpendAuthSigOrchard.Public),nf ⁣ ⁣ ⁣ ⁣⦂  FqP,SigHash ⁣ ⁣ ⁣ ⁣⦂  MessageHash)\begin{array}{rl} \hspace{4.1em} ( \mathsf{rt^{Orchard}} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,q_{\mathbb{P}}-1 \}, \\ \mathsf{rk} \!\!\!\!&{\small ⦂}\; \mathsf{SpendAuthSig^{Orchard}.Public} ), \\ \mathsf{nf} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{q_{\mathbb{P}}}, \\ \mathsf{SigHash} \!\!\!\!&{\small ⦂}\; \mathsf{MessageHash} ) \end{array}

the prover knows an auxiliary input:

(path ⁣ ⁣ ⁣ ⁣⦂  {0 .. qP−1}[MerkleDepthOrchard],pos ⁣ ⁣ ⁣ ⁣⦂  {0 .. 2MerkleDepthOrchard−1},α ⁣ ⁣ ⁣ ⁣⦂  FrP,akP ⁣ ⁣ ⁣ ⁣⦂  P∗,nk ⁣ ⁣ ⁣ ⁣⦂  FqP,rivk_ext ⁣ ⁣ ⁣ ⁣⦂  FrP,rivk ⁣ ⁣ ⁣ ⁣⦂  FrP,(qk,σqsk) ⁣ ⁣ ⁣ ⁣⦂  (BY[ℓqk/8]×SoKqsk((qk),SigHash))∪{(⊥,⊥)},σsk ⁣ ⁣ ⁣ ⁣⦂  SoKsk((akP,nk,rivk_ext),SigHash)∪{⊥},rseed ⁣ ⁣ ⁣ ⁣⦂  BY[32],gd ⁣ ⁣ ⁣ ⁣⦂  P∗,v ⁣ ⁣ ⁣ ⁣⦂  {0 .. 2ℓvalue−1},ρ ⁣ ⁣ ⁣ ⁣⦂  FqP)\begin{array}{rl} \hspace{4em} ( \mathsf{path} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,q_{\mathbb{P}}-1 \}^{[\mathsf{MerkleDepth^{Orchard}}]}, \\ \mathsf{pos} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,2^{\mathsf{MerkleDepth^{Orchard}}}-1 \}, \\ \mathsf{\alpha} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ \mathsf{ak}^{\mathbb{P}} \!\!\!\!&{\small ⦂}\; \mathbb{P}^*, \\ \mathsf{nk} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{q_{\mathbb{P}}}, \\ \mathsf{rivk\_ext} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ \mathsf{rivk} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{r_{\mathbb{P}}}, \\ (\mathsf{qk}, \sigma_{\mathsf{qsk}}) \!\!\!\!&{\small ⦂}\; \big(\mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qk}}/8]} \times \mathsf{SoK^{qsk}}\big((\mathsf{qk}), \mathsf{SigHash}\big)\big) \cup \{(\bot, \bot)\}, \\ \sigma_{\mathsf{sk}} \!\!\!\!&{\small ⦂}\; \mathsf{SoK^{sk}}\big((\mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}), \mathsf{SigHash}\big) \cup \{\bot\}, \\ \mathsf{rseed} \!\!\!\!&{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[32]}, \\ \mathsf{g_d} \!\!\!\!&{\small ⦂}\; \mathbb{P}^*, \\ \mathsf{v} \!\!\!\!&{\small ⦂}\; \{ 0\,..\,2^{\ell_{\mathsf{value}}}-1 \}, \\ \text{ρ} \!\!\!\!&{\small ⦂}\; \mathbb{F}_{q_{\mathbb{P}}} ) \end{array}

where

BindKeyssk(sk,akP,nk,rivk_ext)=( ⁣ ⁣ ⁣ ⁣akP=[Hask(sk)] GOrchard ⁣ ⁣ ⁣ ⁣∧  nk=Hnk(sk) ⁣ ⁣ ⁣ ⁣∧  rivk_ext=Hrivk_legacy(sk) )\begin{array}{rll} \hspace{1em}\mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) = \big(&\!\!\!\! \mathsf{ak}^{\mathbb{P}} = [\mathsf{H^{ask}}(\mathsf{sk})]\, \mathcal{G}^{\mathsf{Orchard}} \\ &\!\!\!\! \wedge\; \mathsf{nk} = \mathsf{H^{nk}}(\mathsf{sk}) \\ &\!\!\!\! \wedge\; \mathsf{rivk\_ext} = \mathsf{H^{rivk\_legacy}}(\mathsf{sk}) \,\big) \end{array}

and

SoKqsk.Statement ⁣ ⁣ ⁣= { qsk  ⦂  BY[ℓqsk/8] ⁣ ⁣ ⁣ ⁣∣   qk=Hqk(qsk) }SoKsk.Statement ⁣ ⁣ ⁣= { sk  ⦂  B[ℓsk] ⁣ ⁣ ⁣ ⁣∣   BindKeyssk(sk,akP,nk,rivk_ext) }\begin{array}{rll} \hspace{1em}\mathsf{SoK^{qsk}.Statement} \!\!\!&=\, \big\{\,\mathsf{qsk} \;{\small ⦂}\; \mathbb{B}^{{\kern-0.1em\tiny\mathbb{Y}}[\ell_{\mathsf{qsk}}/8]} &\!\!\!\!|\;\, \mathsf{qk} = \mathsf{H^{qk}}(\mathsf{qsk}) \,\big\} \\ \hspace{1em}\mathsf{SoK^{sk}.Statement} \!\!\!&=\, \big\{\,\mathsf{sk} \;{\small ⦂}\; \mathbb{B}^{[\ell_{\mathsf{sk}}]} &\!\!\!\!|\;\, \mathsf{BindKeys^{sk}}(\mathsf{sk}, \mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}) \,\big\} \end{array}

such that the following conditions hold:

{   rk=SpendAuthSigOrchard.RandomizePublic(α,akP)(∧  ak=ExtractP(akP)(∧  ((qk,σqsk)=(⊥,⊥))≠(σsk=⊥)(∧  (qk,σqsk)≠(⊥,⊥)⇒( SoKqsk.Validate((qk),SigHash,σqsk)∧ rivk_ext=Hqkrivk_ext(ak,nk))(∧  σsk≠⊥⇒SoKsk.Validate((akP,nk,rivk_ext),SigHash,σsk)(∧  rivk∈{ rivk_ext, Hrivk_extrivk_int(ak,nk) }(∧  let ivk=Commitrivkivk(ak,nk)(∧  ivk∉{0,⊥}(∧  let pkd=[ivk] gd(∧  let ψ=Hrseedψ,Orchard(ρ‾)(∧  let noterepr=(reprP(gd),reprP(pkd),v,ρ‾,ψ)(∧  let rcm=Hrseedrcm,Orchard(0x03,noterepr)(∧  let cm=NoteCommitrcmOrchard(noterepr)(∧  cm≠⊥(∧  let cmx=ExtractP(cm)(∧  let leaf=MerkleCRH(cmx,ρ)(∧  path is a path to leaf in the rehashed commitment tree(∧  nf=DeriveNullifiernk(ρ,ψ,cm)(}\begin{array}{l} \{\;\, \mathsf{rk} = \mathsf{SpendAuthSig^{Orchard}.RandomizePublic}(\alpha, \mathsf{ak}^{\mathbb{P}}) \vphantom{\big(}\\ \wedge\; \mathsf{ak} = \mathsf{Extract}_{\mathbb{P}}(\mathsf{ak}^{\mathbb{P}}) \vphantom{\Big(}\\ \wedge\; \big((\mathsf{qk}, \sigma_{\mathsf{qsk}}) = (\bot, \bot)\big) \neq \big(\sigma_{\mathsf{sk}} = \bot\big) \vphantom{\big(}\\ \wedge\; (\mathsf{qk}, \sigma_{\mathsf{qsk}}) \neq (\bot, \bot) \Rightarrow \big(\, \mathsf{SoK^{qsk}.Validate}\big((\mathsf{qk}), \mathsf{SigHash}, \sigma_{\mathsf{qsk}}\big) \kern0.05em\wedge\, \mathsf{rivk\_ext} = \mathsf{H^{rivk\_ext}_{qk}}(\mathsf{ak}, \mathsf{nk})\kern0.05em\big) \vphantom{\Big(}\\ \wedge\; \sigma_{\mathsf{sk}} \neq \bot \Rightarrow \mathsf{SoK^{sk}.Validate}\big((\mathsf{ak}^{\mathbb{P}}, \mathsf{nk}, \mathsf{rivk\_ext}), \mathsf{SigHash}, \sigma_{\mathsf{sk}}\big) \vphantom{\big(}\\ \wedge\; \mathsf{rivk} \in \big\{\, \mathsf{rivk\_ext},\, \mathsf{H^{rivk\_int}_{rivk\_ext}}(\mathsf{ak}, \mathsf{nk}) \,\big\} \vphantom{\Big(}\\ \wedge\; \text{let } \mathsf{ivk} = \mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) \vphantom{\big(}\\ \wedge\; \mathsf{ivk} \not\in \{0, \bot\} \vphantom{\Big(}\\ \wedge\; \text{let } \mathsf{pk_d} = [\mathsf{ivk}]\, \mathsf{g_d} \vphantom{\big(}\\ \wedge\; \text{let } \text{ψ} = \mathsf{H^{\text{ψ},Orchard}_{rseed}}(\underline{\text{ρ}}) \vphantom{\Big(}\\ \wedge\; \text{let } \mathsf{noterepr} = \big(\mathsf{repr}_{\mathbb{P}}(\mathsf{g_d}), \mathsf{repr}_{\mathbb{P}}(\mathsf{pk_d}), \mathsf{v}, \underline{\text{ρ}}, \text{ψ}\big) \vphantom{\big(}\\ \wedge\; \text{let } \mathsf{rcm} = \mathsf{H^{rcm,Orchard}_{rseed}}\big(\mathtt{0x03}, \mathsf{noterepr}\big) \vphantom{\Big(}\\ \wedge\; \text{let } \mathsf{cm} = \mathsf{NoteCommit^{Orchard}_{rcm}}(\mathsf{noterepr}) \vphantom{\big(}\\ \wedge\; \mathsf{cm} \neq \bot \vphantom{\Big(}\\ \wedge\; \text{let } \mathsf{cm}_x = \mathsf{Extract}_{\mathbb{P}}(\mathsf{cm}) \vphantom{\big(}\\ \wedge\; \text{let } \mathsf{leaf} = \mathsf{MerkleCRH}(\mathsf{cm}_x, \text{ρ}) \vphantom{\Big(}\\ \wedge\; \mathsf{path} \textsf{ is a path to } \mathsf{leaf} \textsf{ in the rehashed commitment tree} \vphantom{\big(}\\ \wedge\; \mathsf{nf} = \mathsf{DeriveNullifier_{nk}}(\text{ρ}, \text{ψ}, \mathsf{cm}) \vphantom{\Big(}\\ \} \end{array}

and nf\mathsf{nf} is the revealed nullifier.

(We don't need to check the derivation of gd\mathsf{g_d} from d\mathsf{d}.)

Cost

Note that in the "use_qsk\mathsf{use\_qsk}" case, one BLAKE2b compression is required to compute rivk_ext\mathsf{rivk\_ext} (provided ℓqk≤504\ell_{\mathsf{qk}} \leq 504 bits, so that the input qk ∣∣ [0x0D] ∣∣ ak ∣∣ nk\mathsf{qk} \,||\, [\mathtt{0x0D}] \,||\, \mathsf{ak} \,||\, \mathsf{nk} fits in a single 128-byte BLAKE2b block), and in the "not use_qsk\mathsf{use\_qsk}" case, three BLAKE2b compressions in total are required to compute Hask\mathsf{H^{ask}}, Hnk\mathsf{H^{nk}}, and Hrivk_legacy\mathsf{H^{rivk\_legacy}}. Since these cases are mutually exclusive, it is possible to multiplex the same three compression function instances. So, supporting "use_qsk\mathsf{use\_qsk}" in addition to "not use_qsk\mathsf{use\_qsk}" costs very little extra.

All of the operations below need to be implemented with complete additions, even if they are incomplete in the current Orchard[ZSA] statement/circuit.

In SoKsk\mathsf{SoK^{sk}} and the main circuit:

  • 7 BLAKE2b-512 compressions:
    • 3 multiplexed between Hrivk_ext\mathsf{H^{rivk\_ext}} when use_qsk\mathsf{use\_qsk} is true (1 compression), and Hask\mathsf{H^{ask}} + Hnk\mathsf{H^{nk}} + Hrivk_legacy\mathsf{H^{rivk\_legacy}} when use_qsk\mathsf{use\_qsk} is false (3 compressions)
    • 1 to compute Hrivk_int\mathsf{H^{rivk\_int}}
    • 1 to compute Hψ\mathsf{H^{\text{ψ}}}
    • 2 to compute Hrcm\mathsf{H^{rcm}}
  • 1 use of Commitivk\mathsf{Commit^{ivk}} (SinsemillaShortCommit\mathsf{SinsemillaShortCommit})
  • 1 use of NoteCommit\mathsf{NoteCommit} (SinsemillaCommit\mathsf{SinsemillaCommit})
  • 1 full-width fixed-base Pallas scalar multiplication, [ask] GOrchard[\mathsf{ask}]\, \mathcal{G}^{\mathsf{Orchard}}
  • 1 full-width variable-base Pallas scalar multiplication, [ivk] gd[\mathsf{ivk}]\, \mathsf{g_d}
  • 1 Merkle tree path check
  • 1 additional use of MerkleCRH\mathsf{MerkleCRH} to compute leaf\mathsf{leaf}.

In SoKqsk\mathsf{SoK^{qsk}}:

  • 1 BLAKE3 compression for Hqk\mathsf{H^{qk}} (with the derive_key\mathsf{derive\_key} context key precomputed as a constant)

plus, potentially, linking commitments between the circuits.

The expensive parts of this are the 7 BLAKE2b compressions.

Security analysis

Let us consider the security of the Orchard protocol against a discrete-logarithm-breaking adversary — which by definition includes quantum adversaries. Similar attacks apply to the Sapling protocol.

Suppose that the proof system has been replaced by one that is post-quantum knowledge-sound.

Repairing the note commitment Merkle tree

MerkleCRH\mathsf{MerkleCRH} is instantiated using SinsimillaHash\mathsf{SinsimillaHash} 32. Its collision resistance depends on the Discrete Logarithm Relation Problem on the Pallas curve 33, and so it is not post-quantum collision-resistant or collapsing. However, because the note commitment tree is public, it is possible to re-hash all of its leaves to construct a new Merkle tree using a collapsing hash function. Suppose this has been done.

The post-quantum security of Merkle trees —considered as position-binding vector commitments which is the property required by Zcash 27— is proven under reasonable assumptions in 34, 35, and 36.

Note: when we rehash the commitment tree, we could include both ρ\text{ρ} and cmx\mathsf{cm}_x for each note (i.e. what is currently the leaf layer becomes MerkleCRH(ρ,cmx)\mathsf{MerkleCRH}(\text{ρ}, \mathsf{cm}_x) where MerkleCRH\mathsf{MerkleCRH} is collapsing). This change might not be necessary; it just removes potential complications due to duplicate commitments for the same note.

Attacks against binding of note commitments

We still face the problem that NoteCommit\mathsf{NoteCommit} is not binding against a discrete-logarithm-breaking adversary: given the discrete logarithm relations between bases, we can easily write a linear equation in the scalar field with multiple solutions of the inputs for a given commitment.

This allows an adversary to find two distinct notes corresponding to openings of NoteCommit\mathsf{NoteCommit} on the same commitment. They create one note as an output and spend the other note — which may have a greater value, or a value in a different ZSA asset, breaking the Balance property.

Repairing note commitments

We prefer to fix this without changing NoteCommit\mathsf{NoteCommit} itself. Instead we change how rcm\mathsf{rcm} is computed to be a hash of rseed\mathsf{rseed} and noterepr=(g⋆d,pk⋆d,v,ρ‾,ψ)\mathsf{noterepr} = (\mathsf{g}\star_{\mathsf{d}}, \mathsf{pk}\star_{\mathsf{d}}, \mathsf{v}, \underline{\text{ρ}}, \text{ψ}), as detailed in the [Specification] section. Specifically, when leadByte=0x03\mathsf{leadByte} = \mathtt{0x03} we have:

rcm=Hrseedrcm(noterepr)=ToScalar(PRFrseedexpand(pre_rcm))\hspace{2em}\mathsf{rcm} = \mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) = \mathsf{ToScalar}(\mathsf{PRF^{expand}_{rseed}}(\mathsf{pre\_rcm}))

where pre_rcm=[0x0B] ∣∣ encode(noterepr)\text{where } \mathsf{pre\_rcm} = [\mathtt{0x0B}] \,||\, \mathsf{encode}(\mathsf{noterepr})

Informal security argument for binding of note commitments

For the formal versions of these arguments and their adaptation to the post-quantum setting, see the key-binding and Spendability theorems below, and the Adaptation to the quantum setting section.

We can view the output of NoteCommitrcm\mathsf{NoteCommit_{rcm}} for notetuple=(rseed,noterepr)\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr}) as the point addition of a randomization term [Hrseedrcm(noterepr)] R[\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr})]\, \mathcal{R}, and some other function of notetuple\mathsf{notetuple}.

Without loss of generality, we can write that function as [f(notetuple)] R[\mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}, by expanding each of the Sinemilla bases Cj=Q(D) or S(j)\mathcal{C}_j = \mathcal{Q}(D) \textsf{ or } \mathcal{S}(j) used by HashToSinsimillaPoint\mathsf{HashToSinsimillaPoint} as Cj=[cj] R\mathcal{C}_j = [c_j]\, \mathcal{R} for some cjc_j. That is, the note commitment for notetuple\mathsf{notetuple} is

[Hrseedrcm(noterepr)+f(notetuple)] R.[\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}\textsf{.}

We will model Hrcm\mathsf{H^{rcm}} as a random oracle independent of f\mathsf{f} with uniform output on FrP\mathbb{F}_{r_{\mathbb{P}}}. This is reasonable because Hrcm\mathsf{H^{rcm}} cannot depend on any of the cjc_j, and in any case it is instantiated using BLAKE2b, a conventional hash function not related to the Pallas curve.

The fact that NoteCommit\mathsf{NoteCommit} has ψ=Hrseedψ(ρ)\text{ψ} = \mathsf{H}^{\text{ψ}}_{\mathsf{rseed}}(\text{ρ}) as an input does not affect the analysis provided that Hrcm\mathsf{H^{rcm}} and Hψ\mathsf{H}^{\text{ψ}} can be treated as independent. In practice both are defined in terms of PRFexpand\mathsf{PRF^{expand}}, but with strict domain separation, and so the assumption of independence is reasonable as long as BLAKE2b-512 can be modelled as a random oracle. Note that since the input to Hrcm\mathsf{H^{rcm}} needs more than one BLAKE2b input block, we require that a HAIFA sponge can be modelled as a random oracle which is justified by 37. It is possible that there could be better-than-generic quantum attacks against BLAKE2b-512, but none have been published to our knowledge. In practice, we consider it reasonable to assume that BLAKE2b-512 has the properties needed for Hrcm\mathsf{H^{rcm}} to be collapsing. Taking the 512-bit BLAKE2b output modulo rP≈2254r_{\mathbb{P}} \approx 2^{254} cannot introduce a problem.

For each Hrcm\mathsf{H^{rcm}} oracle query the adversary chooses notetuple=(rseed,noterepr)\mathsf{notetuple} = (\mathsf{rseed}, \mathsf{noterepr}) and obtains a "random" rcm=Hrseedrcm(noterepr)\mathsf{rcm} = \mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}).

We have cmx=ExtractP([Hrseedrcm(noterepr)+f(notetuple)] R)\mathsf{cm}_x = \mathsf{Extract}_{\mathbb{P}}([\mathsf{H^{rcm}_{rseed}}(\mathsf{noterepr}) + \mathsf{f}(\mathsf{notetuple})]\, \mathcal{R}).

Over all Pallas curve points PP, the number of outputs of ExtractP(P)\mathsf{Extract}_{\mathbb{P}}(P) is (FrP+1)/2≈2253(\mathbb{F}_{r_\mathbb{P}} + 1)/2 \approx 2^{253} — one for each possible xx-coordinate of Pallas curve points, plus one for the zero point OP\mathcal{O}_{\mathbb{P}} which is mapped to 00.

Only one point maps to 00, as opposed to two points mapping to every other possible output of ExtractP\mathsf{Extract}_{\mathbb{P}}, but that has negligible effect.

There are two values of cm\mathsf{cm} that match cmx\mathsf{cm}_x in their xx-coordinate. Because the output of NoteCommitrcm\mathsf{NoteCommit_{rcm}} for notetuple\mathsf{notetuple} is of the form cm=[f(notetuple)+rcm] R\mathsf{cm} = [\mathsf{f}(\mathsf{notetuple}) + \mathsf{rcm}]\, \mathcal{R}, for any given note we have exactly two values of rcm\mathsf{rcm} that will pass the commitment check.

Suppose there are NN legitimate notes in the tree. The adversary is trying to find a note that will pass the commitment check without actually being a note in the tree. As argued above, the distribution of rcm\mathsf{rcm} is indistinguishable from uniform-random on FrP\mathbb{F}_{r_\mathbb{P}}. The success probability for each attempt in a classical search is therefore 2N/rP2N/r_{\mathbb{P}} where rPr_{\mathbb{P}} is the order of the Pallas curve, and that is negligible because N≤232≪rPN \leq 2^{32} \ll r_{\mathbb{P}}.

We're not finished yet because we also have to prove that the nullifier is computed deterministically for a given note.

All of the inputs to DeriveNullifier\mathsf{DeriveNullifier} are things we committed to in the protocol so far except nk\mathsf{nk}. By the same argument used pre-quantumly, there is only one ivk\mathsf{ivk} for a given (gd,pkd)(\mathsf{g_d}, \mathsf{pk_d}). So in order to just use the existing protocol for this part, we would need to prove that there is only one nk\mathsf{nk} (that is feasible to find) such that Commitrivkivk(ak,nk)=ivk\mathsf{Commit^{ivk}_{rivk}}(\mathsf{ak}, \mathsf{nk}) = \mathsf{ivk}. Unfortunately that's not true; Commitivk\mathsf{Commit^{ivk}} is instantiated by SinsemillaShortCommit\mathsf{SinsemillaShortCommit} which is not post-quantum binding.

There are two cases depending on which witness branch the adversary uses (they can choose to attack either, or both simultaneously):

Citation graph

Hover or tap a node to see its title and citations.
Loading citation graph…
ZIP 2005: Ironwood Quantum Recoverability · ZIP.tools