diff --git a/protocol/incremental_merkle.odg b/protocol/incremental_merkle.odg index 39b603703..8040cc4ac 100644 Binary files a/protocol/incremental_merkle.odg and b/protocol/incremental_merkle.odg differ diff --git a/protocol/incremental_merkle.pdf b/protocol/incremental_merkle.pdf index 2d8abccc4..79f2822e4 100644 Binary files a/protocol/incremental_merkle.pdf and b/protocol/incremental_merkle.pdf differ diff --git a/protocol/protocol.pdf b/protocol/protocol.pdf index 100283237..73d8ecaf2 100644 Binary files a/protocol/protocol.pdf and b/protocol/protocol.pdf differ diff --git a/protocol/protocol.tex b/protocol/protocol.tex index f776c2ad2..f0b320cef 100644 --- a/protocol/protocol.tex +++ b/protocol/protocol.tex @@ -1,4 +1,4 @@ -\documentclass[8pt]{article} +\documentclass{article} \RequirePackage{amsmath} \RequirePackage{bytefield} \RequirePackage{graphicx} @@ -6,6 +6,8 @@ \RequirePackage{mathtools} \RequirePackage{xspace} \RequirePackage{url} +\RequirePackage{changepage} +\RequirePackage{lmodern} \setlength{\oddsidemargin}{-0.25in} % Left margin of 1 in + 0 in = 1 in \setlength{\textwidth}{7in} % Right margin of 8.5 in - 1 in - 6.5 in = 1 in @@ -16,6 +18,19 @@ \mathchardef\mhyphen="2D +\RequirePackage[usenames,dvipsnames]{xcolor} +% https://en.wikibooks.org/wiki/LaTeX/Colors#The_68_standard_colors_known_to_dvips +\newcommand{\eli}[1]{{\color{JungleGreen}\sf{Eli: #1}}} +\newcommand{\sean}[1]{{\color{blue}\sf{Sean: #1}}} +\newcommand{\taylor}[1]{{\color{red}\sf{Taylor: #1}}} +\newcommand{\daira}[1]{{\color{RedOrange}\sf{Daira: #1}}} +\newcommand{\nathan}[1]{{\color{ForestGreen}\sf{Nathan: #1}}} +\newcommand{\todo}[1]{{\color{Sepia}\sf{TODO: #1}}} + +\newcommand{\changedcolor}{magenta} +\newcommand{\setchanged}{\color{\changedcolor}} +\newcommand{\changed}[1]{{\setchanged{#1}}} + % terminology \newcommand{\term}[1]{\textsl{#1}\xspace} @@ -34,6 +49,7 @@ \newcommand{\coinCommitmentTree}{\term{coin commitment tree}} \newcommand{\PourDescription}{\term{Pour description}} \newcommand{\PourDescriptions}{\term{Pour descriptions}} +\newcommand{\sequenceOfPourDescriptions}{\changed{sequence of} \PourDescription\changed{\term{s}}} \newcommand{\PourTransfer}{\term{Pour transfer}} \newcommand{\PourTransfers}{\term{Pour transfers}} \newcommand{\fullnode}{\term{full node}} @@ -54,8 +70,9 @@ \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}} -\newcommand{\transmittedPlaintext}{\term{transmitted coin plaintext}} -\newcommand{\transmittedCiphertext}{\term{transmitted coin ciphertext}} +\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}} @@ -63,6 +80,7 @@ \newcommand{\spentSerialsMap}{\term{spent serial numbers map}} \newcommand{\zkSNARK}{\term{zk-SNARK}} \newcommand{\zkSNARKs}{\term{zk-SNARKs}} +\newcommand{\memo}{\term{memo field}} % key pairs: \newcommand{\PublicAddress}{\mathsf{addr_{pk}}} @@ -76,7 +94,11 @@ \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{\EphemeralPublic}{\mathsf{pk_{eph}}} +\newcommand{\EphemeralPrivate}{\mathsf{sk_{eph}}} \newcommand{\Value}{\mathsf{v}} % Coins @@ -87,14 +109,31 @@ \newcommand{\CoinAddressRand}{\mathsf{\uprho}} \newcommand{\CoinAddressRandOld}[1]{\mathsf{\uprho^{old}_\mathnormal{#1}}} \newcommand{\CoinAddressRandNew}[1]{\mathsf{\uprho^{new}_\mathnormal{#1}}} +\newcommand{\CoinAddressPreRand}{\mathsf{\upvarphi}} \newcommand{\CoinCommitS}{\mathsf{s}} \newcommand{\TransmitPlaintextVersionByte}{\mathbf{0x00}} +\newcommand{\hSigInputVersionByte}{\mathbf{0x00}} +\newcommand{\Memo}{\mathsf{memo}} +\newcommand{\CryptoBox}{\mathsf{crypto\_box}} +\newcommand{\CryptoBoxOpen}{\mathsf{crypto\_box\_open}} +\newcommand{\CryptoBoxSeal}{\mathsf{crypto\_box\_seal}} +\newcommand{\CryptoBoxSpecific}{\mathsf{crypto\_box\_curve25519xsalsa20poly1305}} +\newcommand{\Plaintext}[1]{\mathbf{P}_{#1}} +\newcommand{\Ciphertext}[1]{\mathbf{C}_{#1}} +\newcommand{\Nonce}{\mathsf{nonce}} +\newcommand{\Prenonce}{\mathsf{prenonce}} +\newcommand{\TransmitEncrypt}[1]{\mathsf{Encrypt}_{#1}} +\newcommand{\TransmitDecrypt}[1]{\mathsf{Decrypt}_{#1}} \newcommand{\CRH}{\mathsf{CRH}} \newcommand{\CRHbox}[1]{\CRH\left(\;\raisebox{-1.3ex}{\usebox{#1}}\;\right)} +\newcommand{\FullHash}{\mathtt{SHA256}} +\newcommand{\FullHashbox}[1]{\FullHash\left(\;\raisebox{-1.3ex}{\usebox{#1}}\;\right)} +\newcommand{\Justthebox}[1]{\;\raisebox{-1.3ex}{\usebox{#1}}\;} \newcommand{\PRF}[2]{\mathsf{{PRF}^{#2}_\mathnormal{#1}}} \newcommand{\PRFaddr}[1]{\PRF{#1}{addr}} \newcommand{\PRFsn}[1]{\PRF{#1}{sn}} \newcommand{\PRFpk}[1]{\PRF{#1}{pk}} +\newcommand{\PRFrho}[1]{\PRF{#1}{\CoinAddressRand}} \newcommand{\SHA}{\mathtt{SHA256Compress}} \newcommand{\SHAName}{\term{SHA-256 compression}} \newcommand{\SHAOrig}{\term{SHA-256}} @@ -103,7 +142,7 @@ \newcommand{\InternalHashK}{\mathsf{k}} \newcommand{\InternalHash}{\mathsf{InternalH}} \newcommand{\Leading}[1]{\mathtt{Leading}_{#1}} -\newcommand{\Trailing}[1]{\mathtt{Trailing}_{#1}} +\newcommand{\ReplacementCharacter}{\textsf{U+FFFD}} % merkle tree \newcommand{\MerkleDepth}{\mathsf{d}} @@ -122,7 +161,8 @@ \newcommand{\scriptPubKey}{\mathtt{scriptPubKey}} \newcommand{\serials}{\mathtt{serials}} \newcommand{\commitments}{\mathtt{commitments}} -\newcommand{\TransmitCiphertexts}{\mathtt{ciphertexts}} +\newcommand{\ephemeralKey}{\mathtt{ephemeralKey}} +\newcommand{\ciphertexts}{\mathtt{ciphertexts}} \newcommand{\rt}{\mathsf{rt}} % pour @@ -147,21 +187,19 @@ \newcommand{\COMMtrapdoor}{\term{\textsf{COMM} trapdoor}} \newcommand{\CoinCommitment}[1]{\mathtt{CoinCommitment}(#1)} -\RequirePackage[usenames,dvipsnames]{xcolor} -% https://en.wikibooks.org/wiki/LaTeX/Colors#The_68_standard_colors_known_to_dvips -\newcommand{\eli}[1]{{\color{magenta}\sf{Eli: #1}}} -\newcommand{\sean}[1]{{\color{blue}\sf{Sean: #1}}} -\newcommand{\taylor}[1]{{\color{red}\sf{Taylor: #1}}} -\newcommand{\daira}[1]{{\color{RedOrange}\sf{Daira: #1}}} -\newcommand{\nathan}[1]{{\color{ForestGreen}\sf{Nathan: #1}}} - \begin{document} -\title{Zcash Protocol Specification} +\title{Zcash Protocol Specification \\ +\Large Version 2.0-draft-1} \author{Sean Bowe | Daira Hopwood | Taylor Hornby} \date{\today} \maketitle + +\tableofcontents +\newpage + + \section{Introduction} \Zcash is an implementation of the \term{Decentralized Anonymous Payment} @@ -171,6 +209,8 @@ \section{Introduction} protected by zero-knowledge succinct non-interactive arguments of knowledge (\zkSNARKs). +Changes from the original \Zerocash are highlighted in \changed{\changedcolor}. + \section{Concepts} \subsection{Integers, Bit Sequences, and Endianness} @@ -195,17 +235,19 @@ \subsection{Cryptographic Functions} $\CRH$ is a collision-resistant hash function. In \Zcash, the $\SHAName$ function 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$. Three \emph{independent} -$\PRF{x}{}$ are needed in our scheme: $\PRFaddr{x}$, $\PRFsn{x}$, and $\PRFpk{x}$. -It is required that $\PRFsn{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')$. +$\PRF{x}{}$ is a pseudo-random function seeded by $x$. \changed{Four} \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{}$}. -In \Zcash, the $\SHAName$ function is used to construct all three of these -functions. The bits $\mathtt{00}$, $\mathtt{01}$ and $\mathtt{10}$ 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 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. \newsavebox{\addrbox} \begin{lrbox}{\addrbox} @@ -238,6 +280,18 @@ \subsection{Cryptographic Functions} \end{bytefield} \end{lrbox} +\newsavebox{\rhobox} +\begin{lrbox}{\rhobox} +\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)$} +\end{bytefield} +\end{lrbox} + \nathan{Note: If we change input arity (i.e. $\NOld$), we need to be aware of how it is associated with this bit-packing.} @@ -245,7 +299,9 @@ \subsection{Cryptographic Functions} \begin{aligned} \SpendAuthorityPublic &:= \PRFaddr{\SpendAuthorityPrivate}(0) &= \CRHbox{\addrbox} \\ \sn &:= \PRFsn{\SpendAuthorityPrivate}(\CoinAddressRand) &= \CRHbox{\snbox} \\ -\h{i} &:= \PRFpk{\SpendAuthorityPrivate}(i, \hSig) &= \CRHbox{\pkbox} +\h{i} &:= \PRFpk{\SpendAuthorityPrivate}(i, \hSig) &= \CRHbox{\pkbox} \\ +\setchanged \CoinAddressRandNew{i} &\setchanged := \PRFrho{\CoinAddressPreRand}(i, \hSig) +&\setchanged = \CRHbox{\rhobox} \end{aligned} \end{equation*} @@ -284,26 +340,107 @@ \subsection{Confidential Addresses and Private Keys} \subsection{Coins} -A \coin (denoted $\Coin$) is a tuple $(\SpendAuthorityPublic, \Value, -\CoinAddressRand, \CoinCommitRand)$ which represents that a value $\Value$ is +A \coin (denoted $\Coin$) is a tuple $\changed{(\SpendAuthorityPublic, \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)$. $\CoinAddressRand$ and -$\CoinCommitRand$ are tokens randomly generated by the sender. Only a hash of -these values is disclosed publicly, which allows these random tokens to blind the -value and recipient \emph{except} to those who possess these tokens. +$\SpendAuthorityPublic = \PRFaddr{\SpendAuthorityPrivate}(0)$. + +$\CoinCommitRand$ is randomly generated by the sender. \changed{$\CoinAddressRand$ +is generated from a random seed $\CoinAddressPreRand$ using +$\PRFrho{\CoinAddressPreRand}$.} Only a commitment to these values is disclosed +publicly, which allows the tokens $\CoinCommitRand$ and $\CoinAddressRand$ to blind +the value and recipient \emph{except} to those who possess these tokens. + +\subsubsection{In-band secret distribution} + +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 +$\TransmitPrivate$) is used to reconstruct the original \coin \changed{ and \memo}. + +\changed{ +The encryption algorithm is defined in terms of $\CryptoBox$ (i.e. +$\CryptoBoxSpecific$) \cite{cryptobox} as follows. +} + +\newsavebox{\prenoncebox} +\begin{lrbox}{\prenoncebox} +\setchanged +\begin{bytefield}[bitwidth=0.05em]{520} + \bitbox{120}{64 bit $i-1$} & + \bitbox{256}{256 bit $\EphemeralPublic$} + \bitbox{256}{256 bit $\TransmitPublicNew{i}$} +\end{bytefield} +\end{lrbox} -\subparagraph{In-band secret distribution} +\newsavebox{\noncebox} +\begin{lrbox}{\noncebox} +\setchanged +\begin{bytefield}[bitwidth=0.085em]{192} + \bitbox{128}{$\Leading{128}(\Prenonce)$} & + \bitbox{72}{64 bit $i-1$} +\end{bytefield} +\end{lrbox} -In order to transmit the secret $\Value$, $\CoinAddressRand$ and $\CoinCommitRand$ -to the recipient (necessary for the recipient to later spend) \emph{without} -requiring an out-of-band communication channel, the $\transmitPublicAlgorithm$ -public key $\TransmitPublic$ is used to encrypt these secrets to form a -\transmittedCiphertext. The recipient's possession of the associated -$(\PublicAddress, \PrivateAddress)$ (which contains both $\SpendAuthorityPublic$ and -$\TransmitPrivate$) is used to reconstruct the original \coin. +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. -\subparagraph{Coin Commitments} +\changed{ +Define: +\begin{equation*} +\begin{aligned} +\Prenonce(i, \EphemeralPublic, \TransmitPublicNew{i}) &:= \FullHashbox{\prenoncebox} \\ +\Nonce(i, \EphemeralPublic, \TransmitPublicNew{i}) &:= \Justthebox{\noncebox} +\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} +} + +Let $(\TransmitPublic, \TransmitPrivate)$ be the recipient's \changed{Curve25519} +(public, private) key pair, and let $\changed{(\EphemeralPublic,}\; +\Ciphertext{1..\NNew}\changed{)}$ be the \coinsCiphertext. + +Then for each $i$ in $\{1..\NNew\}$, the recipient will attempt to decrypt that +ciphertext component as follows: + +\changed{ +\begin{itemize} + \item $\TransmitDecrypt{\TransmitPrivate}(i, \EphemeralPublic, \Ciphertext{i}) = +\CryptoBoxOpen(\Ciphertext{i}, \EphemeralPublic, \TransmitPrivate, +\Nonce(i, \EphemeralPublic, \TransmitPublic))$ +\end{itemize} +} + +Any ciphertext components that fail to decrypt with a given recipient's private key +will be ignored. + +\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. +} + +\subsubsection{Coin Commitments} The underlying $\Value$ and $\SpendAuthorityPublic$ are blinded with $\CoinAddressRand$ and $\CoinCommitRand$ using the collision-resistant hash function $\CRH$ in a @@ -342,7 +479,7 @@ \subsection{Coins} \end{aligned} \end{equation*} -\subparagraph{Serials} +\subsubsection{Serial numbers} A \serialNumber (denoted $\sn$) equals $\PRFsn{\SpendAuthorityPrivate}(\CoinAddressRand)$. A \coin is spent by proving @@ -402,18 +539,21 @@ \subsection{The Blockchain} An \anchor is a Merkle tree root of a \treestate, and uniquely identifies that \treestate given the assumed security properties of the Merkle tree's hash function. -Each \transaction is associated with a sequence of \PourDescriptions. TODO They also have -a transparent value flow that interacts with the Pour $\vpubOld$ and $\vpubNew$. +Each \transaction is associated with a \sequenceOfPourDescriptions. +\todo{They also have a transparent value flow that interacts with the Pour +\changed{$\vpubOld$ and} $\vpubNew$.} Inputs and outputs are associated with a value. The total value of the outputs must not exceed the total value of the inputs. -The \anchor of the first \PourDescription in a \transaction must refer to some -earlier \block's final \treestate. +The \anchor of the \changed{first} \PourDescription in a \transaction must refer to +some earlier \block's final \treestate. +\changed{ The \anchor of each subsequent \PourDescription may refer either to some earlier \block's final \treestate, or to the output \treestate of the immediately preceding \PourDescription. +} These conditions act as constraints on the blocks that a \fullnode will accept into its \blockchainview. @@ -437,15 +577,16 @@ \section{Pour Transfers and Descriptions} confused with, the \PourCircuit used for the \zkSNARK proof and verification. A \PourTransfer spends $\NOld$ \coins $\cOld{1..\NOld}$ and creates $\NNew$ \coins -$\cNew{1..\NNew}$. \Zcash transactions have an additional field $\vpour$, which is a -sequence of \PourDescriptions. +$\cNew{1..\NNew}$. \Zcash transactions have an additional field $\vpour$, which is +a \sequenceOfPourDescriptions. Each \PourDescription consists of: \begin{list}{}{} - +\changed{ \item $\vpubOldField$ which is a value $\vpubOld$ that the \PourTransfer removes from the value pool. +} \item $\vpubNewField$ which is a value $\vpubNew$ that the \PourTransfer inserts into the value pool. @@ -455,48 +596,81 @@ \section{Pour Transfers and Descriptions} this transaction. \sean{We need to be more specific here.} \item $\scriptSig$ which is a \script that creates conditions for acceptance of a -\PourDescription in a transaction. The $\SHA$ hash of this value is $\hSig$. - -\daira{Why $\SHA$ and not $\SHAOrig$? The script is variable-length.} +\PourDescription in a transaction. \item $\scriptPubKey$ which is a \script used to satisfy the conditions of the $\scriptSig$. -\item $\serials$ which is an $\NOld$ size sequence of serials $\snOld{1..\NOld}$. +\item $\serials$ which is an $\NOld$ size sequence of serials $\snOld{\mathrm{1}..\NOld}$. \item $\commitments$ which is a $\NNew$ size sequence of \coinCommitments -$\cmNew{1..\NNew}$. +$\cmNew{\mathrm{1}..\NNew}$. -\item $\TransmitCiphertexts$ which is a $\NNew$ size sequence each element of which -is a \transmittedCiphertext. +\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 $\vmacs$ which is a $\NOld$ size sequence of message authentication tags -$\h{1..\NOld}$ that bind $\hSig$ to each $\SpendAuthorityPrivate$ of the +$\h{\mathrm{1}..\NOld}$ that bind $\hSig$ to each $\SpendAuthorityPrivate$ of the $\PourDescription$. \item $\zkproof$ which is the zero-knowledge proof $\PourProof$. \end{list} +\subparagraph{Computation of $\hSig$} + +\newsavebox{\hsigbox} +\begin{lrbox}{\hsigbox} +\setchanged +\begin{bytefield}[bitwidth=0.045em]{808} + \bitbox{80}{$\hSigInputVersionByte$} & + \bitbox{256}{256 bit $\snOld{0}$} & + \bitbox{24}{...} & + \bitbox{256}{256 bit $\snOld{\NOld-1}$} & + \bitbox{256}{$\scriptPubKey$} +\end{bytefield} +\end{lrbox} + +\changed{ +Given a \PourDescription, we define: + +\begin{itemize} + \item[] $\hSig := \FullHashbox{\hsigbox}$ +\end{itemize} +} + \subparagraph{Merkle root validity} -A $\PourDescription$ is valid if $\rt$ is a Coin commitment tree root found in -either the blockchain or a merkle root produced by inserting the Coin commitments -of a previous $\PourDescription$ in the transaction to the Coin commitment tree +A \PourDescription is valid if $\rt$ is a \coinCommitmentTree root found in +either the blockchain or a merkle root produced by inserting the \coinCommitments +of a previous $\PourDescription$ in the transaction to the \coinCommitmentTree identified by that previous $\PourDescription$'s $\anchor$. \subparagraph{Non-malleability} -A $\PourDescription$ is valid if the script formed by appending $\scriptPubKey$ to +A \PourDescription is valid if the script formed by appending $\scriptPubKey$ to $\scriptSig$ returns $true$. The $\scriptSig$ is cryptographically bound to $\PourProof$. \subparagraph{Balance} -A \PourTransfer can be seen, from the perspective of the transaction, as an -input and an output simultaneously. $\vpubOld$ takes value from the value pool and -$\vpubNew$ adds value to the value pool. As a result, $\vpubOld$ is treated like an -\emph{output} value, whereas $\vpubNew$ is treated like an \emph{input} value. +A \PourTransfer can be seen, from the perspective of the transaction, as +an input \changed{and an output simultaneously}. +\changed{$\vpubOld$ takes value from the value pool and} +$\vpubNew$ adds value to the value pool. As a result, \changed{$\vpubOld$ is +treated like an \emph{output} value, whereas} $\vpubNew$ is treated like an +\emph{input} value. + +\changed{ +Note that unlike original \Zerocash \cite{ZerocashOakland}, \Zcash does not have +a distinction between Mint and Pour transfers. The addition of $\vpubOld$ to a +\PourDescription subsumes the functionality of Mint. Also, \PourDescriptions +are indistinguishable regardless of the number of real input \coins. +} \subparagraph{Commitments and Serials} @@ -512,10 +686,10 @@ \subsection{Pour Circuit and Proofs} In \Zcash, $\NOld$ and $\NNew$ are both $2$. A valid instance of $\PourProof$ assures that given a \term{primary input} -$(\rt, \snOld{1..\NOld}, \cmNew{1..\NNew}, \vpubOld, \vpubNew, \hSig, \h{1..\NOld})$, -a witness of \term{auxiliary input} -$(\treepath{1..\NOld}, \cOld{1..\NOld}, \SpendAuthorityPrivateOld{1..\NOld}, \cNew{1..\NNew})$ -exists, where: +$(\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}, +\cNew{1..\NNew}\changed{, \CoinAddressPreRand})$ exists, where: \begin{list}{}{} @@ -531,13 +705,13 @@ \subsection{Pour Circuit and Proofs} \subparagraph{Merkle path validity} -for each $i \in \{1..\NOld\}$ $\mid$ $\vOld{i} \neq 0$: $\treepath{i}$ must be a valid path +for each $i \in \{1..\NOld\}$ \changed{$\mid$ $\vOld{i} \neq 0$}: $\treepath{i}$ must be a valid path of depth $\MerkleDepth$ from \linebreak $\CoinCommitment{\cOld{i}}$ to Coin commitment merkle tree root $\rt$. \subparagraph{Balance} -$\vpubOld + \vsum{i=1}{\NOld} \vOld{i} = \vpubNew + \vsum{i=1}{\NNew} \vNew{i}$. +$\changed{\vpubOld +} \vsum{i=1}{\NOld} \vOld{i} = \vpubNew + \vsum{i=1}{\NNew} \vNew{i}$. \subparagraph{Serial integrity} @@ -553,6 +727,12 @@ \subsection{Pour Circuit and Proofs} for each $i \in \{1..\NOld\}$: $\h{i}$ = $\PRFpk{\SpendAuthorityPrivateOld{i}}(i, \hSig)$ +\changed{ +\subparagraph{Uniqueness of $\CoinAddressRandNew{i}$} + +for each $i \in \{1..\NNew\}$: $\CoinAddressRandNew{i}$ = $\PRFrho{\CoinAddressPreRand}(i, \hSig)$ +} + \subparagraph{Commitment integrity} for each $i \in \{1..\NNew\}$: $\cmNew{i}$ = $\CoinCommitment{\cNew{i}}$ @@ -584,34 +764,29 @@ \subsection{Confidential Public Addresses} A \publicAddress consists of $\SpendAuthorityPublic$ and $\TransmitPublic$. $\SpendAuthorityPublic$ is a SHA-256 compression function output. -$\TransmitPublic$ is an encryption public key (currently ECIES, but this may -change to Curve25519/crypto\_box\_seal), which represents an equivalence class -of two points sharing an $x$ coordinate on an elliptic curve. +$\TransmitPublic$ is a \changed{Curve25519} public key, for use with the +encryption scheme defined in section ``In-band secret distribution". \subsubsection{Raw Encoding} The raw encoding of a confidential address consists of: \begin{equation*} -\begin{bytefield}[bitwidth=0.07em]{528} - \bitbox{48}{$\PublicAddressLeadByte$} & +\begin{bytefield}[bitwidth=0.07em]{520} + \bitbox{48}{\changed{$\PublicAddressLeadByte$}} & \bitbox{256}{$\SpendAuthorityPublic$ (32 bytes)} & - \bitbox{264}{A 33-byte encoding of $\TransmitPublic$} + \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 raw encoding of a \Zcash public address. +} \item 32 bytes specifying $\SpendAuthorityPublic$. - \item An encoding of $\TransmitPublic$: The byte $\mathbf{0x01}$, followed by 32 bytes - representing the $x$ coordinate of an elliptic curve point according to - the $\mathsf{FE2OSP}$ primitive specified in section 5.5.4 of IEEE Std 1363-2000. - [Non-normative note: Since the curve is over a prime field, this is just - the 32-byte big-endian representation of the $x$ coordinate. The - overall encoding matches the $\mathsf{EC2OSP{\mhyphen}X}$ primitive - specified in section 5.5.6.3 of IEEE Std 1363a-2004. It does not - matter which of the two points with the same $x$ coordinate is used.] + \item \changed{32 bytes} specifying $\TransmitPublic$, \changed{using the + normal encoding of a Curve25519 public key \cite{Curve25519}}. \end{itemize} \daira{check that this lead byte is distinct from other Bitcoin stuff, @@ -619,14 +794,12 @@ \subsubsection{Raw Encoding} \nathan{what about the network version byte?} -\daira{add bibliographic references for the IEEE standards.} - \subsection{Confidential Address Secrets} A confidential address secret consists of $\SpendAuthorityPrivate$ and $\TransmitPrivate$. $\SpendAuthorityPrivate$ is a SHA-256 compression function -output. $\TransmitPrivate$ is an encryption private key (currently ECIES), which -is an integer. +output. $\TransmitPrivate$ is a \changed{Curve25519} private key, for use with +the encryption scheme defined in section ``In-band secret distribution". \subsubsection{Raw Encoding} @@ -634,17 +807,19 @@ \subsubsection{Raw Encoding} \begin{equation*} \begin{bytefield}[bitwidth=0.07em]{520} - \bitbox{48}{$\PrivateAddressLeadByte$} & + \bitbox{48}{\changed{$\PrivateAddressLeadByte$}} & \bitbox{256}{$\SpendAuthorityPrivate$ (32 bytes)} & \bitbox{256}{$\TransmitPrivate$ (32 bytes)} \end{bytefield} \end{equation*} \begin{itemize} +\changed{ \item A byte $\PrivateAddressLeadByte$ indicating this version of the raw encoding of a \Zcash private key. +} \item 32 bytes specifying $\SpendAuthorityPrivate$. - \item 32 bytes specifying a big-endian encoding of $\TransmitPrivate$. + \item 32 bytes specifying $\TransmitPrivate$. \end{itemize} \daira{check that this lead byte is distinct from other Bitcoin stuff, @@ -657,10 +832,11 @@ \subsection{Coins} Transmitted coins are stored on the blockchain in encrypted form, together with a \coinCommitment $\cm$. -A \transmittedCiphertext is an ECIES encryption of a \transmittedPlaintext to a -\transmitPublicAlgorithm key $\TransmitPublic$. +The \coinPlaintexts associated with a \PourDescription are encrypted to the +respective \transmitPublicAlgorithm keys $\TransmitPublicNew{\mathrm{1}..\NNew}$, +and the result forms a \coinsCiphertext. -A \transmittedPlaintext consists of $(\Value, \CoinAddressRand, \CoinCommitRand)$, +Each \coinPlaintext consists of $(\Value, \CoinAddressRand, \CoinCommitRand\changed{, \Memo})$, where: \begin{itemize} @@ -668,45 +844,69 @@ \subsection{Coins} \coin in \zatoshi (1 \ZEC = $10^8$ \zatoshi). \item $\CoinAddressRand$ is a 32-byte $\PRFsn{\SpendAuthorityPrivate}$ preimage. \item $\CoinCommitRand$ is a 48-byte \COMMtrapdoor. +\changed{ + \item $\Memo$ is a 64-byte \memo associated with this \coin. +} \end{itemize} +\changed{ +The usage of the $\memo$ is by agreement between the sender and recipient of the +\coin. It should be encoded as a UTF-8 human-readable string \cite{Unicode}, padded +with zero bytes. Wallet software is expected to strip any trailing zero bytes and +then display the resulting UTF-8 string to the recipient user, where applicable. +Incorrect UTF-8-encoded byte sequences should be displayed as replacement characters +(\ReplacementCharacter). This does not preclude uses of the \memo by automated +software, but specification of such usage is not in the scope of this document. +} + Note that the value $\CoinCommitS$ described as being part of a \coin in the \Zerocash paper is not encoded because the instantiation of $\COMM{\CoinCommitS}$ does not use it. -\subsection{Raw Encoding} +\subsubsection{Raw Encoding} -The raw encoding of a \transmittedPlaintext consists of, in order: +The raw encoding of a \coinPlaintext consists of, in order: \begin{equation*} -\begin{bytefield}[bitwidth=0.05em]{712} - \bitbox{64}{$\TransmitPlaintextVersionByte$} & - \bitbox{120}{$\Value$ (8 bytes)} & +\begin{bytefield}[bitwidth=0.035em]{1224} + \bitbox{80}{\changed{$\TransmitPlaintextVersionByte$}} & + \bitbox{144}{$\Value$ (8 bytes)} & \bitbox{256}{$\CoinAddressRand$ (32 bytes)} & \bitbox{384}{$\CoinCommitRand$ (48 bytes)} & + \changed{\bitbox{512}{$\Memo$ (64 bytes)}} \end{bytefield} \end{equation*} \begin{itemize} +\changed{ \item A byte $\TransmitPlaintextVersionByte$ indicating this version of the raw -encoding of a \transmittedPlaintext. +encoding of a \coinPlaintext. +} \item 8 bytes specifying a big-endian encoding of $\Value$. \item 32 bytes specifying $\CoinAddressRand$. \item 48 bytes specifying $\CoinCommitRand$. +\changed{ + \item 64 bytes specifying $\Memo$. +} \end{itemize} \section{Pours (within a transaction on the blockchain)} TBD. +\changed{Describe case where there are fewer than $\NOld$ real input coins.} + \section{Transactions} TBD. +\changed{ \section{Differences from the Zerocash paper} \begin{itemize} + \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, \CoinAddressRand, \CoinCommitRand, \CoinCommitS, \cm)$, whereas this specification @@ -715,6 +915,7 @@ \section{Differences from the Zerocash paper} in section 5.1 of the paper does not use $\CoinCommitS$, and $\cm$ can be computed from the other fields. \end{itemize} +} \section{References} diff --git a/protocol/zcash.bib b/protocol/zcash.bib index 71bb98ba4..2d02853ba 100644 --- a/protocol/zcash.bib +++ b/protocol/zcash.bib @@ -8,8 +8,49 @@ @inproceedings{ZerocashOakland } @misc{Base58Check, + key={Base58Check}, title={Base58{C}heck encoding}, howpublished={\url{https://en.bitcoin.it/wiki/Base58Check_encoding}}, - note={Accessed: 2016-01-26} + note={\mbox{Accessed: 2016-01-26}} } +@inproceedings{Curve25519, + author={Daniel Bernstein}, + title={Curve25519: new {D}iffie-{H}ellman speed records}, + booktitle={Public Key Cryptography - PKC 2006. Proceedings of the 9th International Conference on Theory and Practice in Public-Key Cryptography, New York, NY, USA, April 24-26}, + year={2006}, + publisher={Springer-Verlag}, + note={Document ID: 4230efdfa673480fc079449d90f322c0. \mbox{Date: 2006-02-09.} +\url{http://cr.yp.to/papers.html#curve25519}} +} + +@book{Unicode, + author={The Unicode Consortium}, + publisher={The Unicode Consortium}, + year={2015}, + title={The Unicode Standard}, + note={\url{http://www.unicode.org/versions/latest/}} +} + +@misc{cryptobox, + author={Daniel Bernstein}, + title={Cryptography in {N}a{C}l}, + howpublished={\url{https://nacl.cr.yp.to/valid.html}}, + note={\mbox{Accessed: 2016-02-01}} +} + +@misc{cryptoboxseal, + key={libsodium}, + title={libsodium documentation: Sealed boxes}, + howpublished={\url{https://download.libsodium.org/doc/public-key_cryptography/sealed_boxes.html}}, + note={\mbox{Accessed: 2016-02-01}} +} + +@misc{sha256, + author={NIST}, + title={{FIPS} 180-4: Secure {H}ash {S}tandard ({SHS})}, + month={August}, + year={2015}, + note={DOI: 10.6028/NIST.FIPS.180-4}, + howpublished={\url{http://csrc.nist.gov/publications/PubsFIPS.html#180-4}} +}