Fixes to encryption section.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Hopwood 2016-02-25 21:42:00 +00:00
parent dc4e99389e
commit 19eb032dac
1 changed files with 119 additions and 121 deletions

View File

@ -103,9 +103,10 @@
\newcommand{\ViewingKeyLeadByte}{\mathbf{0x??}}
\newcommand{\SpendingKeyLeadByte}{\mathbf{0x??}}
\newcommand{\AuthPublic}{\mathsf{a_{pk}}}
\newcommand{\AuthPrivate}{\mathsf{a_{sk}}}
\newcommand{\DiscloseKey}{\mathsf{a_{vk}}}
\newcommand{\AuthPrivate}{\mathsf{a_{sk}}}
\newcommand{\AuthPublicOld}[1]{\mathsf{a^{old}_{pk,\mathnormal{#1}}}}
\newcommand{\DiscloseKeyOld}[1]{\mathsf{a^{old}_{vk,\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}}}}
@ -120,6 +121,7 @@
\newcommand{\TransmitPublicNew}[1]{\mathsf{pk^{new}_{\enc,\mathnormal{#1}}}}
\newcommand{\TransmitPrivate}{\mathsf{sk_{enc}}}
\newcommand{\Value}{\mathsf{v}}
\newcommand{\ValueNew}[1]{\mathsf{v^{new}_\mathnormal{#1}}}
% Coins
\newcommand{\Coin}[1]{\mathbf{c}_{#1}}
@ -136,17 +138,16 @@
\newcommand{\hSigInputVersionByte}{\mathbf{0x00}}
\newcommand{\Memo}{\mathsf{memo}}
\newcommand{\CurveMultiply}{\mathsf{Curve25519}}
\newcommand{\CryptoBox}{\mathsf{crypto\_box}}
\newcommand{\CryptoBoxOpen}{\mathsf{crypto\_box\_open}}
\newcommand{\CryptoBoxSeal}{\mathsf{crypto\_box\_seal}}
\newcommand{\CryptoBoxSpecific}{\mathsf{crypto\_box\_curve25519xsalsa20poly1305}}
\newcommand{\DecryptCoin}{\mathtt{DecryptCoin}}
\newcommand{\Plaintext}{\mathbf{P}}
\newcommand{\Ciphertext}{\mathbf{C}}
\newcommand{\Key}{\mathsf{K}}
\newcommand{\Nonce}{\mathsf{nonce}}
\newcommand{\Empty}{\varnothing}
\newcommand{\TransmitPlaintext}[1]{\Plaintext^\enc_{#1}}
\newcommand{\TransmitCiphertext}[1]{\Ciphertext^\enc_{#1}}
\newcommand{\TransmitKey}[1]{\Key^\enc_{#1}}
\newcommand{\TransmitKeyCompare}[1]{\Key^*_{#1}}
\newcommand{\DiscloseCiphertext}[1]{\Ciphertext^\disclose_{#1}}
\newcommand{\SharedPlaintext}[1]{\Plaintext^\shared_{#1}}
\newcommand{\SharedCiphertext}{\Ciphertext^\shared}
@ -178,6 +179,7 @@
\newcommand{\InternalHash}{\mathsf{InternalH}}
\newcommand{\Leading}[1]{\mathtt{Leading}_{#1}}
\newcommand{\ReplacementCharacter}{\textsf{U+FFFD}}
\newcommand{\CryptoBoxSeal}{\mathsf{crypto\_box\_seal}}
% merkle tree
\newcommand{\MerkleDepth}{\mathsf{d}}
@ -216,6 +218,7 @@
\newcommand{\vpubNew}{\mathsf{v_{pub}^{new}}}
\newcommand{\cOld}[1]{\mathbf{c}_{#1}^\mathsf{old}}
\newcommand{\cNew}[1]{\mathbf{c}_{#1}^\mathsf{new}}
\newcommand{\cpNew}[1]{\mathbf{cp}_{#1}^\mathsf{new}}
\newcommand{\vOld}[1]{\mathsf{v}_{#1}^\mathsf{old}}
\newcommand{\vNew}[1]{\mathsf{v}_{#1}^\mathsf{new}}
\newcommand{\NP}{\mathsf{NP}}
@ -294,6 +297,8 @@ with indices $1$ through $\mathrm{N}$ inclusive. For example,
$\AuthPublicNew{\mathrm{1}..\NNew}$ means the sequence $[\AuthPublicNew{\mathrm{1}},
\AuthPublicNew{\mathrm{2}}, ...\;\AuthPublicNew{\NNew}]$.
$\Empty$ denotes an empty byte sequence.
\subsection{Cryptographic Functions}
$\CRH$ is a collision-resistant hash function. In \Zcash, the $\SHAName$ function
@ -315,42 +320,15 @@ ensuring that the functions are independent.
\newcommand{\iminusone}{\hspace{0.3pt}\scriptsize{$i$\hspace{0.6pt}-1}}
\newsavebox{\addrboxa}
\begin{lrbox}{\addrboxa}
\newsavebox{\addrbox}
\begin{lrbox}{\addrbox}
\setchanged
\begin{bytefield}[bitwidth=0.065em]{512}
\bitbox{242}{256 bit $\AuthPrivate$} &
\bitbox{242}{256 bit $x$} &
\bitbox{18}{0} &
\bitbox{18}{0} &
\bitbox{186}{$0^{252}$} &
\bitbox{18}{0} &
\bitbox{18}{0} &
\end{bytefield}
\end{lrbox}
\newsavebox{\addrboxb}
\begin{lrbox}{\addrboxb}
\setchanged
\begin{bytefield}[bitwidth=0.065em]{512}
\bitbox{242}{256 bit $\DiscloseKey$} &
\bitbox{18}{0} &
\bitbox{18}{0} &
\bitbox{186}{$0^{252}$} &
\bitbox{18}{0} &
\bitbox{18}{1} &
\end{bytefield}
\end{lrbox}
\newsavebox{\addrboxc}
\begin{lrbox}{\addrboxc}
\setchanged
\begin{bytefield}[bitwidth=0.065em]{512}
\bitbox{242}{256 bit $\AuthPrivate$} &
\bitbox{18}{0} &
\bitbox{18}{0} &
\bitbox{186}{$0^{252}$} &
\bitbox{18}{1} &
\bitbox{18}{0} &
\bitbox{174}{$0^{252}$} &
\bitbox{48}{2 bit $t$} &
\end{bytefield}
\end{lrbox}
@ -392,17 +370,11 @@ need to be aware of how it is associated with this bit-packing.}
\begin{equation*}
\begin{aligned}
\setchanged \DiscloseKey &\setchanged := \PRFaddr{\AuthPrivate}(0)
&\setchanged = \CRHbox{\addrboxa} \\
\setchanged \AuthPublic &\setchanged := \PRFaddr{\DiscloseKey}(1)
&\setchanged = \CRHbox{\addrboxb} \\
\setchanged \TransmitPrivate' &\setchanged := \PRFaddr{\AuthPrivate}(2)
&\setchanged = \CRHbox{\addrboxc} \\
\setchanged \TransmitPrivate &\setchanged := \Clamp(\TransmitPrivate') & \\
\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 \PRFaddr{x}(t) &\setchanged := \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}
\end{aligned}
\end{equation*}
@ -446,25 +418,25 @@ to:
\item obtain a \paymentAddress\changed{ or \viewingKey} from a \spendingKey.
\end{itemize}
Each key component, i.e. each of $\AuthPublic$, $\TransmitPublic$,
\changed{$\DiscloseKey$, }$\TransmitPrivate$, and $\AuthPrivate$, is a sequence of
32 bytes. \changed{$\AuthPublic$, $\DiscloseKey$, and $\TransmitPrivate$ are derived
as follows:}
Each key component, i.e. each of $\AuthPrivate$, \changed{$\DiscloseKey$,
}$\AuthPublic$, $\TransmitPrivate$, and $\TransmitPublic$, is a sequence of
32 bytes.
\changed{
$\DiscloseKey$, $\AuthPublic$, $\TransmitPrivate$, and $\TransmitPublic$ are
derived as follows:
\begin{equation*}
\begin{aligned}
\setchanged \DiscloseKey &\setchanged := \PRFaddr{\AuthPrivate}(0) & \hspace{30em} \\
\setchanged \AuthPublic &\setchanged := \PRFaddr{\DiscloseKey}(1) & \\
\setchanged \TransmitPrivate &\setchanged := \Clamp(\PRFaddr{\AuthPrivate}(2)) &
\DiscloseKey &:= \PRFaddr{\AuthPrivate}(0) & \hspace{30em} \\
\AuthPublic &:= \PRFaddr{\DiscloseKey}(1) & \\
\TransmitPrivate &:= \Clamp(\PRFaddr{\AuthPrivate}(2)) & \\
\TransmitPublic &:= \CurveMultiply(\TransmitPrivate)
\end{aligned}
\end{equation*}
\changed{
$\Clamp$ performs the clamping of Curve25519 private key bits, and
where $\Clamp$ performs the clamping of Curve25519 private key bits, and
$\CurveMultiply$ performs point multiplication, both as defined in \cite{Curve25519}.
Let $\TransmitPublic := \CurveMultiply(\TransmitPrivate)$, i.e. the public key
corresponding to the private key $\TransmitPrivate$.
}
Users can accept payment from multiple parties with a single
@ -843,17 +815,12 @@ recipient \emph{without} requiring an out-of-band communication channel, the
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{To also transmit these values to a \viewingKey holder for outgoing
\PourTransfers, the \discloseKey $\DiscloseKey$ is used to symmetrically
encrypt them, and also to encrypt the ephemeral secret and address public
keys (to allow the \viewingKey holder to check whether the other encryptions
are valid).} All of these encryptions are combined to form a \coinsCiphertext.
\changed{
Let $\SymEncrypt{\Key}(\Plaintext)$ be the $\SymSpecific$ encryption
\cite{rfc7539} of plaintext $\Plaintext$ with empty ``additional data",
empty nonce, and key $\Key$.
}
\changed{Several more encryptions are used to also reveal these values to a
holder of a \viewingKey for any of the input \coins, and also to permit them
to check whether the other encryptions are valid.}
All of the resulting ciphertexts are combined to form a \coinsCiphertext.
\newsavebox{\kdfbox}
\begin{lrbox}{\kdfbox}
@ -866,6 +833,14 @@ empty nonce, and key $\Key$.
\end{bytefield}
\end{lrbox}
\newsavebox{\tagbox}
\begin{lrbox}{\tagbox}
\setchanged
\begin{bytefield}[bitwidth=0.032em]{8}
\bitbox{160}{8 bit $i-1$}
\end{bytefield}
\end{lrbox}
\newsavebox{\sharedbox}
\begin{lrbox}{\sharedbox}
\setchanged
@ -877,42 +852,55 @@ empty nonce, and key $\Key$.
\end{bytefield}
\end{lrbox}
Let $\TransmitPublicNew{\mathrm{1}..\NNew}$ be the \changed{Curve25519} public keys
for the intended recipient addresses of each new \coin,
\changed{let $\DiscloseKey$ be the sender's \discloseKey,}
and let $\CoinPlaintext{1..\NNew}$ be the \coinPlaintexts.
Let $\TransmitPlaintext{i}$ be the raw encoding of $\CoinPlaintext{i}$.
\subsection{Encryption}
\changed{
Let $\SymEncrypt{\Key}(\Plaintext, \Nonce)$ be the $\SymSpecific$ \cite{rfc7539}
encryption of plaintext $\Plaintext$ with empty ``additional data", nonce $\Nonce$,
and key $\Key$.
Similarly, let $\SymDecrypt{\Key}(\Ciphertext, \Nonce)$ be the $\SymSpecific$
decryption of ciphertext $\Ciphertext$ with empty ``additional data",
nonce $\Nonce$, and key $\Key$. The result is either the plaintext byte sequence,
or $\bot$ indicating failure to decrypt.
Define:
\begin{equation*}
\begin{aligned}
\KDF(\DHSecret{i}, \EphemeralPublic, \TransmitPublicNew{i}, i) &:= \FullHashbox{\kdfbox} \\
\SharedPlaintext{} &:= \Justthebox{\sharedbox}
\end{aligned}
\end{equation*}
$\KDF(\DHSecret{i}, \EphemeralPublic, \TransmitPublicNew{i}, i) := \FullHashbox{\kdfbox}$.
$\Tag{i} := \Justthebox{\tagbox}$.
}
Let $\TransmitPublicNew{\mathrm{1}..\NNew}$ be the \changed{Curve25519} public keys
for the intended recipient addresses of each new \coin,
\changed{let $\DiscloseKeyOld{\mathrm{1}..\NOld}$ be the \discloseKey for each of
the addresses from which the old \coins are sent,} and let $\CoinPlaintext{1..\NNew}$
be the \coinPlaintexts.
Let $\TransmitPlaintext{i}$ be the raw encoding of $\CoinPlaintext{i}$.
Then to encrypt:
\begin{itemize}
\changed{
\item Generate a new Curve25519 (public, private) key pair:
$(\EphemeralPublic, \EphemeralPrivate)$.
\item Let $\SharedPlaintext{} := \Justthebox{\sharedbox}$.
\item \todo{$\SharedPlaintext{}$ needs to include $\TransmitKey{1..\NNew}$.}
\item Generate a new Curve25519 (public, private) key pair
$(\EphemeralPublic, \EphemeralPrivate)$, and a new $\SymSpecific$ key $\SharedKey{}$.
\item For $i$ in $\{1..\NNew\}$,
\begin{itemize}
\item Let $\DHSecret{i} := \CurveMultiply(\TransmitPublicNew{i},
\EphemeralPrivate)$.
\item Let $\TransmitKey{i} := \KDF(\DHSecret{i}, \EphemeralPublic,
\TransmitPublicNew{i}, i)$.
\item Let $\TransmitCiphertext{i} := \SymEncrypt{\TransmitKey{i}}(\TransmitPlaintext{i})$.
\item Let $\TransmitCiphertext{i} :=
\SymEncrypt{\TransmitKey{i}}(\TransmitPlaintext{i}, \Empty)$.
\end{itemize}
\item Let $\SharedKey{} := ...$.
\item Let $\SharedCiphertext := \SymEncrypt{\SharedKey{}}(\SharedPlaintext{})$.
\item For $i$ in $\{1..\NOld\}$,
\begin{itemize}
\item Let $\DiscloseCiphertext{i} := \SymEncrypt{\DiscloseKey{i}}(\SharedKey{})$.
\item Let $\DiscloseCiphertext{i} :=
\SymEncrypt{\DiscloseKeyOld{i}}(\SharedKey{}, \Tag{i})$.
\end{itemize}
\item Let $\SharedCiphertext := \SymEncrypt{\SharedKey{}}(\SharedPlaintext{}, \Empty)$.
}
\end{itemize}
@ -920,6 +908,8 @@ The resulting \coinsCiphertext is $\changed{(\EphemeralPublic,
\TransmitCiphertext{\mathrm{1}..\NNew}, \DiscloseCiphertext{\mathrm{1}..\NOld},
\SharedCiphertext)}$.
\subsection{Decryption by a Recipient}
Let $(\TransmitPublic, \TransmitPrivate)$ be the recipient's \changed{Curve25519}
(public, private) key pair, and let $\cmNew{\mathrm{1}..\NNew}$ be the coin
commitments of each output coin. Then for each $i$ in $\{1..\NNew\}$, the recipient
@ -928,22 +918,21 @@ will attempt to decrypt that ciphertext component as follows:
\changed{
\begin{itemize}
\item Let $\DHSecret{i} := \CurveMultiply(\EphemeralPublic, \TransmitPrivate)$.
\item Return $\DecryptCoin(\DHSecret{i}, \EphemeralPublic, \TransmitPublicNew{i}, i,
\TransmitCiphertext{i}, \cmNew{i}).$
\end{itemize}
$\DecryptCoin(\DHSecret{i}, \EphemeralPublic, \TransmitPublicNew{i}, i,
\TransmitCiphertext{i}, \cmNew{i})$ is defined as follows:
\begin{itemize}
\item Let $\TransmitKey{i} := \KDF(\DHSecret{i}, \EphemeralPublic,
\TransmitPublicNew{i}, i)$.
\item Let $\TransmitPlaintext{i} := \SymDecrypt{\TransmitKey{i}}(\TransmitCiphertext{i})$.
\item Return $\DecryptCoin(\TransmitKey{i}, \TransmitCiphertext{i}, \cmNew{i}).$
\end{itemize}
$\DecryptCoin(\TransmitKey{i}, \TransmitCiphertext{i}, \cmNew{i})$ is defined as follows:
\begin{itemize}
\item Let $\TransmitPlaintext{i} :=
\SymDecrypt{\TransmitKey{i}}(\TransmitCiphertext{i}, \Empty)$.
\item If $\TransmitPlaintext{i} = \bot$, return $\bot$.
\item Extract $\CoinPlaintext{i} := (\AuthPublic, \Value, \CoinAddressRand,
\CoinCommitRand, \Memo)$ from $\TransmitPlaintext{i}$.
\item If $\CoinCommitment(\Coin{i}) \neq \cmNew{i}$, return $\bot$, else
return $\CoinPlaintext{i}$.
\item Extract $\CoinPlaintext{i} = (\AuthPublicNew{i}, \ValueNew{i},
\CoinAddressRandNew{i}, \CoinCommitRandNew{i}, \Memo_i)$ from $\TransmitPlaintext{i}$.
\item If $\CoinCommitment((\AuthPublicNew{i}, \ValueNew{i}, \CoinAddressRandNew{i},
\CoinCommitRandNew{i})) \neq \cmNew{i}$, return $\bot$, else return $\CoinPlaintext{i}$.
\end{itemize}
}
@ -961,35 +950,45 @@ the transaction in which a coin was output to no longer be on the consensus
blockchain.
\changed{
\subsection{Decryption by a Viewing Key Holder}
Let $\DiscloseKey{}$ be a \viewingKey holder's \discloseKey.
Then for each \PourDescription in its \blockchainview, the \viewingKey holder
will attempt to decrypt the corresponding \coinsCiphertext as follows:
}
\changed{
\begin{enumerate}
\item Set $\SharedPlaintext{} := \bot$.
\item For $i$ in $\{1..\NNew\}$,
\begin{itemize}
\item Let $\SharedKey{i} := \SymDecrypt{\DiscloseKey{}}(\DiscloseCiphertext{i}, \Tag{i})$.
\item Let $\SharedKey{i} :=
\SymDecrypt{\DiscloseKey{}}(\DiscloseCiphertext{i}, \Tag{i})$.
\item If $\SharedKey{i} = \bot$ then continue with the next $i$.
\item Let $\SharedPlaintext{i} := \SymDecrypt{\SharedKey{i}}(\SharedCiphertext)$.
\item Let $\SharedPlaintext{i} :=
\SymDecrypt{\SharedKey{i}}(\SharedCiphertext, \Empty)$.
\item If $\SharedPlaintext{i} = \bot$ then continue with the next $i$.
\item Set $\SharedPlaintext{} := \SharedPlaintext{i}$ and exit the loop.
\end{itemize}
\item If $\SharedPlaintext{} = \bot$ (i.e. it was not set in the loop), then this
transaction does not contain any information decryptable by the \viewingKey; return $\bot$.
\item Extract $\TransmitPublicNew{\mathrm{1}..\NNew}$ and $\EphemeralPrivate$
from $\SharedPlaintext{}$.
transaction does not contain any information decryptable by the \viewingKey; set
$\CoinPlaintext{i} = \bot$ for $i$ in $\{1..\NNew\}$ and return
$\CoinPlaintext{\mathrm{1}..\NNew}$.
\item Extract $\TransmitKey{1..\NNew}$, $\TransmitPublicNew{\mathrm{1}..\NNew}$,
and $\EphemeralPrivate$ from $\SharedPlaintext{}$.
\item For $i$ in $\{1..\NNew\}$,
\begin{itemize}
\item Let $\CoinPlaintext{i} :=
\DecryptCoin(\TransmitKey{i}, \TransmitCiphertext{i}, \cmNew{i})$.
\item Let $\DHSecret{i} := \CurveMultiply(\TransmitPublicNew{i}, \EphemeralPrivate)$.
\item Let $\CoinPlaintext{i} := \DecryptCoin(\DHSecret{i}, \EphemeralPublic,
\TransmitPublicNew{i}, i, \TransmitCiphertext{i}, \cmNew{i}).$
\item Let $\TransmitKeyCompare{i} := \KDF(\DHSecret{i}, \EphemeralPublic,
\TransmitPublicNew{i}, i)$.
\item If $\CoinPlaintext{i} \neq \bot$ and
$\TransmitKeyCompare{i} \neq \TransmitKey{i}$ then set the \memo
of $\CoinPlaintext{i}$ to be $\bot$ (indicating that, although this is a valid
coin, the recipient would not have been able to decrypt it, and that the \memo
cannot be verified).
\end{itemize}
\item Return $\CoinPlaintext{\mathrm{1}..\NNew}$.
\end{enumerate}
}
If a party holds more than one \viewingKey, it may optimize the above
procedure by performing the loop in step 2 for the $\DiscloseKey{}$ of each
@ -998,22 +997,21 @@ decrypts correctly is the one that should be used in step 4 onward.
(However, additional information is provided by which \viewingKey was able
to decrypt each $\DiscloseCiphertext{i}$.)
\changed{
The public key encryption used in this part of the protocol is based loosely on
the $\CryptoBoxSeal$ algorithm defined in libsodium \cite{cryptoboxseal}, but
with the following differences:
other encryption schemes based on Diffie-Hellman over an elliptic curve, such
as ECIES or the $\CryptoBoxSeal$ algorithm defined in libsodium \cite{cryptoboxseal}.
Note that:
\begin{itemize}
\item The same ephemeral key is used for all encryptions to the recipient keys
in a given \PourDescription.
\item The nonce for each ciphertext component depends on the index $i$.
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.
\item $\FullHash$ (the full hash, not the compression function) is used instead
of $\mathsf{blake2b}$.
\item In addition to the Diffie-Hellman secret, the KDF takes as input the
public keys of both parties, and the index $i$.
\item The nonce parameter to $\SymSpecific$ is not used for the public key
encryption.
\item The ephemeral secret $\EphemeralPrivate$ is included together with
the \transmitKeypair public keys of the recipients, encrypted to the
\discloseKey. This allows a \viewingKey holder to check whether the
the \transmitKeypair public keys of the recipients, symmetrically
encrypted to the \discloseKey.
This allows a \viewingKey holder to check whether the
indicated recipients would be able to decrypt a given component, and
if so to decrypt the memo field. (We do not rely on this to ensure
that a \viewingKey holder can decrypt the other components of the