Compare commits

...

8 Commits

Author SHA1 Message Date
Daira Hopwood e57ce2056f Fix raw encoding diagrams and descriptions. 8 years ago
Daira Hopwood 563abc2a00 More work in progress. 8 years ago
Daira Hopwood a1cdc3b436 Work in progress. 8 years ago
Daira Hopwood 5047e2e7f3 Add key_components diagram. 8 years ago
Daira Hopwood 21266e21a8 Mark changes, more WIP for viewing keys. 8 years ago
Daira Hopwood 25b8fdc5e4 WIP fixes. 8 years ago
David Stainton a0f4b09fa9 More WIP 8 years ago
Daira Hopwood 9f2965f69f Work in progress on viewing key support. 8 years ago
  1. 4
      protocol/Makefile
  2. BIN
      protocol/key_components.odg
  3. BIN
      protocol/key_components.pdf
  4. BIN
      protocol/key_components_alt.odg
  5. BIN
      protocol/protocol.pdf
  6. 470
      protocol/protocol.tex

4
protocol/Makefile

@ -1,4 +1,8 @@
protocol.pdf: protocol.tex zcash.bib incremental_merkle.pdf
$(MAKE) pdf
.PHONY: pdf
pdf:
# If pdflatex fails, touch an input so that 'make' won't think it is up-to-date next time.
pdflatex protocol.tex || touch incremental_merkle.pdf
bibtex protocol

BIN
protocol/key_components.odg

Binary file not shown.

BIN
protocol/key_components.pdf

Binary file not shown.

BIN
protocol/key_components_alt.odg

Binary file not shown.

BIN
protocol/protocol.pdf

Binary file not shown.

470
protocol/protocol.tex

