mirror of https://github.com/zcash/orchard.git
Merge pull request #10 from zcash/nullifier-rationale
book: Add nullifier rationale
This commit is contained in:
commit
fe32db4be1
|
@ -29,7 +29,6 @@ Group hashing uses the isogeny.
|
|||
- nsk goes away; `nk` is now a field element
|
||||
- TODO: ak / nk split enables splitting the security argument, but could consider merging.
|
||||
Merging would help with ivk derivation perf (though as a commitment now it's pretty cheap)
|
||||
- TODO: nullifier computation
|
||||
|
||||
ZIP 32 integration
|
||||
- Use same Sapling design?
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
# Commitments
|
||||
|
||||
As in Sapling, we require two kinds of commitment schemes in Pollard:
|
||||
- $HomomorphicCommit$ is a linearly homomorphic commitment scheme with perfect hiding, and
|
||||
As in Sapling, we require two kinds of commitment schemes in Orchard:
|
||||
- $\mathit{HomomorphicCommit}$ is a linearly homomorphic commitment scheme with perfect hiding,
|
||||
and strong binding reducible to DL.
|
||||
- $\mathit{Commit}$ and $\mathit{ShortCommit}$ are commitment schemes with perfect hiding, and
|
||||
strong binding reducible to DL.
|
||||
- $Commit$ and $ShortCommit$ are commitment schemes with perfect hiding, and strong
|
||||
binding reducible to DL.
|
||||
|
||||
By "strong binding" we mean that the scheme is collision resistant on the input and
|
||||
randomness.
|
||||
|
||||
We instantiate $HomomorphicCommit$ with a Pedersen commitment, and use it for value
|
||||
commitments:
|
||||
We instantiate $\mathit{HomomorphicCommit}$ with a Pedersen commitment, and use it for
|
||||
value commitments:
|
||||
|
||||
$$\mathsf{cv} = HomomorphicCommit^{\mathsf{cv}}_{\mathsf{rcv}}(v)$$
|
||||
$$\mathsf{cv} = \mathit{HomomorphicCommit}^{\mathsf{cv}}_{\mathsf{rcv}}(v)$$
|
||||
|
||||
We instantiate $Commit$ and $ShortCommit$ with Sinsemilla, and use them for all other
|
||||
commitments:
|
||||
We instantiate $\mathit{Commit}$ and $\mathit{ShortCommit}$ with Sinsemilla, and use them
|
||||
for all other commitments:
|
||||
|
||||
$$\mathsf{ivk} = ShortCommit^{\mathsf{ivk}}_{\mathsf{rivk}}(\mathsf{nk}, \mathsf{ak})$$
|
||||
$$\mathsf{cm} = Commit^{\mathsf{cm}}_{\mathsf{rcm}}(\text{rest of note})$$
|
||||
$$\mathsf{ivk} = \mathit{ShortCommit}^{\mathsf{ivk}}_{\mathsf{rivk}}(\mathsf{ak}, \mathsf{nk})$$
|
||||
$$\mathsf{cm} = \mathit{Commit}^{\mathsf{cm}}_{\mathsf{rcm}}(\text{rest of note})$$
|
||||
|
||||
This is the same split (and rationale) as in Sapling, but using the more PLONK-efficient
|
||||
Sinsemilla instead of Bowe-Hopwood Pedersen hashes.
|
||||
Sinsemilla instead of Bowe--Hopwood Pedersen hashes.
|
||||
|
||||
Note that we also deviate from Sapling by using $ShortCommit$ to deriving $\mathsf{ivk}$
|
||||
Note that we also deviate from Sapling by using $\mathit{ShortCommit}$ to deriving $\mathsf{ivk}$
|
||||
instead of a full PRF. This removes an unnecessary (large) PRF primitive from the circuit,
|
||||
at the cost of requiring $\mathsf{rivk}$ to be part of the full viewing key.
|
||||
|
|
|
@ -2,34 +2,26 @@
|
|||
|
||||
The nullifier design we use for Orchard is
|
||||
|
||||
$$\mathsf{nf} = [Hash_{\mathsf{nk}}(\psi)] H + [\mathsf{rnf}] \mathcal{I},$$
|
||||
$$\mathsf{nf} = [F_{\mathsf{nk}}(\rho) + \psi \pmod{p}] \mathcal{G} + \mathsf{cm},$$
|
||||
|
||||
where:
|
||||
- $Hash$ is a keyed circuit-efficient hash (such as Rescue).
|
||||
- $GH$ is a cryptographic hash into the group (such as BLAKE2s with simplified SWU).
|
||||
- $\mathcal{I}$ is a fixed base, independent of any others returned by $GH$.
|
||||
- $H$ is a base unique to this output.
|
||||
- For non-zero-valued notes, $H = GH(\rho)$. As with $\mathsf{h_{Sig}}$ in Sprout,
|
||||
$\rho$ includes the nullifiers of any Orchard notes being spent in the same action.
|
||||
Given that an action consists of a single spend and a single output, we set $\rho$ to
|
||||
be the nullifier of the spent note.
|
||||
- For zero-valued notes, $H$ is constrained by the circuit to a fixed base independent
|
||||
of $\mathcal{I}$ and any others returned by $GH$.
|
||||
|
||||
- $F$ is a keyed circuit-efficient PRF (such as Rescue or Poseidon).
|
||||
- $\rho$ is unique to this output. As with $\mathsf{h_{Sig}}$ in Sprout, $\rho$ includes
|
||||
the nullifiers of any Orchard notes being spent in the same action. Given that an action
|
||||
consists of a single spend and a single output, we set $\rho$ to be the nullifier of the
|
||||
spent note.
|
||||
- $\psi$ is sender-controlled randomness. It is not required to be unique, and in practice
|
||||
is derived from both $\rho$ and a sender-selected random value $\mathsf{rseed}$:
|
||||
$\psi = KDF^\psi(\rho, \mathsf{rseed})$.
|
||||
- $\mathsf{rnf}$ is a blinding scalar, similarly generated as
|
||||
$\mathsf{rnf} = KDF^\mathsf{rnf}(\rho, \mathsf{rseed})$.
|
||||
$$\psi = KDF^\psi(\rho, \mathsf{rseed}).$$
|
||||
- $\mathcal{G}$ is a fixed independent base.
|
||||
|
||||
This gives a note structure of
|
||||
|
||||
$$(addr, v, H, \psi, \mathsf{rnf}, \mathsf{rcm}).$$
|
||||
$$(addr, v, \rho, \psi, \mathsf{rcm}).$$
|
||||
|
||||
The note plaintext includes $\mathsf{rseed}$ in place of $\psi$, $\mathsf{rnf}$, and
|
||||
$\mathsf{rcm}$. $H$ is omitted entirely from the action:
|
||||
- Consensus nodes directly derive $GH(\rho)$ and provide it as a public input to the
|
||||
circuit (which ignores it for zero-valued notes, as with the commitment tree anchor).
|
||||
- The recipient can recompute the correct $H$ given their additional knowledge of $v$.
|
||||
The note plaintext includes $\mathsf{rseed}$ in place of $\psi$ and $\mathsf{rcm}$, and
|
||||
omits $\rho$ (which is a public part of the action).
|
||||
|
||||
## Security properties
|
||||
|
||||
|
@ -38,28 +30,34 @@ We care about several security properties for our nullifiers:
|
|||
- **Balance:** can I forge money?
|
||||
|
||||
- **Note Privacy:** can I gain information about notes only from the public block chain?
|
||||
|
||||
- This describes notes sent in-band.
|
||||
|
||||
- **Note Privacy (OOB):** can I gain information about notes sent out-of-band, only from
|
||||
the public block chain?
|
||||
|
||||
- In this case, we assume privacy of the channel over which the note is sent, and that
|
||||
the adversary does not have access to any notes sent to the same address which are
|
||||
then spent (so that the nullifier is on the block chain somewhere).
|
||||
|
||||
- **Spend Unlinkability:** given the incoming viewing key for an address, and not the full
|
||||
viewing key, can I (possibly the sender) detect spends of any notes sent to that address?
|
||||
- We're giving $ivk$ to the attacker and allowing it to be the sender in order to make
|
||||
this property as strong as possible: they will have *all* the notes sent to that
|
||||
|
||||
- We're giving $\mathsf{ivk}$ to the attacker and allowing it to be the sender in order
|
||||
to make this property as strong as possible: they will have *all* the notes sent to that
|
||||
address.
|
||||
|
||||
- **Faerie Resistance:** can I perform a Faerie Gold attack (i.e. cause notes to be
|
||||
accepted that are unspendable)?
|
||||
|
||||
- We're giving the full viewing key to the attacker and allowing it to be the sender in
|
||||
order to make this property as strong as possible: they will have *all* the notes sent
|
||||
to that address, and be able to derive *every* nullifier.
|
||||
|
||||
We assume (and instantiate elsewhere) the following primitives:
|
||||
|
||||
- $GH$ is a cryptographic hash into the group (such as BLAKE2s with simplified SWU), used
|
||||
to derive all fixed independent bases.
|
||||
- $E$ is an elliptic curve (such as Pallas).
|
||||
- $KDF$ is the note encryption key derivation function.
|
||||
|
||||
|
@ -67,21 +65,29 @@ For our chosen design, our desired security properties rely on the following ass
|
|||
|
||||
$$
|
||||
\begin{array}{|l|l|}
|
||||
\hline
|
||||
\text{Balance} & DL_E \\
|
||||
\text{Note Privacy} & HashDH^{KDF}_E \\
|
||||
\text{Note Privacy (OOB)} & \text{Perfect} \\
|
||||
\text{Spend Unlinkability} & DDH_E^\dagger \vee PRF_{Hash} \\
|
||||
\text{Faerie Resistance} & (RO_{GH} \vee (Coll_{GH} \wedge RO_{Hash})) \wedge DL_E \\
|
||||
\text{Note Privacy} & \mathit{HashDH}^{KDF}_E \\
|
||||
\text{Note Privacy (OOB)} & \text{Near perfect} \ddagger \\
|
||||
\text{Spend Unlinkability} & DDH_E^\dagger \vee PRF_F \\
|
||||
\text{Faerie Resistance} & DL_E \\
|
||||
\hline
|
||||
\end{array}
|
||||
$$
|
||||
|
||||
$HashDH^{F}_E$ is computational Diffie-Hellman using $F$ for the key derivation, with
|
||||
$\mathit{HashDH}^{KDF}_E$ is computational Diffie-Hellman using $KDF$ for the key derivation, with
|
||||
one-time ephemeral keys. This assumption is heuristically weaker than $DDH_E$ but stronger
|
||||
than $DL_E$.
|
||||
|
||||
We omit $RO_{GH}$ as a security assumption because we only rely on the random oracle
|
||||
applied to fixed inputs defined by the protocol, i.e. to generate the fixed base
|
||||
$\mathcal{G}$, not to attacker-specified inputs.
|
||||
|
||||
> $\dagger$ We additionally assume that for any input $x$,
|
||||
> $\{Hash_{\mathsf{nk}}(x) : \mathsf{nk} \in E\}$ gives a scalar in an adequate range for
|
||||
> $DDH_E$. (Otherwise, $Hash$ could be trivial, e.g. independent of $\mathsf{nk}$.)
|
||||
> $\{F_{\mathsf{nk}}(x) : \mathsf{nk} \in E\}$ gives a scalar in an adequate range for
|
||||
> $DDH_E$. (Otherwise, $F$ could be trivial, e.g. independent of $\mathsf{nk}$.)
|
||||
>
|
||||
> $\ddagger$ Statistical distance $< 2^{-167.8}$ from perfect.
|
||||
|
||||
## Considered alternatives
|
||||
|
||||
|
@ -92,29 +98,151 @@ not fully rigorous.
|
|||
$$
|
||||
\begin{array}{|c|l|c|c|c|c|c|}
|
||||
\hline
|
||||
\mathsf{nf} & Note & \text{Balance} & \text{Note Privacy} & \text{Note Privacy (OOB)} & \text{Spend Unlinkability} & \text{Faerie Resistance} & \text{Rejected because} \\\hline
|
||||
[\mathsf{nk}] [\theta] H & (addr, v, H, \theta, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E & RO_{GH} \wedge DL_E & \text{No SU for DL-breaking} \\\hline
|
||||
[\mathsf{nk}] H + [\mathsf{rnf}] \mathcal{I} & (addr, v, H, \mathsf{rnf}, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E & RO_{GH} \wedge DL_E & \text{No SU for DL-breaking} \\\hline
|
||||
Hash([\mathsf{nk}] [\theta] H) & (addr, v, H, \theta, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E \vee Pre_{Hash} & Coll_{Hash} \wedge RO_{GH} \wedge DL_E & Coll_{Hash} \text{ for FR} \\\hline
|
||||
Hash([\mathsf{nk}] H + [\mathsf{rnf}] \mathcal{I}) & (addr, v, H, \mathsf{rnf}, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E \vee Pre_{Hash} & Coll_{Hash} \wedge RO_{GH} \wedge DL_E & Coll_{Hash} \text{ for FR} \\\hline
|
||||
[Hash_{\mathsf{nk}}(\psi)] [\theta] H & (addr, v, H, \theta, \psi, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_{Hash} & RO_{GH} \wedge DL_E & 2 \text{ variable-base scalar mults} \\\hline
|
||||
[Hash_{\mathsf{nk}}(\psi)] \mathcal{G} + [\theta] H & (addr, v, H, \theta, \psi, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_{Hash} & RO_{GH} \wedge DL_E \\\hline
|
||||
[Hash_{\mathsf{nk}}(\psi)] H + \mathsf{cm} & (addr, v, H, \psi, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & PRF_{Hash} & DDH_E^\dagger \vee PRF_{Hash} & (RO_{GH} \vee (Coll_{GH} \wedge RO_{Hash})) \wedge DL_E & PRF_{Hash} \text{ for NP(OOB)} \\\hline
|
||||
[Hash_{\mathsf{nk}}(\rho, \psi)] \mathcal{G} + \mathsf{cm} & (addr, v, \rho, \psi, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & PRF_{Hash} & DDH_E^\dagger \vee PRF_{Hash} & Coll_{Hash} \wedge DL_E & PRF_{Hash} \text{ for NP(OOB)} \\\hline
|
||||
[Hash_{\mathsf{nk}}(\rho)] \mathcal{G} + \mathsf{cm} & (addr, v, \rho, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & PRF_{Hash} & DDH_E^\dagger \vee PRF_{Hash} & Coll_{Hash} \wedge DL_E & PRF_{Hash} \text{ for NP(OOB)} \\\hline
|
||||
[Hash_{\mathsf{nk}}(\rho, \psi)] \mathcal{G} + Commit^{\mathsf{nf}}_{\mathsf{rnf}}(v, \rho) & (addr, v, \rho, \mathsf{rnf}, \psi, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_{Hash} & Coll_{Hash} \wedge DL_E & Coll_{Hash} \text{ for FR} \\\hline
|
||||
[Hash_{\mathsf{nk}}(\rho)] \mathcal{G} + Commit^{\mathsf{nf}}_{\mathsf{rnf}}(v, \rho) & (addr, v, \rho, \mathsf{rnf}, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_{Hash} & Coll_{Hash} \wedge DL_E & Coll_{Hash} \text{ for FR} \\\hline
|
||||
[Hash_{\mathsf{nk}}(\rho, \psi)] \mathcal{G} + [\mathsf{rnf}] \mathcal{I} + \mathsf{cm} & (addr, v, \rho, \mathsf{rnf}, \psi, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_{Hash} & Coll_{Hash} \wedge DL_E & Coll_{Hash} \text{ for FR} \\\hline
|
||||
[Hash_{\mathsf{nk}}(\rho)] \mathcal{G} + [\mathsf{rnf}] \mathcal{I} + \mathsf{cm} & (addr, v, \rho, \mathsf{rnf}, \mathsf{rcm}) & DL_E & HashDH^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_{Hash} & Coll_{Hash} \wedge DL_E & Coll_{Hash} \text{ for FR} \\\hline
|
||||
\mathsf{nf} & Note & \text{Balance} & \text{Note Privacy} & \text{Note Privacy (OOB)} & \text{Spend Unlinkability} & \text{Faerie Resistance} & \text{Reason not to use} \\\hline
|
||||
[\mathsf{nk}] [\theta] H & (addr, v, H, \theta, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E & RO_{GH} \wedge DL_E & \text{No SU for DL-breaking} \\\hline
|
||||
[\mathsf{nk}] H + [\mathsf{rnf}] \mathcal{I} & (addr, v, H, \mathsf{rnf}, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E & RO_{GH} \wedge DL_E & \text{No SU for DL-breaking} \\\hline
|
||||
\mathit{Hash}([\mathsf{nk}] [\theta] H) & (addr, v, H, \theta, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E \vee Pre_{\mathit{Hash}} & Coll_{\mathit{Hash}} \wedge RO_{GH} \wedge DL_E & Coll_{\mathit{Hash}} \text{ for FR} \\\hline
|
||||
\mathit{Hash}([\mathsf{nk}] H + [\mathsf{rnf}] \mathcal{I}) & (addr, v, H, \mathsf{rnf}, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E \vee Pre_{\mathit{Hash}} & Coll_{\mathit{Hash}} \wedge RO_{GH} \wedge DL_E & Coll_{\mathit{Hash}} \text{ for FR} \\\hline
|
||||
[F_{\mathsf{nk}}(\psi)] [\theta] H & (addr, v, H, \theta, \psi, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_F & RO_{GH} \wedge DL_E & \text{Performance (2 variable-base)} \\\hline
|
||||
[F_{\mathsf{nk}}(\psi)] H + [\mathsf{rnf}] \mathcal{I} & (addr, v, H, \mathsf{rnf}, \psi, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_F & RO_{GH} \wedge DL_E & \text{Performance (1 variable- + 1 fixed-base)} \\\hline
|
||||
[F_{\mathsf{nk}}(\psi)] \mathcal{G} + [\theta] H & (addr, v, H, \theta, \psi, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_F & RO_{GH} \wedge DL_E & \text{Performance (1 variable- + 1 fixed-base)} \\\hline
|
||||
[F_{\mathsf{nk}}(\psi)] H + \mathsf{cm} & (addr, v, H, \psi, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & DDH_E^\dagger & DDH_E^\dagger \vee PRF_F & RO_{GH} \wedge DL_E & \text{NP(OOB) not perfect} \\\hline
|
||||
[F_{\mathsf{nk}}(\rho, \psi)] \mathcal{G} + \mathsf{cm} & (addr, v, \rho, \psi, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & DDH_E^\dagger & DDH_E^\dagger \vee PRF_F & DL_E & \text{NP(OOB) not perfect} \\\hline
|
||||
[F_{\mathsf{nk}}(\rho)] \mathcal{G} + \mathsf{cm} & (addr, v, \rho, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & DDH_E^\dagger & DDH_E^\dagger \vee PRF_F & DL_E & \text{NP(OOB) not perfect} \\\hline
|
||||
[F_{\mathsf{nk}}(\rho, \psi)] \mathcal{G_v} + [\mathsf{rnf}] \mathcal{I} & (addr, v, \rho, \mathsf{rnf}, \psi, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_F & Coll_F \wedge DL_E & Coll_F \text{ for FR} \\\hline
|
||||
[F_{\mathsf{nk}}(\rho)] \mathcal{G_v} + [\mathsf{rnf}] \mathcal{I} & (addr, v, \rho, \mathsf{rnf}, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_F & Coll_F \wedge DL_E & Coll_F \text{ for FR} \\\hline
|
||||
[F_{\mathsf{nk}}(\rho) + \psi \pmod{p}] \mathcal{G_v} & (addr, v, \rho, \psi, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Near perfect} \ddagger & DDH_E^\dagger \vee PRF_F & \color{red}{\text{broken}} & \text{broken for FR} \\\hline
|
||||
[F_{\mathsf{nk}}(\rho, \psi)] \mathcal{G} + \mathit{Commit}^{\mathsf{nf}}_{\mathsf{rnf}}(v, \rho) & (addr, v, \rho, \mathsf{rnf}, \psi, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_F & DL_E & \text{Performance (2 fixed-base)} \\\hline
|
||||
[F_{\mathsf{nk}}(\rho)] \mathcal{G} + \mathit{Commit}^{\mathsf{nf}}_{\mathsf{rnf}}(v, \rho) & (addr, v, \rho, \mathsf{rnf}, \mathsf{rcm}) & DL_E & \mathit{HashDH}^{KDF}_E & \text{Perfect} & DDH_E^\dagger \vee PRF_F & DL_E & \text{Performance (2 fixed-base)} \\\hline
|
||||
\end{array}
|
||||
$$
|
||||
|
||||
In the above alternatives:
|
||||
- $\mathcal{G}$ is an fixed independent base, independent of $\mathcal{I}$ and any others
|
||||
returned by $GH$.
|
||||
|
||||
The $Commit^{\mathsf{nf}}$ variants enabled nullifier domain separation based on note
|
||||
value, without directly depending on $\mathsf{cm}$ (which in its native type is a base
|
||||
field element, not a group element). We decided instead to follow Sapling by defining an
|
||||
intermediate representation of $\mathsf{cm}$ as a group element, that is only used in
|
||||
- $\mathit{Hash}$ is a keyed circuit-efficient hash (such as Rescue).
|
||||
- $\mathcal{I}$ is an fixed independent base, independent of $\mathcal{G}$ and any others
|
||||
returned by $GH$.
|
||||
- $\mathcal{G_v}$ is a pair of fixed independent bases (independent of all others), where
|
||||
the specific choice of base depends on whether the note has zero value.
|
||||
- $H$ is a base unique to this output.
|
||||
|
||||
- For non-zero-valued notes, $H = GH(\rho)$. As with $\mathsf{h_{Sig}}$ in Sprout,
|
||||
$\rho$ includes the nullifiers of any Orchard notes being spent in the same action.
|
||||
- For zero-valued notes, $H$ is constrained by the circuit to a fixed base independent
|
||||
of $\mathcal{I}$ and any others returned by $GH$.
|
||||
|
||||
## Rationale
|
||||
|
||||
In order to satisfy the **Balance** security property, we require that the circuit must be
|
||||
able to enforce that only one nullifier is accepted for a given note. As in Sprout and
|
||||
Sapling, we achieve this by ensuring that the nullifier deterministically depends only on
|
||||
values committed to (directly or indirectly) by the note commitment. As in Sapling,
|
||||
this involves arguing that:
|
||||
|
||||
- There can be only one $\mathsf{ivk}$ for a given $\mathit{addr}$. This is true because
|
||||
the circuit checks that $\mathsf{pk_d} = [\mathsf{ivk}] \mathsf{g_d}$, and the mapping
|
||||
$\mathsf{ivk} \mapsto [\mathsf{ivk}] \mathsf{g_d}$ is an injection for any $\mathsf{g_d}$.
|
||||
($\mathsf{ivk}$ is in the base field of $E$, which must be smaller than its scalar field,
|
||||
as is the case for Pallas.)
|
||||
- There can be only one $\mathsf{nk}$ for a given $\mathsf{ivk}$. This is true because the
|
||||
circuit checks that $\mathsf{ivk} = \mathit{ShortCommit}^{\mathsf{ivk}}_{\mathsf{rivk}}(\mathsf{ak}, \mathsf{nk})$
|
||||
where $\mathit{ShortCommit}$ is binding (see [Commitments](commitments.html)).
|
||||
|
||||
### Use of $\rho$
|
||||
|
||||
**Faerie Resistance** requires that nullifiers be unique. This is primarily achieved by
|
||||
taking a unique value (checked for uniqueness by the public consensus rules) as an input
|
||||
to the nullifier. However, it is also necessary to ensure that the transformations applied
|
||||
to this value preserve its uniqueness. Meanwhile, to achieve **Spend Unlinkability**, we
|
||||
require that the nullifier does not reveal any information about the unique value it is
|
||||
derived from.
|
||||
|
||||
The design alternatives fall into two categories in terms of how they balance these
|
||||
requirements:
|
||||
|
||||
- Publish a unique value $\rho$ at note creation time, and blind that value within the
|
||||
nullifier computation.
|
||||
|
||||
- This is similar to the approach taken in Sprout and Sapling, which both implemented
|
||||
nullifiers as PRF outputs; Sprout uses the compression function from SHA-256, while
|
||||
Sapling uses BLAKE2s.
|
||||
|
||||
- Derive a unique base $H$ from some unique value, publish that unique base at note
|
||||
creation time, and then blind the base (either additively or multiplicatively) during
|
||||
nullifier computation.
|
||||
|
||||
For **Spend Unlinkability**, the only value unknown to the adversary is $\mathsf{nk}$, and
|
||||
the cryptographic assumptions only involve the first term (other terms like $\mathsf{cm}$
|
||||
or $[\mathsf{rnf}] \mathcal{I}$ cannot be extracted directly from the observed nullifiers,
|
||||
but can be subtracted from them). We therefore ensure that the first term does not commit
|
||||
directly to the note (to avoid a DL-breaking adversary from immediately breaking **SU**).
|
||||
|
||||
We were considering using a design involving $H$ with the goal of eliminating all usages
|
||||
of a PRF inside the circuit, for two reasons:
|
||||
|
||||
- Instantiating $PRF_F$ with a traditional hash function is expensive in the circuit.
|
||||
- We didn't want to solely rely on an algebraic hash function satisfying $PRF_F$ to
|
||||
achieve **Spend Unlinkability**.
|
||||
|
||||
However, those designs rely on both $RO_{GH}$ and $DL_E$ for **Faerie Resistance**, while
|
||||
still requiring $DDH_E$ for **Spend Unlinkability**. (There are two designs for which this
|
||||
is not the case, but they rely on $DDH_E^\dagger$ for **Note Privacy (OOB)** which was not
|
||||
acceptable).
|
||||
|
||||
By contrast, several designs involving $\rho$ (including the chosen design) have weaker
|
||||
assumptions for **Faerie Resistance** (only relying on $DL_E$), and **Spend Unlinkability**
|
||||
does not require $PRF_F$ to hold: they can fall back on the same $DDH_E$ assumption as the
|
||||
$H$ designs (along with an additional assumption about the output of $F$ which is easily
|
||||
satisfied).
|
||||
|
||||
### Use of $\psi$
|
||||
|
||||
Most of the designs include either a multiplicative blinding term $[\theta] H$, or an
|
||||
additive blinding term $[\mathsf{rnf}] \mathcal{I}$, in order to achieve perfect
|
||||
**Note Privacy (OOB)** (to an adversary who does not know the note). The chosen design is
|
||||
effectively using $[\psi] \mathcal{G}$ for this purpose; a DL-breaking adversary only
|
||||
learns $F_{\mathsf{nk}}(\rho) + \psi \pmod{p}$. This reduces **Note Privacy (OOB)** from
|
||||
perfect to statistical, but given that $\psi$ is from a distribution statistically close
|
||||
to uniform on $[0, q)$, this is statistically close to better than $2^{-128}$. The benefit
|
||||
is that it does not require an additional scalar multiplication, making it more efficient
|
||||
inside the circuit.
|
||||
|
||||
$\psi$'s derivation has two motivations:
|
||||
|
||||
- Deriving from a random value $\mathsf{rseed}$ enables multiple derived values to be
|
||||
conveyed to the recipient within an action (such as the ephemeral secret $\mathsf{esk}$,
|
||||
per [ZIP 212](https://zips.z.cash/zip-0212)), while keeping the note plaintext short.
|
||||
- Mixing $\rho$ into the derivation ensures that the sender can't repeat $\psi$ across two
|
||||
notes, which could have enabled spend linkability attacks in some designs.
|
||||
|
||||
The note that is committed to, and which the circuit takes as input, only includes $\psi$
|
||||
(i.e. the circuit does not check the derivation from $\mathsf{rseed}$). However, an
|
||||
adversarial sender is still constrained by this derivation, because the recipient
|
||||
recomputes $\psi$ during note decryption. If an action were created using an arbitrary
|
||||
$\psi$ (for which the adversary did not have a corresponding $\mathsf{rseed}$), the
|
||||
recipient would derive a note commitment that did not match the action's commitment field,
|
||||
and reject it (as in Sapling).
|
||||
|
||||
### Use of $\mathsf{cm}$
|
||||
|
||||
The nullifier commits to the note value via $\mathsf{cm}$ for two reasons:
|
||||
|
||||
- It domain-separates nullifiers for zero-valued notes from other notes. This is necessary
|
||||
because we do not require zero-valued notes to exist in the commitment tree.
|
||||
- Designs that bind the nullifier to $F_{\mathsf{nk}}(\rho)$ require $Coll_F$ to achieve
|
||||
**Faerie Resistance** (and similarly where $\mathit{Hash}$ is applied to a value derived from
|
||||
$H$). Adding $\mathsf{cm}$ to the nullifier avoids this assumption: all of the bases
|
||||
used to derive $\mathsf{cm}$ are fixed and independent of $\mathcal{G}$, and so the
|
||||
nullifier can be viewed as a Pedersen hash where the input includes $\rho$ directly.
|
||||
|
||||
The $\mathit{Commit}^{\mathsf{nf}}$ variants were considered to avoid directly depending on
|
||||
$\mathsf{cm}$ (which in its native type is a base field element, not a group element). We
|
||||
decided instead to follow Sapling by defining an intermediate representation of
|
||||
$\mathsf{cm}$ as a group element, that is only used in nullifier computation. The circuit
|
||||
already needs to compute $\mathsf{cm}$, so this improves performance by removing
|
||||
|
||||
We also considered variants that used a choice of fixed bases $\mathcal{G_v}$ to provide
|
||||
domain separation for zero-valued notes. The most performant design (similar to the chosen
|
||||
design) does not achieve **Faerie Resistance** for an adversary that knows the recipient's
|
||||
full viewing key ($\psi$ could be brute-forced to cancel out $F_{\mathsf{nk}}(\rho)$,
|
||||
causing a collision), and the other variants require assuming $Coll_F$ as mentioned above.
|
||||
|
|
Loading…
Reference in New Issue