Abstract
This proposal describes a mechanism for creating signatures with Sapling addresses, suitable for use by the signmessage
and verifymessage
RPC methods in zcashd
.
@@ -41,28 +41,28 @@ License: MIT
\(\mathsf{MerkleCRH}^\mathsf{Sapling}\)
- \(\mathsf{DiversifyHash}(d)\)
+ \(\mathsf{DiversifyHash}(\mathsf{d})\)
- \(\mathsf{MixingPedersenHash}(cm, position)\)
+ \(\mathsf{MixingPedersenHash}(\mathsf{cm}, position)\)
- \(\mathsf{PRF}^\mathsf{nfSapling}_nk(ρ)\)
+ \(\mathsf{PRF}^\mathsf{nfSapling}_\mathsf{nk}(ρ)\)
- \(\mathsf{SpendAuthSig.RandomizePrivate}(α, sk)\)
+ \(\mathsf{SpendAuthSig.RandomizePrivate}(α, \mathsf{sk})\)
,
- \(\mathsf{SpendAuthSig.RandomizePublic}(α, vk)\)
+ \(\mathsf{SpendAuthSig.RandomizePublic}(α, \mathsf{vk})\)
,
- \(\mathsf{SpendAuthSig.Sign}(sk, m)\)
+ \(\mathsf{SpendAuthSig.Sign}(\mathsf{sk}, m)\)
, and
- \(\mathsf{SpendAuthSig.Verify}(vk, m, σ)\)
+ \(\mathsf{SpendAuthSig.Verify}(\mathsf{vk}, m, σ)\)
- \(\mathsf{NoteCommit}^\mathsf{Sapling}_rcm(g_d, pk_d, value)\)
+ \(\mathsf{NoteCommit}^\mathsf{Sapling}_\mathsf{rcm}(\mathsf{g_d}, \mathsf{pk_d}, value)\)
- \(\mathsf{ValueCommit}_rcv(value)\)
+ \(\mathsf{ValueCommit}_\mathsf{rcv}(value)\)
We also reproduce some notation and functions here for convenience:
@@ -102,17 +102,21 @@ License: MIT
Specification
A Sapling address signature is created by taking the process for creating a Sapling Spend description, and running it with fixed inputs:
- - A fake Sapling note with a value of 1 zatoshi and rcm = 0.
+ - A fake Sapling note with a value of
+ \(1\)
+ zatoshi and
+ \(\mathsf{rcm} = 0\)
+ .
- A Sapling commitment tree that is empty except for the commitment for the fake note.
Signature algorithm
The inputs to the signature algorithm are:
@@ -190,17 +194,17 @@ License: MIT
The inputs to the verification algorithm are:
- The payment address
- \((d, pk_d)\)
+ \((\mathsf{d}, \mathsf{pk_d})\)
,
- The SLIP-44 coin type,
- The message
\(msg\)
that is claimed to be signed, and
- The ZIP 304 signature
- \((nf, rk, zkproof, spendAuthSig)\)
+ \((\mathsf{nf}, \mathsf{rk}, zkproof, spendAuthSig)\)
.
- The signature is verified as follows:
+ The signature MUST be verified as follows:
- Let
\(coinType\)
@@ -209,29 +213,29 @@ License: MIT
\(digest = \mathsf{BLAKE2b}\text{-}\mathsf{256}(\texttt{"ZIP304Signed"}\,||\,coinType, zkproof\,||\,msg)\)
.
- If
- \(\mathsf{SpendAuthSig.Verify}(rk, digest, spendAuthSig) = 0\)
+ \(\mathsf{SpendAuthSig.Verify}(\mathsf{rk}, digest, spendAuthSig) = 0\)
, return false.
- Let
- \(cm = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{DiversifyHash}(d)), \mathsf{repr}_\mathbb{J}(pk_d), 1)\)
+ \(\mathsf{cm} = \mathsf{NoteCommit}^\mathsf{Sapling}_0(\mathsf{repr}_\mathbb{J}(\mathsf{DiversifyHash}(\mathsf{d})), \mathsf{repr}_\mathbb{J}(\mathsf{pk_d}), 1)\)
.
- Let
- \(rt\)
+ \(\mathsf{rt}\)
be the root of a Merkle tree with depth
\(\mathsf{MerkleDepth}^\mathsf{Sapling}\)
and hashing function
\(\mathsf{MerkleCRH}^\mathsf{Sapling}\)
, containing
- \(cm\)
+ \(\mathsf{cm}\)
at position 0, and
\(\mathsf{Uncommitted}^\mathsf{Sapling}\)
at all other positions.
- Let
\(path\)
be the Merkle path from position 0 to
- \(rt\)
+ \(\mathsf{rt}\)
.
- Let
- \(cv = \mathsf{ValueCommit}_0(1)\)
+ \(\mathsf{cv} = \mathsf{ValueCommit}_0(1)\)
.
- This is a constant and may be pre-computed.
@@ -240,31 +244,33 @@ License: MIT
- Verify
\(zkproof\)
as a Sapling spend proof with primary input
- \((rt, cv, nf, rk)\)
+ \((\mathsf{rt}, \mathsf{cv}, \mathsf{nf}, \mathsf{rk})\)
. If verification fails, return false.
- Return true.
Signature encoding
The raw form of a ZIP 304 signature is
- \(nf\,||\,rk\,||\,zkproof\,||\,spendAuthSig\)
+ \(\mathsf{nf}\,||\,\mathsf{rk}\,||\,zkproof\,||\,spendAuthSig\)
, for a total size of 320 bytes.
When encoding a ZIP 304 signature in a human-readable format, implementations SHOULD use standard Base64 for compatibility with the signmessage
and verifymessage
RPC methods in zcashd
. ZIP 304 signatures in this form are 428 bytes. The encoded form is the string 'zip304:' followed by the result of Base64-encoding the raw form of the signature.
Rationale
We use a fake note within the signature scheme in order to reuse the Sapling Spend circuit and its parameters. It is possible to construct a signature scheme with a smaller encoded signature, but this would require a new circuit and another parameter-generation ceremony (if Groth16 were used).
- We use a note value of 1 zatoshi instead of zero to ensure that the payment address is fully bound to
+
We use a note value of
+ \(1\)
+ zatoshi instead of zero to ensure that the payment address is fully bound to
\(zkproof\)
. Notes with zero value have certain constraints disabled inside the circuit.
We set
- \(rcm\)
+ \(\mathsf{rcm}\)
and
- \(rcv\)
+ \(\mathsf{rcv}\)
to zero because we do not need the hiding properties of the note commitment or value commitment schemes (as we are using a fixed-value fake note), and can thus omit both
- \(rcm\)
+ \(\mathsf{rcm}\)
and
- \(rcv\)
+ \(\mathsf{rcv}\)
from the signature.