@ -35,6 +35,7 @@
\newcommand{\term}[1]{\textsl{#1}\xspace}
\newcommand{\termbf}[1]{\textbf{#1}\xspace}
\newcommand{\conformance}[1]{\textmd{#1}\xspace}
\newcommand{\Zcash}{\termbf{Zcash}}
\newcommand{\Zerocash}{\termbf{Zerocash}}
@ -42,6 +43,12 @@
\newcommand{\ZEC}{\termbf{ZEC}}
\newcommand{\zatoshi}{\term{zatoshi}}
\newcommand{\MUST}{\conformance{MUST}}
\newcommand{\MUSTNOT}{\conformance{MUST NOT}}
\newcommand{\SHOULD}{\conformance{SHOULD}}
\newcommand{\SHOULDNOT}{\conformance{SHOULD NOT}}
\newcommand{\MAY}{\conformance{MAY}}
\newcommand{\coin}{\term{coin}}
\newcommand{\coins}{\term{coins}}
\newcommand{\coinCommitment}{\term{coin commitment}}
@ -67,15 +74,21 @@
\newcommand{\script}{\term{script}}
\newcommand{\serialNumber}{\term{serial number}}
\newcommand{\serialNumbers}{\term{serial numbers}}
\newcommand{\publicAddress}{\term{confidential address}}
% Let's rename ``privateAddress'' to something else, since it sounds like an oxymoron to me. (This is related to a code naming issue #602 and we might want to update both at the same time.)
\newcommand{\privateAddress}{\term{confidential private key}}
% Daira: This doesn't adequately distinguish between zk stuff and transparent stuff
\newcommand{\paymentAddress}{\term{payment address}}
\newcommand{\paymentAddresses}{\term{payment addresses}}
\newcommand{\viewingKey}{\term{viewing key}}
\newcommand{\viewingKeys}{\term{viewing keys}}
\newcommand{\spendingKey}{\term{spending key}}
\newcommand{\spendingKeys}{\term{spending keys}}
\newcommand{\keyTuple}{\term{key tuple}}
\newcommand{\coinPlaintext}{\term{coin plaintext}}
\newcommand{\coinPlaintexts}{\term{coin plaintexts}}
\newcommand{\coinsCiphertext}{\term{transmitted coins ciphertext}}
\newcommand{\transmitPublicAlgorithm}{\term{key-private encryption}}
\newcommand{\transmitPrivateAlgorithm}{\term{key-private decryption}}
\newcommand{\spendAuthority}{\term{spend authority}}
\newcommand{\authKeypair}{\term{authorization}}
\newcommand{\transmitKeypair}{\term{transmission}}
\newcommand{\discloseKeypair}{\term{disclosure}}
\newcommand{\keyPrivateAlgorithm}{\term{key-private encryption scheme}}
\newcommand{\incrementalMerkleTree}{\term{incremental merkle tree}}
\newcommand{\spentSerialsMap}{\term{spent serial numbers map}}
\newcommand{\zkSNARK}{\term{zk-SNARK}}
@ -83,20 +96,27 @@
\newcommand{\memo}{\term{memo field}}
% key pairs:
\newcommand{\PublicAddress}{\mathsf{addr_{pk}}}
\newcommand{\PrivateAddress}{\mathsf{addr_{sk}}}
\newcommand{\PublicAddressLeadByte}{\mathbf{0x92}}
\newcommand{\PrivateAddressLeadByte}{\mathbf{0x93}}
\newcommand{\SpendAuthorityPublic}{\mathsf{a_{pk}}}
\newcommand{\SpendAuthorityPrivate}{\mathsf{a_{sk}}}
\newcommand{\SpendAuthorityPublicOld}[1]{\mathsf{a^{old}_{pk,\mathnormal{#1}}}}
\newcommand{\SpendAuthorityPrivateOld}[1]{\mathsf{a^{old}_{sk,\mathnormal{#1}}}}
\newcommand{\SpendAuthorityPublicNew}[1]{\mathsf{a^{new}_{pk,\mathnormal{#1}}}}
\newcommand{\SpendAuthorityPrivateNew}[1]{\mathsf{a^{new}_{sk,\mathnormal{#1}}}}
\newcommand{\TransmitPublic}{\mathsf{pk_{enc}}}
\newcommand{\TransmitPublicNew}[1]{\mathsf{pk_{enc,\mathnormal{#1}}}}
\newcommand{\TransmitPrivate}{\mathsf{sk_{enc}}}
\newcommand{\TransmitPrivateNew}[1]{\mathsf{sk_{enc,\mathnormal{#1}}}}
\newcommand{\PaymentAddress}{\mathsf{addr_{pk}}}
\newcommand{\ViewingKey}{\mathsf{addr_{viewkey}}}
\newcommand{\SpendingKey}{\mathsf{addr_{sk}}}
\newcommand{\PaymentAddressLeadByte}{\mathbf{0x92}}
\newcommand{\ViewingKeyLeadByte}{\mathbf{0x??}}
\newcommand{\SpendingKeyLeadByte}{\mathbf{0x93}}
\newcommand{\AuthPublic}{\mathsf{a_{pk}}}
\newcommand{\AuthPrivate}{\mathsf{a_{sk}}}
\newcommand{\AuthPublicOld}[1]{\mathsf{a^{old}_{pk,\mathnormal{#1}}}}
\newcommand{\AuthPrivateOld}[1]{\mathsf{a^{old}_{sk,\mathnormal{#1}}}}
\newcommand{\AuthPublicNew}[1]{\mathsf{a^{new}_{pk,\mathnormal{#1}}}}
\newcommand{\AuthPrivateNew}[1]{\mathsf{a^{new}_{sk,\mathnormal{#1}}}}
\newcommand{\enc}{\mathsf{enc}}
\newcommand{\disclose}{\mathsf{disclose}}
\newcommand{\PublicKey}[1]{\mathsf{pk_\mathnormal{#1}}}
\newcommand{\PrivateKey}[1]{\mathsf{sk_\mathnormal{#1}}}
\newcommand{\SecretKey}[1]{\mathsf{K_\mathnormal{#1}}}
\newcommand{\TransmitPublic}{\PublicKey{\enc}}
\newcommand{\TransmitPrivate}{\PrivateKey{\enc}}
\newcommand{\DisclosePublic}{\PublicKey{\disclose}}
\newcommand{\DisclosePrivate}{\PrivateKey{\disclose}}
\newcommand{\EphemeralPublic}{\mathsf{pk_{eph}}}
\newcommand{\EphemeralPrivate}{\mathsf{sk_{eph}}}
\newcommand{\Value}{\mathsf{v}}
@ -118,12 +138,17 @@
\newcommand{\CryptoBoxOpen}{\mathsf{crypto\_box\_open}}
\newcommand{\CryptoBoxSeal}{\mathsf{crypto\_box\_seal}}
\newcommand{\CryptoBoxSpecific}{\mathsf{crypto\_box\_curve25519xsalsa20poly1305}}
\newcommand{\CryptoSecretBox}{\mathsf{crypto\_secretbox}}
\newcommand{\CryptoSecretBoxOpen}{\mathsf{crypto\_secretbox\_open}}
\newcommand{\CryptoSecretBoxSpecific}{\mathsf{crypto\_secretbox\_xsalsa20poly1305}}
\newcommand{\Plaintext}[1]{\mathbf{P}_{#1}}
\newcommand{\Ciphertext}[1]{\mathbf{C}_{#1}}
\newcommand{\SymCiphertext}[1]{\mathbf{C}^\mathsf{sym}_{#1}}
\newcommand{\Ciphertext}[1]{\mathbf{C}^\mathsf{pk}_{#1}}
\newcommand{\Tag}[1]{\mathsf{tag}_{#1}}
\newcommand{\Nonce}{\mathsf{nonce}}
\newcommand{\Prenonce}{\mathsf{prenonce}}
\newcommand{\TransmitEncrypt}[1]{\mathsf{Encrypt}_{#1}}
\newcommand{\TransmitDecrypt}[1]{\mathsf{Decrypt}_{#1}}
\newcommand{\Encrypt}[1]{\mathsf{Encrypt}_{#1}}
\newcommand{\Decrypt}[1]{\mathsf{Decrypt}_{#1}}
\newcommand{\CRH}{\mathsf{CRH}}
\newcommand{\CRHbox}[1]{\CRH\left(\;\raisebox{-1.3ex}{\usebox{#1}}\;\right)}
\newcommand{\FullHash}{\mathtt{SHA256}}
@ -134,6 +159,7 @@
\newcommand{\PRFsn}[1]{\PRF{#1}{sn}}
\newcommand{\PRFpk}[1]{\PRF{#1}{pk}}
\newcommand{\PRFrho}[1]{\PRF{#1}{\CoinAddressRand}}
\newcommand{\PRFsym}[1]{\PRF{#1}{sym}}
\newcommand{\SHA}{\mathtt{SHA256Compress}}
\newcommand{\SHAName}{\term{SHA-256 compression}}
\newcommand{\SHAOrig}{\term{SHA-256}}
@ -162,7 +188,8 @@
\newcommand{\serials}{\mathtt{serials}}
\newcommand{\commitments}{\mathtt{commitments}}
\newcommand{\ephemeralKey}{\mathtt{ephemeralKey}}
\newcommand{\ciphertexts}{\mathtt{ciphertexts}}
\newcommand{\symCiphertexts}{\mathtt{symCiphertexts}}
\newcommand{\pkCiphertexts}{\mathtt{pkCiphertexts}}
\newcommand{\rt}{\mathsf{rt}}
% pour
@ -191,7 +218,7 @@
\begin{document}
\title{Zcash Protocol Specification \\
\Large Version 2.0-draft-1}
\Large Version 2.0-draft-2}
\author{Sean Bowe | Daira Hopwood | Taylor Hornby}
\date{\today}
\maketitle
@ -211,6 +238,23 @@ protected by zero-knowledge succinct non-interactive arguments of knowledge
Changes from the original \Zerocash are highlighted in \changed{\changedcolor}.
\section{Caution}
\Zcash security depends on consensus. Should your program diverge from
consensus, its security is weakened or destroyed. The cause of the divergence
doesn't matter: it could be a bug in your program, it could be an error in
this documentation which you implemented as described, or it could be you do
everything right but other software on the network behaves unexpectedly. The
specific cause will not matter to the users of your software whose wealth is
lost.
Having said that, a specification of \emph{intended} behaviour is essential
for security analysis, understanding of the protocol, and maintenance of
Zcash Core and related software. If you find any mistake in this specification,
please contact \todo{address}. While the production \Zcash network has yet
to be launched, please feel free to do so in public even if you believe the
mistake may indicate a security weakness.
\section{Concepts}
\subsection{Integers, Bit Sequences, and Endianness}
@ -237,46 +281,50 @@ is used which takes a 512-bit block and produces a 256-bit hash. This is
different from the $\SHAOrig$ function, which hashes arbitrary-length strings.
\cite{sha256}
$\PRF{x}{}$ is a pseudo-random function seeded by $x$. \changed{Four} \emph{independent}
$\PRF{x}{}$ is a pseudo-random function seeded by $x$. \changed{Five} \emph{independent}
$\PRF{x}{}$ are needed in our scheme: $\PRFaddr{x}$, $\PRFsn{x}$, $\PRFpk{x}$\changed{,
and $\PRFrho{x}$}. It is required that $\PRFsn{x}$ \changed{and $\PRFrho{x}$} be
collision-resistant across all $x$ --- i.e. it should not be feasible to find
$(x, y) \neq (x', y')$ such that $\PRFsn{x}(y) = \PRFsn{x'}(y')$\changed{, and similarly
for $\PRFrho{}$}.
$\PRFrho{x}$, and $\PRFsym{x}$}. It is required that $\PRFsn{x}$
\changed{and $\PRFrho{x}$} be collision-resistant across all $x$ --- i.e.
it should not be feasible to find $(x, y) \neq (x', y')$ such that
$\PRFsn{x}(y) = \PRFsn{x'}(y')$\changed{, and similarly for $\PRFrho{}$}.
In \Zcash, the $\SHAName$ function is used to construct all four of these
functions. The bits $\mathtt{00}$, $\mathtt{01}$, $\mathtt{10}$\changed{, and
$\mathtt{11}$} are included (respectively) within the blocks that are hashed,
ensuring that the functions are independent.
In \Zcash, the $\SHAName$ function is used to construct all \changed{five} of these
functions. The bit patterns $\mathtt{0000}$, $\mathtt{01xx}$, $\mathtt{10xx}$\changed{,
$\mathtt{11xx}$, and $\mathtt{00x1}$} are included (respectively) within the
blocks that are hashed, ensuring that these functions are independent.
\newcommand{\iminusone}{\hspace{0.3pt}\scriptsize{$i$\hspace{0.6pt}-1}}
\newsavebox{\addrbox}
\begin{lrbox}{\addrbox}
\begin{bytefield}[bitwidth=0.065em]{512}
\bitbox{242}{256 bit $\SpendAuthorityPrivate$} &
\bitbox{14}{0} &
\bitbox{14}{0} &
\bitbox{242}{$0^{254}$} &
\bitbox{242}{256 bit $\AuthPrivate$} &
\bitbox{18}{0} &
\bitbox{18}{0} &
\bitbox{18}{0} &
\bitbox{18}{0} &
\bitbox{180}{$0^{252}$} &
\end{bytefield}
\end{lrbox}
\newsavebox{\snbox}
\begin{lrbox}{\snbox}
\begin{bytefield}[bitwidth=0.065em]{512}
\bitbox{242}{256 bit $\SpendAuthorityPrivate$} &
\bitbox{14}{0} &
\bitbox{14}{1} &
\bitbox{242}{$\Leading{254}(\CoinAddressRand)$} &
\bitbox{242}{256 bit $\AuthPrivate$} &
\bitbox{18}{0} &
\bitbox{18}{1} &
\bitbox{216}{$\Leading{254}(\CoinAddressRand)$} &
\end{bytefield}
\end{lrbox}
\newsavebox{\pkbox}
\begin{lrbox}{\pkbox}
\begin{bytefield}[bitwidth=0.065em]{512}
\bitbox{242}{256 bit $\SpendAuthorityPrivate$} &
\bitbox{14}{1} &
\bitbox{14}{0} &
\bitbox{14}{$i$} &
\bitbox{228}{$\Leading{253}(\hSig)$}
\bitbox{242}{256 bit $\AuthPrivate$} &
\bitbox{18}{1} &
\bitbox{18}{0} &
\bitbox{18}{\iminusone} &
\bitbox{198}{$\Leading{253}(\hSig)$}
\end{bytefield}
\end{lrbox}
@ -285,10 +333,23 @@ ensuring that the functions are independent.
\setchanged
\begin{bytefield}[bitwidth=0.065em]{512}
\bitbox{242}{256 bit $\CoinAddressPreRand$} &
\bitbox{14}{1} &
\bitbox{14}{1} &
\bitbox{14}{$i$} &
\bitbox{228}{$\Leading{253}(\hSig)$}
\bitbox{18}{1} &
\bitbox{18}{1} &
\bitbox{18}{\iminusone} &
\bitbox{198}{$\Leading{253}(\hSig)$}
\end{bytefield}
\end{lrbox}
\newsavebox{\symbox}
\begin{lrbox}{\symbox}
\setchanged
\begin{bytefield}[bitwidth=0.065em]{512}
\bitbox{242}{256 bit $\SecretKey{\disclose}$} &
\bitbox{18}{0} &
\bitbox{18}{0} &
\bitbox{18}{\iminusone} &
\bitbox{18}{1}
\bitbox{180}{$0^{252}$}
\end{bytefield}
\end{lrbox}
@ -297,54 +358,85 @@ is associated with this bit-packing.}
\begin{equation*}
\begin{aligned}
\SpendAuthorityPublic &:= \PRFaddr{\SpendAuthorityPrivate}(0) &= \CRHbox{\addrbox} \\
\sn &:= \PRFsn{\SpendAuthorityPrivate}(\CoinAddressRand) &= \CRHbox{\snbox} \\
\h{i} &:= \PRFpk{\SpendAuthorityPrivate}(i, \hSig) &= \CRHbox{\pkbox} \\
\AuthPublic &:= \PRFaddr{\AuthPrivate}(0) &= \CRHbox{\addrbox} \\
\sn &:= \PRFsn{\AuthPrivate}(\CoinAddressRand) &= \CRHbox{\snbox} \\
\h{i} &:= \PRFpk{\AuthPrivate}(i, \hSig) &= \CRHbox{\pkbox} \\
\setchanged \CoinAddressRandNew{i} &\setchanged := \PRFrho{\CoinAddressPreRand}(i, \hSig)
&\setchanged = \CRHbox{\rhobox}
&\setchanged = \CRHbox{\rhobox} \\
\setchanged \SecretKey{i} &\setchanged := \PRFsym{\SecretKey{\disclose}}(i)
&\setchanged = \CRHbox{\symbox}
\end{aligned}
\end{equation*}
\daira{Should we instead define $\CoinAddressRand$ to be 254 bits and $\hSig$ to be
253 bits?}
\subsection{Confidential Addresses and Private Keys}
\subsection{Payment Addresses\changed{, Viewing Keys,} and Spending Keys}
A \keyTuple $(\PaymentAddress, \changed{\ViewingKey,\;} \SpendingKey)$ is generated
by users who wish to receive payments under this scheme. The parts of
the \keyTuple are composed from \changed{three} distinct keypairs, called the
\authKeypair, \transmitKeypair \changed{, and \discloseKeypair} keypairs.
\begin{itemize}
\item The \paymentAddress $\PaymentAddress$ is a pair
$(\AuthPublic, \TransmitPublic)$, containing the \emph{public}
components of the \authKeypair and \transmitKeypair keypairs
respectively.
\changed{
\item The \viewingKey $\ViewingKey$ is a pair
$(\TransmitPrivate, \DisclosePrivate)$, containing the \emph{private}
components of the \transmitKeypair and \discloseKeypair keypairs
respectively.
}
\item The \spendingKey $\SpendingKey$ is a \changed{triple}
$(\AuthPrivate, \TransmitPrivate\changed{, \DisclosePrivate})$,
containing the \emph{private} components of the \authKeypair,
\transmitKeypair\changed{, and \discloseKeypair} keypairs respectively.
\end{itemize}
The following diagram depicts the relations between key components.
Arrows point from a private component to the corresponding public
component derived from it.
\nathan{This term, \publicAddress, may be confusing by comparison to
a ``private key''. In the latter case the adjective is reminding a
user of their responsibility to protect its privacy, but in the case
of \publicAddress we want users to know ``transfers to this address
are confidential, but the address itself *may* be published or kept
confidential depending on your needs. Two different people can compare
addresses to know they have the same \publicAddress.''}
\begin{center}
\includegraphics[scale=.5]{key_components}
\end{center}
Note that a \spendingKey holder can derive
$(\AuthPublic, \TransmitPublic\changed{, \DisclosePublic})$,
\changed{and a \viewingKey holder can derive $(\TransmitPublic, \DisclosePublic)$,}
even though these components are not formally part of the respective keys.
Implementations \MAY cache these derived public components, provided that
they are deleted if the corresponding private component is deleted.
A key pair $(\PublicAddress, \PrivateAddress)$ is generated by
users who wish to receive coins under this scheme. The tuple parts
embody two distinct keypairs used for different purposes called
the \spendAuthority and the \transmitPublicAlgorithm keypair. The
\publicAddress $\PublicAddress$ is a tuple $(\SpendAuthorityPublic,
\TransmitPublic)$, containing the public components of the \spendAuthority
and \transmitPublicAlgorithm respectively. The $\PrivateAddress$ is
a tuple $(\SpendAuthorityPrivate, \TransmitPrivate)$, containing the
secret components respectively.
The composition of \paymentAddresses\changed{, \viewingKeys,} and \spendingKeys
is a cryptographic protocol detail that should not normally be
exposed to users. However, user-visible operations should be provided
to:
\nathan{A diagram could really help here.}
\begin{itemize}
\changed{
\item obtain a \viewingKey from a \spendingKey; and
}
\item obtain a \paymentAddress from a \spendingKey.
\end{itemize}
Users can accept payment from multiple parties with a single
$\PublicAddress$ and the fact that these payments are destined to
$\PaymentAddress$ and the fact that these payments are destined to
the same payee is not revealed on the blockchain, even to the
paying parties. \emph{However} if two parties collude to compare a
$\PublicAddress$ they can trivially determine they are the same. In the
$\PaymentAddress$ they can trivially determine they are the same. In the
case that a payee wishes to prevent this they should create a distinct
\publicAddress for each payer.
\paymentAddress for each payer.
\subsection{Coins}
A \coin (denoted $\Coin$) is a tuple $\changed{(\SpendAuthorityPublic, \Value,
A \coin (denoted $\Coin$) is a tuple $\changed{(\AuthPublic, \Value,
\CoinAddressRand, \CoinCommitRand)}$ which represents that a value $\Value$ is
spendable by the recipient who holds the $\spendAuthority$ key pair
$(\SpendAuthorityPublic, \SpendAuthorityPrivate)$ such that
$\SpendAuthorityPublic = \PRFaddr{\SpendAuthorityPrivate}(0)$.
spendable by the recipient who holds the $\authKeypair$ key pair
$(\AuthPublic, \AuthPrivate)$ such that
$\AuthPublic = \PRFaddr{\AuthPrivate}(0)$.
$\CoinCommitRand$ is randomly generated by the sender. \changed{$\CoinAddressRand$
is generated from a random seed $\CoinAddressPreRand$ using
@ -357,23 +449,28 @@ the value and recipient \emph{except} to those who possess these tokens.
In order to transmit the secret $\Value$, $\CoinAddressRand$, and $\CoinCommitRand$
(necessary for the recipient to later spend) \changed{and also a \memo} to the
recipient \emph{without} requiring an out-of-band communication channel, the
$\transmitPublicAlgorithm$ public key $\TransmitPublic$ is used to encrypt these
secrets to form a \coinsCiphertext. The recipient's possession of the associated
$(\PublicAddress, \PrivateAddress)$ (which contains both $\SpendAuthorityPublic$ and
\transmitKeypair public key $\TransmitPublic$ is used to encrypt these
secrets. The recipient's possession of the associated
$(\PaymentAddress, \SpendingKey)$ (which contains both $\AuthPublic$ and
$\TransmitPrivate$) is used to reconstruct the original \coin \changed{ and \memo}.
\changed{Similarly, to transmit these values to a \viewingKey holder for outgoing
\PourTransfers, the \discloseKeypair public key $\DisclosePublic$ is used to
encrypt the same secrets.}
The encryptions are combined to form a \coinsCiphertext.
\changed{
The encryption algorithm is defined in terms of $\CryptoBox$ (i.e.
$\CryptoBoxSpecific$) \cite{cryptobox} as follows.
The encryption algorithm is defined in terms of $\CryptoBox$ (specifically,
$\CryptoBoxSpecific$) and $\CryptoSecretBox$ (specifically,
$\CryptoSecretBoxSpecific$) \cite{cryptobox} as follows.
}
\newsavebox{\prenoncebox}
\begin{lrbox}{\prenoncebox}
\setchanged
\begin{bytefield}[bitwidth=0.05em]{520}
\bitbox{120}{64 bit $i-1$} &
\bitbox{120}{64 bit $\Tag{i}$} &
\bitbox{256}{256 bit $\EphemeralPublic$}
\bitbox{256}{256 bit $\TransmitPublicNew{i}$}
\bitbox{256}{256 bit $\PublicKey{i}$}
\end{bytefield}
\end{lrbox}
@ -382,74 +479,137 @@ $\CryptoBoxSpecific$) \cite{cryptobox} as follows.
\setchanged
\begin{bytefield}[bitwidth=0.085em]{192}
\bitbox{128}{$\Leading{128}(\Prenonce)$} &
\bitbox{72}{64 bit $i-1$}
\bitbox{64}{64 bit $\Tag{i}$}
\end{bytefield}
\end{lrbox}
\newsavebox{\tagibox}
\begin{lrbox}{\tagibox}
\setchanged
\begin{bytefield}[bitwidth=0.09em]{64}
\bitbox{64}{64 bit $i-1$}
\end{bytefield}
\end{lrbox}
Let $\TransmitPublicNew{\mathrm{1}..\NNew}$ be the \changed{Curve25519} public keys
for the intended recipient addresses of each new \coin, and let $\Plaintext{1..\NNew}$
be their \coinPlaintexts.
\newsavebox{\tagdbox}
\begin{lrbox}{\tagdbox}
\setchanged
\begin{bytefield}[bitwidth=0.09em]{64}
\bitbox{64}{$1^{64}$}
\end{bytefield}
\end{lrbox}
Let $\PublicKey{\mathrm{1}..\NNew}$ be the \changed{Curve25519} public keys
for the intended recipient addresses of each new \coin,
\changed{let $\PublicKey{\disclose}$ be the sender's \discloseKeypair public key,}
and let $\Plaintext{1..\NNew}$ be the \coinPlaintexts.
\changed{
Define:
\begin{equation*}
\begin{aligned}
\Prenonce(i, \EphemeralPublic, \TransmitPublicNew{i}) &:= \FullHashbox{\prenoncebox} \\
\Nonce(i, \EphemeralPublic, \TransmitPublicNew{i}) &:= \Justthebox{\noncebox}
\Prenonce(\Tag{i}, \EphemeralPublic, \PublicKey{i}) &:= \FullHashbox{\prenoncebox} \\
\Nonce(\Tag{i}, \EphemeralPublic, \PublicKey{i}) &:= \Justthebox{\noncebox} \\
\Tag{i} &:= \Justthebox{\tagibox} \\
\Tag{\disclose} &:= \Justthebox{\tagdbox}
\end{aligned}
\end{equation*}
}
Then to encrypt:
\changed{
\begin{itemize}
\item Generate a new Curve25519 (public, private) key pair $(\EphemeralPublic, \EphemeralPrivate)$.
\item For $i$ in $\{1..\NNew\}$, let $\Ciphertext{i} = \CryptoBox(\Plaintext{i}, \TransmitPublicNew{i}, \EphemeralPrivate,
\Nonce(i, \EphemeralPublic, \TransmitPublicNew{i}))$.
\item Let $\TransmitEncrypt{\TransmitPublicNew{\mathrm{1}..\NNew}}(\Plaintext{1..\NNew}) =
(\EphemeralPublic, \Ciphertext{1..\NNew})$.
\end{itemize}
\changed{
\item Generate a new Curve25519 (public, private) key pair
$(\EphemeralPublic, \EphemeralPrivate)$.
\item Generate a random 256-bit secret key $\SecretKey{\disclose}$.
\item For $i$ in $\{1..\NNew\}$,
\begin{itemize}
\item let $\SecretKey{i} = \PRFsym{\SecretKey{\disclose}}(i)$.
\item let $\SymCiphertext{i} = \CryptoSecretBox(\Plaintext{i}, \SecretKey{i}, 0)$.
\end{itemize}
\item For $i$ in $\{1..\NNew, \disclose\}$, let
$\Ciphertext{i} = \CryptoBox(\SecretKey{i}, \PublicKey{i}, \EphemeralPrivate,
\Nonce(\Tag{i}, \EphemeralPublic, \PublicKey{i}))$
\item Let $\Encrypt{\PublicKey{\mathrm{1}..\NNew}, \PublicKey{\disclose}}(
\Plaintext{1..\NNew}) = (\EphemeralPublic, \SymCiphertext{1..\NNew},
\Ciphertext{1..\NNew}, \Ciphertext{\disclose})$.
}
\end{itemize}
%}
%Let:
%\begin{itemize}
% \item $(\PublicKey{j}, \PrivateKey{j})$ (for some $j \in \keynames$})
% be a \changed{Curve25519} (public, private) key pair;
%\changed{
% \item $\EphemeralPublic$ be an ephemeral Curve25519 public key,
%, \Ciphertext{i}{j} Then for each $i$ in $\{1..\NNew\}$, the recipient
%Let $\changed{(\EphemeralPublic,}\; \TransmitCiphertext{1..\NNew}\changed{,
%\DiscloseCiphertext{1..\NNew})}$ be the \coinsCiphertext. Then to decrypt using
%a \changed{Curve25519} (public
%Let $(\PublicNew{j}, \PrivateNew{j}
Let $(\TransmitPublic, \TransmitPrivate)$ be the recipient's \changed{Curve25519}
(public, private) key pair, and let $\changed{(\EphemeralPublic,}\;
\Ciphertext{1..\NNew}\changed{)}$ be the \coinsCiphertext.
(public, private) key pair. Then for each $i$ in $\{1..\NNew\}$, the recipient
will attempt to decrypt that ciphertext component as follows:
Then for each $i$ in $\{1..\NNew\}$, the recipient will attempt to decrypt that
ciphertext component as follows:
\begin{itemize}
\changed{
\item $\SecretKey{i} := \CryptoBoxOpen(\Ciphertext{i}, \EphemeralPublic,
\TransmitPrivate, \Nonce(\Tag{i}, \EphemeralPublic, \TransmitPublic))$
\item $\Decrypt{\TransmitPrivate}(i, \EphemeralPublic, \Ciphertext{i},
\SymCiphertext{i}) = \CryptoSecretBoxOpen(\SymCiphertext{i}, \SecretKey{i}, 0)$
}
\end{itemize}
\changed{
Similarly, let $(\DisclosePublic, \DisclosePrivate)$ be a view key holder's
Curve25519 (public, private) key pair. Then for each \PourDescription in its
\blockchainview, the view key holder will attempt to decrypt the corresponding
\coinsCiphertext as follows:
}
\begin{itemize}
\item $\TransmitDecrypt{\TransmitPrivate}(i, \EphemeralPublic, \Ciphertext{i}) =
\CryptoBoxOpen(\Ciphertext{i}, \EphemeralPublic, \TransmitPrivate,
\Nonce(i, \EphemeralPublic, \TransmitPublic))$
\end{itemize}
\changed{
\item $\SecretKey{\disclose} := \CryptoBoxOpen(\Ciphertext{\disclose}, \EphemeralPublic,
\DisclosePrivate, \Nonce(\Tag{i}, \EphemeralPublic, \DisclosePublic))$
\item For $i$ in $\{1..\NNew\}$,
\begin{itemize}
\item let $\SecretKey{i} = \PRFsym{\SecretKey{\disclose}}(i)$.
\item let $\Decrypt{\DisclosePrivate}(i, \EphemeralPublic, \Ciphertext{\disclose},
\SymCiphertext{i}) = \CryptoSecretBoxOpen(\SymCiphertext{i}, \SecretKey{i}, 0)$.
\end{itemize}
}
\end{itemize}
Any ciphertext components that fail to decrypt with a given recipient's private key
will be ignored.
Any ciphertext components that fail to decrypt \MUST be ignored. Once a component
has been decrypted, it \MUST be validated as described in section ``Coin Commitments''.
\changed{
This is a variation on the $\CryptoBoxSeal$ algorithm defined in libsodium
\cite{cryptoboxseal}, but with a single ephemeral key used for all encryptions in a
given \PourDescription, and with the nonce for each ciphertext component depending
on the index $i$. Also, $\FullHash$ (the full hash, not the compression function) is
used instead of $\mathsf{blake2b}$. The particular nonce construction is chosen so
that a known-nonce distinguisher for $\mathsf{Salsa20}$ would not directly lead to a
break of the IK-CCA (key privacy) property.
used instead of $\mathsf{blake2b}$. Symmetric encryption is used in addition to public
key encryption to reduce the overall length of the ciphertext; this also contributes
to ensuring that provided that a recipient and a viewing key holder can both decrypt
the ciphertext for a given output \coin, they see the same plaintext. The particular
nonce construction is chosen so that a known-nonce distinguisher for $\mathsf{Salsa20}$
would not directly lead to a break of the IK-CCA (key privacy) property.
}
\subsubsection{Coin Commitments}
The underlying $\Value$ and $\SpendAuthorityPublic$ are blinded with $\CoinAddressRand$
The underlying $\Value$ and $\AuthPublic$ are blinded with $\CoinAddressRand$
and $\CoinCommitRand$ using the collision-resistant hash function $\CRH$ in a
multi-layered process. The resulting hash $\cm = \CoinCommitment{\Coin}$.
\newsavebox{\ihbox}
\begin{lrbox}{\ihbox}
\begin{bytefield}[bitwidth=0.08em]{512}
\bitbox{256}{256 bit $\SpendAuthorityPublic$} &
\bitbox{256}{256 bit $\AuthPublic$} &
\bitbox{256}{256 bit $\CoinAddressRand$}
\end{bytefield}
\end{lrbox}
@ -482,8 +642,8 @@ multi-layered process. The resulting hash $\cm = \CoinCommitment{\Coin}$.
\subsubsection{Serial numbers}
A \serialNumber (denoted $\sn$) equals
$\PRFsn{\SpendAuthorityPrivate}(\CoinAddressRand)$. A \coin is spent by proving
knowledge of $\CoinAddressRand$ and $\SpendAuthorityPrivate$ in zero knowledge while
$\PRFsn{\AuthPrivate}(\CoinAddressRand)$. A \coin is spent by proving
knowledge of $\CoinAddressRand$ and $\AuthPrivate$ in zero knowledge while
disclosing $\sn$, allowing $\sn$ to be used to prevent double-spending.
\subsection{Coin Commitment Tree}
@ -608,13 +768,19 @@ $\cmNew{\mathrm{1}..\NNew}$.
\changed{
\item $\ephemeralKey$ which is a Curve25519 public key $\EphemeralPublic$.
}
\item $\ciphertexts$ which is a $\NNew$ size sequence of ciphertext components.
(\changed{$\ephemeralKey$ and} $\ciphertexts$ together form the \coinsCiphertext.)
\item $\symCiphertexts$ which is a $\NNew$ size sequence of symmetric ciphertext
components, $\SymCiphertext{\mathrm{1}..\NNew}$.
\item $\pkCiphertexts$ which is a $\NNew + 1$ size sequence of public-key-encrypted
ciphertext components, $\Ciphertext{\mathrm{1}..\NNew, \disclose}$.
($\ephemeralKey$, $\symCiphertexts$ and $\pkCiphertexts$ together form
the \coinsCiphertext.)
}
\item $\vmacs$ which is a $\NOld$ size sequence of message authentication tags
$\h{\mathrm{1}..\NOld}$ that bind $\hSig$ to each $\SpendAuthorityPrivate$ of the
$\h{\mathrm{1}..\NOld}$ that bind $\hSig$ to each $\AuthPrivate$ of the
$\PourDescription$.
\item $\zkproof$ which is the zero-knowledge proof $\PourProof$.
@ -688,15 +854,15 @@ In \Zcash, $\NOld$ and $\NNew$ are both $2$.
A valid instance of $\PourProof$ assures that given a \term{primary input}
$(\rt, \snOld{\mathrm{1}..\NOld}, \cmNew{\mathrm{1}..\NNew}, \changed{\vpubOld,\;}
\vpubNew, \hSig, \h{1..\NOld})$, a witness of \term{auxiliary input}
$(\treepath{1..\NOld}, \cOld{1..\NOld}, \SpendAuthorityPrivateOld{\mathrm{1}..\NOld},
$(\treepath{1..\NOld}, \cOld{1..\NOld}, \AuthPrivateOld{\mathrm{1}..\NOld},
\cNew{1..\NNew}\changed{, \CoinAddressPreRand})$ exists, where:
\begin{list}{}{}
\item for each $i \in \{1..\NOld\}$: $\cOld{i}$ = $(\SpendAuthorityPublicOld{i},
\item for each $i \in \{1..\NOld\}$: $\cOld{i}$ = $(\AuthPublicOld{i},
\vOld{i}, \CoinAddressRandOld{i}, \CoinCommitRandOld{i})$
\item for each $i \in \{1..\NNew\}$: $\cNew{i}$ = $(\SpendAuthorityPublicNew{i},
\item for each $i \in \{1..\NNew\}$: $\cNew{i}$ = $(\AuthPublicNew{i},
\vNew{i}, \CoinAddressRandNew{i}, \CoinCommitRandNew{i})$
\item The following conditions hold:
@ -716,16 +882,16 @@ $\changed{\vpubOld +} \vsum{i=1}{\NOld} \vOld{i} = \vpubNew + \vsum{i=1}{\NNew}
\subparagraph{Serial integrity}
for each $i \in \{1..\NNew\}$:
$\snOld{i} = \PRFsn{\SpendAuthorityPrivateOld{i}}(\CoinAddressRandOld{i})$.
$\snOld{i} = \PRFsn{\AuthPrivateOld{i}}(\CoinAddressRandOld{i})$.
\subparagraph{Spend authority}
for each $i \in \{1..\NOld\}$:
$\SpendAuthorityPublicOld{i} = \PRFaddr{\SpendAuthorityPrivateOld{i}}(0)$.
$\AuthPublicOld{i} = \PRFaddr{\AuthPrivateOld{i}}(0)$.
\subparagraph{Non-malleability}
for each $i \in \{1..\NOld\}$: $\h{i}$ = $\PRFpk{\SpendAuthorityPrivateOld{i}}(i, \hSig)$
for each $i \in \{1..\NOld\}$: $\h{i}$ = $\PRFpk{\AuthPrivateOld{i}}(i, \hSig)$
\changed{
\subparagraph{Uniqueness of $\CoinAddressRandNew{i}$}
@ -762,8 +928,8 @@ These are encoded in the same way as in \Bitcoin \cite{Base58Check}.
\subsection{Confidential Public Addresses}
A \publicAddress consists of $\SpendAuthorityPublic$ and $\TransmitPublic$.
$\SpendAuthorityPublic$ is a SHA-256 compression function output.
A \paymentAddress consists of $\AuthPublic$ and $\TransmitPublic$.
$\AuthPublic$ is a SHA-256 compression function output.
$\TransmitPublic$ is a \changed{Curve25519} public key, for use with the
encryption scheme defined in section ``In-band secret distribution".
@ -773,18 +939,19 @@ The raw encoding of a confidential address consists of:
\begin{equation*}
\begin{bytefield}[bitwidth=0.07em]{520}
\bitbox{48}{\changed{$\PublicAddressLeadByte$}} &
\bitbox{256}{$\SpendAuthorityPublic$ (32 bytes)} &
\changed{
\bitbox{48}{$\PaymentAddressLeadByte$}
&}\bitbox{256}{$\AuthPublic$ (32 bytes)} &
\bitbox{256}{A \changed{32-byte} encoding of $\TransmitPublic$}
\end{bytefield}
\end{equation*}
\begin{itemize}
\changed{
\item A byte, $\PublicAddressLeadByte$, indicating this version of the
\item A byte, $\PaymentAddressLeadByte$, indicating this version of the
raw encoding of a \Zcash public address.
}
\item 32 bytes specifying $\SpendAuthorityPublic$.
\item 32 bytes specifying $\AuthPublic$.
\item \changed{32 bytes} specifying $\TransmitPublic$, \changed{using the
normal encoding of a Curve25519 public key \cite{Curve25519}}.
\end{itemize}
@ -796,8 +963,8 @@ and produces `z' as the Base58Check leading character.}
\subsection{Confidential Address Secrets}
A confidential address secret consists of $\SpendAuthorityPrivate$ and
$\TransmitPrivate$. $\SpendAuthorityPrivate$ is a SHA-256 compression function
A confidential address secret consists of $\AuthPrivate$ and
$\TransmitPrivate$. $\AuthPrivate$ is a SHA-256 compression function
output. $\TransmitPrivate$ is a \changed{Curve25519} private key, for use with
the encryption scheme defined in section ``In-band secret distribution".
@ -807,18 +974,19 @@ The raw encoding of a confidential address secret consists of, in order:
\begin{equation*}
\begin{bytefield}[bitwidth=0.07em]{520}
\bitbox{48}{\changed{$\PrivateAddressLeadByte$}} &
\bitbox{256}{$\SpendAuthorityPrivate$ (32 bytes)} &
\changed{
\bitbox{48}{$\SpendingKeyLeadByte$}
&}\bitbox{256}{$\AuthPrivate$ (32 bytes)} &
\bitbox{256}{$\TransmitPrivate$ (32 bytes)}
\end{bytefield}
\end{equation*}
\begin{itemize}
\changed{
\item A byte $\PrivateAddressLeadByte$ indicating this version of the
\item A byte $\SpendingKeyLeadByte$ indicating this version of the
raw encoding of a \Zcash private key.
}
\item 32 bytes specifying $\SpendAuthorityPrivate$.
\item 32 bytes specifying $\AuthPrivate$.
\item 32 bytes specifying $\TransmitPrivate$.
\end{itemize}
@ -833,16 +1001,19 @@ Transmitted coins are stored on the blockchain in encrypted form, together with
a \coinCommitment $\cm$.
The \coinPlaintexts associated with a \PourDescription are encrypted to the
respective \transmitPublicAlgorithm keys $\TransmitPublicNew{\mathrm{1}..\NNew}$,
respective \transmitKeypair keys $\PublicKey{\mathrm{1}..\NNew}$,
and the result forms a \coinsCiphertext.
Each \coinPlaintext consists of $(\Value, \CoinAddressRand, \CoinCommitRand\changed{, \Memo})$,
where:
Each \coinPlaintext consists of $(\changed{\AuthPublic, }\Value, \CoinAddressRand,
\CoinCommitRand\changed{, \Memo})$, where:
\begin{itemize}
\changed{
\item $\AuthPublic$ is a 32-byte \authKeypair public key of the recipient.
}
\item $\Value$ is a 64-bit unsigned integer representing the value of the
\coin in \zatoshi (1 \ZEC = $10^8$ \zatoshi).
\item $\CoinAddressRand$ is a 32-byte $\PRFsn{\SpendAuthorityPrivate}$ preimage.
\item $\CoinAddressRand$ is a 32-byte $\PRFsn{\AuthPrivate}$ preimage.
\item $\CoinCommitRand$ is a 48-byte \COMMtrapdoor.
\changed{
\item $\Memo$ is a 64-byte \memo associated with this \coin.
@ -868,9 +1039,11 @@ does not use it.
The raw encoding of a \coinPlaintext consists of, in order:
\begin{equation*}
\begin{bytefield}[bitwidth=0.035em]{1224}
\bitbox{80}{\changed{$\TransmitPlaintextVersionByte$}} &
\bitbox{144}{$\Value$ (8 bytes)} &
\begin{bytefield}[bitwidth=0.03em]{1480}
\changed{
\bitbox{88}{$\TransmitPlaintextVersionByte$}&
\bitbox{256}{$\AuthPublic$ (32 bytes)}
&}\bitbox{168}{$\Value$ (8 bytes)} &
\bitbox{256}{$\CoinAddressRand$ (32 bytes)} &
\bitbox{384}{$\CoinCommitRand$ (48 bytes)} &
\changed{\bitbox{512}{$\Memo$ (64 bytes)}}
@ -881,6 +1054,7 @@ The raw encoding of a \coinPlaintext consists of, in order:
\changed{
\item A byte $\TransmitPlaintextVersionByte$ indicating this version of the raw
encoding of a \coinPlaintext.
\item 32 bytes specifying the \authKeypair public key of the recipient.
}
\item 8 bytes specifying a big-endian encoding of $\Value$.
\item 32 bytes specifying $\CoinAddressRand$.
@ -908,9 +1082,9 @@ TBD.
\item Instead of ECIES, we use an encryption scheme based on $\CryptoBox$,
defined in section ``In-band secret distribution".
\item Faerie Gold fix (TBD).
\item The paper defines a coin as a tuple $(\SpendAuthorityPublic, \Value,
\item The paper defines a coin as a tuple $(\AuthPublic, \Value,
\CoinAddressRand, \CoinCommitRand, \CoinCommitS, \cm)$, whereas this specification
defines it as $(\SpendAuthorityPublic, \Value, \CoinAddressRand, \CoinCommitRand)$.
defines it as $(\AuthPublic, \Value, \CoinAddressRand, \CoinCommitRand)$.
This is just a clarification, because the instantiation of $\COMM{\CoinCommitS}$
in section 5.1 of the paper does not use $\CoinCommitS$, and $\cm$ can be computed
from the other fields.

Loading…
Cancel
Save