Compare commits

...

6 Commits

Author SHA1 Message Date
Daira Hopwood d616dea37e Reorder definitions to avoid a forward reference. 8 years ago
Daira Hopwood 64be93dce2 Fix formatting and warnings. 8 years ago
Daira Hopwood f3dbba5f86 Switch from blake2b to SHA-256 for nonce computations. 8 years ago
Daira Hopwood 830a31666b Memo field fixes. 8 years ago
Daira Hopwood c34d4261bd More references. 8 years ago
Daira Hopwood d4b60f871d Proposed crypto_box encryption. 8 years ago
  1. BIN
      protocol/protocol.pdf
  2. 165
      protocol/protocol.tex
  3. 43
      protocol/zcash.bib

BIN
protocol/protocol.pdf

Binary file not shown.

165
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
@ -54,8 +56,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 +66,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 +80,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
@ -89,8 +97,20 @@
\newcommand{\CoinAddressRandNew}[1]{\mathsf{\uprho^{new}_\mathnormal{#1}}}
\newcommand{\CoinCommitS}{\mathsf{s}}
\newcommand{\TransmitPlaintextVersionByte}{\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{\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{\CryptoBoxSealHash}{\mathtt{SHA256}}
\newcommand{\CryptoBoxSealHashbox}[1]{\CryptoBoxSealHash\left(\;\raisebox{-1.3ex}{\usebox{#1}}\;\right)}
\newcommand{\PRF}[2]{\mathsf{{PRF}^{#2}_\mathnormal{#1}}}
\newcommand{\PRFaddr}[1]{\PRF{#1}{addr}}
\newcommand{\PRFsn}[1]{\PRF{#1}{sn}}
@ -104,6 +124,7 @@
\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 +143,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
@ -198,6 +220,7 @@ the trailing (final) $k$ bits of its input.
$\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}$.
@ -296,17 +319,72 @@ $\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.
\subparagraph{In-band secret distribution}
\subsubsection{In-band secret distribution}
In order to transmit the secret $\Value$, $\CoinAddressRand$, and $\CoinCommitRand$
(necessary for the recipient to later spend) 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 and \memo.
The encryption algorithm is defined in terms of $\CryptoBox$ (i.e.
$\CryptoBoxSpecific$) \cite{cryptobox} as follows.
\newsavebox{\noncebox}
\begin{lrbox}{\noncebox}
\begin{bytefield}[bitwidth=0.05em]{520}
\bitbox{120}{1 byte $i-1$} &
\bitbox{256}{32 byte $\EphemeralPublic$}
\bitbox{256}{32 byte $\TransmitPublicNew{i}$}
\end{bytefield}
\end{lrbox}
Let $\TransmitPublicNew{1..\NNew}$ be the Curve25519 public keys for the intended
recipient addresses of each new \coin, and let $\Plaintext{1..\NNew}$ be their
\coinPlaintexts.
Define:
\begin{itemize}
\item[] $\Nonce(i, \EphemeralPublic, \TransmitPublicNew{i}) =
\CryptoBoxSealHashbox{\noncebox}$.
\end{itemize}
Then to encrypt:
\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{1..\NNew}}(\Plaintext{1..\NNew}) =
(\EphemeralPublic, \Ciphertext{1..\NNew})$.
\end{itemize}
Let $(\TransmitPublic, \TransmitPrivate)$ be the recipient's Curve25519
(public, private) key pair, and let $(\EphemeralPublic, \Ciphertext{1..\NNew})$
be the \coinsCiphertext.
Then for each $i$ in $\{1..\NNew\}$, the recipient will attempt to decrypt that
ciphertext component as follows:
\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.
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.
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, $\CryptoBoxSealHash$ (the full hash, not the compression
function) is used instead of $\mathsf{blake2b}$.
\subparagraph{Coin Commitments}
\subsubsection{Coin Commitments}
The underlying $\Value$ and $\SpendAuthorityPublic$ are blinded with $\CoinAddressRand$
and $\CoinCommitRand$ using the collision-resistant hash function $\CRH$ in a
@ -345,7 +423,7 @@ multi-layered process. The resulting hash $\cm = \CoinCommitment{\Coin}$.
\end{aligned}
\end{equation*}
\subparagraph{Serials}
\subsubsection{Serial numbers}
A \serialNumber (denoted $\sn$) equals
$\PRFsn{\SpendAuthorityPrivate}(\CoinAddressRand)$. A \coin is spent by proving
@ -470,8 +548,10 @@ $\scriptSig$.
\item $\commitments$ which is a $\NNew$ size sequence of \coinCommitments
$\cmNew{1..\NNew}$.
\item $\TransmitCiphertexts$ which is a $\NNew$ size sequence each element of which
is a \transmittedCiphertext.
\item $\ephemeralKey$ which is a Curve25519 public key $\EphemeralPublic$.
\item $\ciphertexts$ which is a $\NNew$ size sequence of ciphertext components.
($\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
@ -587,9 +667,8 @@ These are encoded in the same way as in \Bitcoin \cite{Base58Check}.
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 Curve25519 public key, for use with the encryption
scheme defined in section ``In-band secret distribution".
\subsubsection{Raw Encoding}
@ -607,14 +686,8 @@ The raw encoding of a confidential address consists of:
\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 32 bytes specifying $\TransmitPublic$, 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,
@ -622,14 +695,12 @@ and produces `z' as the Base58Check leading character.}
\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 Curve25519 private key, for use with the
encryption scheme defined in section ``In-band secret distribution".
\subsubsection{Raw Encoding}
@ -647,7 +718,7 @@ The raw encoding of a confidential address secret consists of, in order:
\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,
@ -660,10 +731,11 @@ and produces `z' as the Base58Check leading character.}
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{1..\NNew}$, and the
result forms a \coinsCiphertext.
A \transmittedPlaintext consists of $(\Value, \CoinAddressRand, \CoinCommitRand)$,
Each \coinPlaintext consists of $(\Value, \CoinAddressRand, \CoinCommitRand, \Memo)$,
where:
\begin{itemize}
@ -671,31 +743,42 @@ where:
\coin in \zatoshi (1 \ZEC = $10^8$ \zatoshi).
\item $\CoinAddressRand$ is a 32-byte $\PRFsn{\SpendAuthorityPrivate}$ preimage.
\item $\CoinCommitRand$ is a 48-byte \COMMtrapdoor.
\item $\Memo$ is a 64-byte \memo associated with this \coin.
\end{itemize}
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}
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}{$\TransmitPlaintextVersionByte$} &
\bitbox{144}{$\Value$ (8 bytes)} &
\bitbox{256}{$\CoinAddressRand$ (32 bytes)} &
\bitbox{384}{$\CoinCommitRand$ (48 bytes)} &
\bitbox{512}{$\Memo$ (64 bytes)}
\end{bytefield}
\end{equation*}
\begin{itemize}
\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$.
\item 64 bytes specifying $\Memo$.
\end{itemize}
\section{Pours (within a transaction on the blockchain)}
@ -710,6 +793,8 @@ TBD.
\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

43
protocol/zcash.bib

@ -8,8 +8,49 @@
}
@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}}
}

Loading…
Cancel
Save