diff options
Diffstat (limited to 'doc/cs/content/appendix')
-rw-r--r-- | doc/cs/content/appendix/crypto_implementation.tex | 279 | ||||
-rw-r--r-- | doc/cs/content/appendix/rsa-redesign.tex | 209 |
2 files changed, 488 insertions, 0 deletions
diff --git a/doc/cs/content/appendix/crypto_implementation.tex b/doc/cs/content/appendix/crypto_implementation.tex new file mode 100644 index 000000000..9ae9b5865 --- /dev/null +++ b/doc/cs/content/appendix/crypto_implementation.tex @@ -0,0 +1,279 @@ +\begin{lstlisting}[style=bfh-c,language=C,, caption={Crypto Implementation API}, label={lst:cryptoapi}] + #include <sodium.h> + + /** + * IMPLEMENTATION NOTICE: + * + * This is an implementation of the Schnorr, Blind Schnorr and + * Clause Blind Schnorr Signature Scheme using Curve25519. + * We use libsodium wherever possible. + * + * Blind Schnorr: The Blind Schnorr Signature Scheme is BROKEN! + * Use the Clause Blind Schnorr Signature Scheme instead. + * + * Clause Blind Schnorr Signature Scheme: + * This is a variation of the Blind Schnorr Signature Scheme where all operations + * before the signature creation are performed twice. + * The signer randomly chooses one of the two sessions and only creates the signature for this session. + * Note that the Clause part needs to be implemented by whoever uses this API. + * Further details about the Clause Blind Schnorr Signature Scheme can be found here: + * https://eprint.iacr.org/2019/877.pdf + */ + + + /** + * Curve25519 Scalar + */ + struct GNUNET_CRYPTO_Cs25519Scalar + { + /** + * 32 byte scalar + */ + unsigned char d[crypto_core_ed25519_SCALARBYTES]; + }; + + + /** + * Curve25519 point + */ + struct GNUNET_CRYPTO_Cs25519Point + { + /** + * This is a point on the Curve25519. + * The x coordinate can be restored using the y coordinate + */ + unsigned char y[crypto_core_ed25519_BYTES]; + }; + + + /** + * The private information of an Schnorr key pair. + */ + struct GNUNET_CRYPTO_CsPrivateKey + { + struct GNUNET_CRYPTO_Cs25519Scalar scalar; + }; + + + /** + * The public information of an Schnorr key pair. + */ + struct GNUNET_CRYPTO_CsPublicKey + { + struct GNUNET_CRYPTO_Cs25519Point point; + }; + + + /** + * Secret used for blinding (alpha and beta). + */ + struct GNUNET_CRYPTO_CsBlindingSecret + { + struct GNUNET_CRYPTO_Cs25519Scalar alpha; + struct GNUNET_CRYPTO_Cs25519Scalar beta; + }; + + + /** + * the private r used in the signature + */ + struct GNUNET_CRYPTO_CsRSecret + { + struct GNUNET_CRYPTO_Cs25519Scalar scalar; + }; + + + /** + * the public R (derived from r) used in c + */ + struct GNUNET_CRYPTO_CsRPublic + { + struct GNUNET_CRYPTO_Cs25519Point point; + }; + + /** + * Schnorr c to be signed + */ + struct GNUNET_CRYPTO_CsC + { + struct GNUNET_CRYPTO_Cs25519Scalar scalar; + }; + + /** + * s in the signature + */ + struct GNUNET_CRYPTO_CsS + { + struct GNUNET_CRYPTO_Cs25519Scalar scalar; + }; + + /** + * blinded s in the signature + */ + struct GNUNET_CRYPTO_CsBlindS + { + struct GNUNET_CRYPTO_Cs25519Scalar scalar; + }; + + /** + * CS Signtature containing scalar s and point R + */ + struct GNUNET_CRYPTO_CsSignature + { + /** + * Schnorr signatures are composed of a scalar s and a curve point + */ + struct GNUNET_CRYPTO_CsS s_scalar; + struct GNUNET_CRYPTO_Cs25519Point r_point; + }; + + /** + * Nonce + */ + struct GNUNET_CRYPTO_CsNonce + { + /*a nonce*/ + unsigned char nonce[256 / 8]; + }; + + + /** + * Create a new random private key. + * + * @param[out] priv where to write the fresh private key + */ + void + GNUNET_CRYPTO_cs_private_key_generate (struct GNUNET_CRYPTO_CsPrivateKey *priv); + + + /** + * Extract the public key of the given private key. + * + * @param priv the private key + * @param[out] pub where to write the public key + */ + void + GNUNET_CRYPTO_cs_private_key_get_public (const struct GNUNET_CRYPTO_CsPrivateKey *priv, + struct GNUNET_CRYPTO_CsPublicKey *pub); + + + /** + * Derive a new secret r pair r0 and r1. + * In original papers r is generated randomly + * To provide abort-idempotency, r needs to be derived but still needs to be UNPREDICTABLE + * To ensure unpredictability a new nonce should be used when a new r needs to be derived. + * Uses HKDF internally. + * Comment: Can be done in one HKDF shot and split output. + * + * @param nonce is a random nonce + * @param lts is a long-term-secret in form of a private key + * @param[out] r array containing derived secrets r0 and r1 + */ + void + GNUNET_CRYPTO_cs_r_derive (const struct GNUNET_CRYPTO_CsNonce *nonce, + const struct GNUNET_CRYPTO_CsPrivateKey *lts, + struct GNUNET_CRYPTO_CsRSecret r[2]); + + + /** + * Extract the public R of the given secret r. + * + * @param r_priv the private key + * @param[out] r_pub where to write the public key + */ + void + GNUNET_CRYPTO_cs_r_get_public (const struct GNUNET_CRYPTO_CsRSecret *r_priv, + struct GNUNET_CRYPTO_CsRPublic *r_pub); + + + /** + * Derives new random blinding factors. + * In original papers blinding factors are generated randomly + * To provide abort-idempotency, blinding factors need to be derived but still need to be UNPREDICTABLE + * To ensure unpredictability a new nonce has to be used. + * Uses HKDF internally + * + * @param secret is secret to derive blinding factors + * @param secret_len secret length + * @param[out] bs array containing the two derivedGNUNET_CRYPTO_CsBlindingSecret + */ + void + GNUNET_CRYPTO_cs_blinding_secrets_derive (const struct GNUNET_CRYPTO_CsNonce *blind_seed, + struct GNUNET_CRYPTO_CsBlindingSecret bs[2]); + + + /** + * Calculate two blinded c's + * Comment: One would be insecure due to Wagner's algorithm solving ROS + * + * @param bs array of the two blinding factor structs each containing alpha and beta + * @param r_pub array of the two signer's nonce R + * @param pub the public key of the signer + * @param msg the message to blind in preparation for signing + * @param msg_len length of message msg + * @param[out] blinded_c array of the two blinded c's + */ + void + GNUNET_CRYPTO_cs_calc_blinded_c (const struct GNUNET_CRYPTO_CsBlindingSecret bs[2], + const struct GNUNET_CRYPTO_CsRPublic r_pub[2], + const struct GNUNET_CRYPTO_CsPublicKey *pub, + const void *msg, + size_t msg_len, + struct GNUNET_CRYPTO_CsC blinded_c[2]); + + + /** + * Sign a blinded c + * This function derives b from a nonce and a longterm secret + * In original papers b is generated randomly + * To provide abort-idempotency, b needs to be derived but still need to be UNPREDICTABLE. + * To ensure unpredictability a new nonce has to be used for every signature + * HKDF is used internally for derivation + * r0 and r1 can be derived prior by using GNUNET_CRYPTO_cs_r_derive + * + * @param priv private key to use for the signing and as LTS in HKDF + * @param r array of the two secret nonce from the signer + * @param c array of the two blinded c to sign c_b + * @param nonce is a random nonce + * @param[out] blinded_signature_scalar where to write the signature + * @return 0 or 1 for b (see Clause Blind Signature Scheme) + */ + int + GNUNET_CRYPTO_cs_sign_derive(const struct GNUNET_CRYPTO_CsPrivateKey *priv, + const struct GNUNET_CRYPTO_CsRSecret r[2], + const struct GNUNET_CRYPTO_CsC c[2], + const struct GNUNET_CRYPTO_CsNonce *nonce, + struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar + ); + + + /** + * Unblind a blind-signed signature using a c that was blinded + * + * @param blinded_signature_scalar the signature made on the blinded c + * @param bs the blinding factors used in the blinding + * @param[out] signature_scalar where to write the unblinded signature + */ + void + GNUNET_CRYPTO_cs_unblind (const struct GNUNET_CRYPTO_CsBlindS *blinded_signature_scalar, + const struct GNUNET_CRYPTO_CsBlindingSecret *bs, + struct GNUNET_CRYPTO_CsS *signature_scalar); + + + /** + * Verify whether the given message corresponds to the given signature and the + * signature is valid with respect to the given public key. + * + * @param sig signature that is being validated + * @param pub public key of the signer + * @param msg is the message that should be signed by @a sig (message is used to calculate c) + * @param msg_len is the message length + * @returns #GNUNET_YES on success, #GNUNET_SYSERR if key parameter(s) invalid #GNUNET_NO if signature invalid + */ + enum GNUNET_GenericReturnValue + GNUNET_CRYPTO_cs_verify (const struct GNUNET_CRYPTO_CsSignature *sig, + const struct GNUNET_CRYPTO_CsPublicKey *pub, + const void *msg, + size_t msg_len); + +\end{lstlisting}
\ No newline at end of file diff --git a/doc/cs/content/appendix/rsa-redesign.tex b/doc/cs/content/appendix/rsa-redesign.tex new file mode 100644 index 000000000..4f66d907e --- /dev/null +++ b/doc/cs/content/appendix/rsa-redesign.tex @@ -0,0 +1,209 @@ +\chapter{Redesigned RSA Protocols} +In order to bring the RSA and \gls{CSBS} protocols closer, this chapter describes a variant of the RSA protocols with the same changes as in the \gls{CSBS} versions (where they can be applied). + + +\section{Withdraw Protocol} +\begin{figure}[htp] + \begin{equation*} + \resizebox{1.0\textwidth}{!}{$\displaystyle + \begin{array}{ l c l } + \text{Customer} & & \text{Exchange} + \\ \text{knows:} & & \text{knows:} + \\ \text{reserve keys } w_s, W_p & & \text{reserve public key } W_p + \\ \text{denomination public key } D_p = e, N & & \text{denomination keys } d_s, D_p + \\ & & + \\\text{generate withdraw secret:} + \\ \omega := randombytes(32) + \\ \text{persist } \langle \omega, D_p \rangle + \\\text{derive coin key pair:} & & + \\ c_s := \text{HKDF}(256, \omega, \text{"cs"}) + \\ C_p := \text{Ed25519.GetPub}(c_s) + \\ \text{blind:} & & + \\ b_s := \text{HKDF}(256, \omega, \text{"b-seed"}) + \\ r := \text{FDH}(b_s) + \\ m' := \text{FDH}(N, C_p)*r^{e} \mod N & & + \\ \text{sign with reserve private key:} & & + \\ \rho_W := \langle D_p, m' \rangle & & + \\ \sigma_W := \text{Ed25519.Sign}(w_s, \rho_W) & & + \\ & \xrightarrow[\rule{2.5cm}{0pt}]{\rho = W_p, \sigma_W, \rho_W} & + \\ & & \langle D_p, m' \rangle := \rho_W + \\ & & \text{verify if } D_p \text{ is valid} + \\ & & \text{check } \text{Ed25519.Verify}(W_p, \rho_W, \sigma_W) + \\ & & \sigma'_c = (m')^{d_s} \mod N + \\ & & \text{decrease balance if sufficient and} + \\ & & \text{persist } \langle D_p, s \rangle + \\ & \xleftarrow[\rule{2.5cm}{0pt}]{\sigma'_c} & + \\ \text{unblind:}& & + \\ \sigma_c = \sigma'_c*r^{-1} & & + \\ \text{verify signature:}& & + \\ \textbf{check if } \sigma_c^{e} = \text{FDH}(N, C_p) & & + \\ & & + \\ \text{resulting coin: } c_s, C_p, \sigma_c, D_p & & + \\ & & + \\ \text{implementation note: minimum of} + \\ \text{persisted values is } \langle \omega, \sigma_c \rangle + \end{array}$ + } + \end{equation*} + \caption{Redesigned RSA withdrawal process} + \label{fig:withdrawal-process-rsa-redesign} +\end{figure} + +The changes to the RSA witdhdraw protocol (see \autoref{fig:withdrawal-process-rsa-redesign}) are limited to the derivation of the coin and blinding factor. + + +\section{Refresh Protocol} +The changes to the refresh protocol are related to the derivation of transfer secrets and subsequent operations, see \autoref{fig:refresh-derive-rsa-redesign}, \autoref{fig:refresh-part1-rsa-redesign} and \autoref{fig:refresh-part2-rsa-redesign}. +\begin{figure}[htp] + \centering + \fbox{% + \procedure[codesize=\small]{$\text{RefreshDerive}(t, \langle e, N \rangle, C_p)$}{% + T := \text{Curve25519.GetPub}(t) \\ + x := \textrm{ECDH-EC}(t, C_p) \\ + b_s := \text{HKDF}(256, x, \text{"b-seed"}) \\ + r := \text{FDH}(b_s) \\ + c'_s := \text{HKDF}(256,x,"c") \\ + C'_p := \text{Ed25519.GetPub}(c'_s) \\ + \overline{m} := r^e * C'_p \mod N \\ + \pcreturn \langle T, c_s', C_p', \overline{m} \rangle + } + } + \caption{Redesigned RSA RefreshDerive algorithm} + \label{fig:refresh-derive-rsa-redesign} +\end{figure} + +\begin{figure}[htp] + \begin{equation*} + \resizebox{1.0\textwidth}{!}{$\displaystyle + \begin{array}{ l c l } + % preliminaries + \text{Customer} & & \text{Exchange} + \\ \text{knows:} & & \text{knows:} + \\ \text{denomination public key } D_{p(i)} & & \text{denomination keys } d_{s(i)}, D_{p(i)} + \\ \text{coin}_0 = \langle D_{p(0)}, c_s^{(0)}, C_p^{(0)}, \sigma_c^{(0)} \rangle & & + % refresh request + \\ \text{Select} \langle N_t, e_t\rangle := D_{p(t)} \in D_{p(i)} + \\ \omega := randombytes(32) + \\ \text{persist } \langle \omega, D_{p(t)} \rangle + \\ \textbf{for } i = 1, \dots, \kappa: % generate k derives + \\ t_i := \text{HKDF}(256, \omega,\text{"t} i \text{"} ) % seed generation + \\ X_i := \text{RefreshDerive}(t_i, D_{p(t)}, C_p^{(0)}) + \\ (T_i, c_s^{(i)}, C_p^{(i)}, \overline{m}_i) := X_i + \\ \textbf{endfor} + \\ h_T := H(T_1, \dots, T_k) + \\ h_{\overline{m}} := H(\overline{m}_1, \dots, \overline{m}_k) + \\ h_C := H(h_t, h_{\overline{m}}) + \\ \rho_{RC} := \langle h_C, D_{p(t)}, D_{p(0)}, C_p^{(0)}, \sigma_C^{(0)} \rangle + \\ \sigma_{RC} := \text{Ed25519.Sign}(c_s^{(0)}, \rho_{RC}) + \\ \text{Persist refresh-request} \langle \omega, \rho_{RC}, \sigma_{RC} \rangle + \\ & \xrightarrow[\rule{2.5cm}{0pt}]{\rho_{RC}, \sigma_{RC}} & + % Exchange checks refresh request + \\ & & (h_C, D_{p(t)}, D_{p(0)}, C_p^{(0)}, \sigma_C^{(0)} = \rho_{RC}) + \\ & & \textbf{check} \text{Ed25519.Verify}(C_p^{(0)}, \sigma_{RC}, \rho_{RC}) + \\ & & x \rightarrow \text{GetOldRefresh}(\rho_{RC}) + \\ & & \textbf{Comment: }\text{GetOldRefresh} (\rho_{RC} \mapsto \{\bot,\gamma\}) + \\ & & \pcif x = \bot + \\ & & v := \text{Denomination}(D_{p(t)}) + \\ & & \langle e_0, N_0 \rangle := D_{p(0)} + \\ & & \textbf{check } \text{IsOverspending}(C_p^{(0)}, D_ {p(0)}, v) + \\ & & \textbf{check } D_{p(t)} \in \{D_{p(i)}\} + \\ & & \textbf{check } \text{FDH}(N_0, C_p^{(0)}) \equiv_{N_0} (\sigma_0^{(0)})^{e_0} + \\ & & \text{MarkFractionalSpend}(C_p^{(0)}, v) + \\ & & \gamma \leftarrow \{1, \dots, \kappa\} + \\ & & \text{Persist refresh-record } \langle \rho_{RC},\gamma \rangle + \\ & & \pcelse + \\ & & \gamma := x + \\ & & \textbf{endif} + \\ & \xleftarrow[\rule{2.5cm}{0pt}]{\gamma} & + \\ + \\ + \\ & \textit{Continued in figure \ref{fig:refresh-part2}} & + %\\ \pcintertext[dotted]{(Continued in Figure)} + \end{array}$ + } + \end{equation*} + \caption{Redesigned RSA refresh protocol (commit phase)} + \label{fig:refresh-part1-rsa-redesign} +\end{figure} + +\begin{figure}[htp] + \begin{equation*} + \resizebox{1.0\textwidth}{!}{$\displaystyle + \begin{array}{ l c l } + % preliminaries + \text{Customer} & & \text{Exchange} + \\ & \textit{Continuation of figure \ref{fig:refresh-part1}} & + \\ + \\ + % Check challenge and send challenge response (reveal not selected msgs) + \\ & \xleftarrow[\rule{2.5cm}{0pt}]{\gamma} & + \\ \textbf{check } \text{IsConsistentChallenge}(\rho_{RC}, \gamma) + \\ \textbf{Comment: } \text{IsConsistentChallenge}\\(\rho_{RC}, \gamma) \mapsto \{ \bot,\top \} + \\ + \\ \text{Persist refresh-challenge} \langle \rho_{RC}, \gamma \rangle + \\ S := \langle t_1, \dots, t_{\gamma-1}, t_{\gamma+1}, \dots, t_\kappa \rangle % all seeds without the gamma seed + \\ \rho_L = \langle C_p^{(0)}, D_{p(t)}, T_{\gamma},\overline{m}_\gamma \rangle + \\ \rho_{RR} = \langle T_\gamma, \overline{m}_\gamma, S \rangle + \\ \sigma_{L} = \text{Ed25519.Sign}(c_s^{(0)}, \rho_{L}) + \\ & \xrightarrow[\rule{2.5cm}{0pt}]{\rho_{RR},\rho_L, \sigma_{L}} & + % check revealed msgs and sign coin + \\ & & \langle T'_\gamma, \overline{m}'_\gamma, S \rangle := \rho_{RR} + \\ & & \langle t_1, \dots, t_{\gamma-1}, t_{\gamma+1}, \dots, t_\kappa \rangle ) := S + \\ & & \textbf{check } \text{Ed25519.Verify}(C_p^{(0)}, \sigma_L, \rho_L) + \\ & & \textbf{for} i = 1,\dots, \gamma-1, \gamma+1,\dots, \kappa + \\ & & X_i := \text{RefreshDerive}(t_i, D_{p(t)}, C_p^{(0)}) + \\ & & \langle T_i, c_s^{(i)}, C_p^{(i)}, \overline{m}_i \rangle := X_i + \\ & & \textbf{endfor} + \\ & & h_T' = H(T_1,\dots,T_{\gamma-1},T'_{\gamma},T_{\gamma+1},\dots,T_\kappa) + \\ & & h_{\overline{m}}' = H(\overline{m}_1,\dots,\overline{m}_{\gamma-1},\overline{m}'_{\gamma},\overline{m}_{\gamma+1},\dots,\overline{m}_\kappa) + \\ & & h_C' = H(h_T', h_{\overline{m}}') + \\ & & \textbf{check } h_C = h_C' + \\ & & \overline{\sigma}_C^{(\gamma)} := \overline{m}^{d_{s(t)}} + \\ & & \text{persist } \langle \rho_L, \sigma_L, S \rangle + \\ & \xleftarrow[\rule{2.5cm}{0pt}]{\overline{\sigma}_C^{(\gamma)}} & + % Check coin signature and persist coin + \\ \sigma_C^{(\gamma)} := r^{-1}\overline{\sigma}_C^{(\gamma)} + \\ \textbf{check if } (\sigma_C^{(\gamma)})^{e_t} \equiv_{N_t} C_p^{(\gamma)} + \\ \text{Persist coin} \langle D_{p(t)}, c_s^{(\gamma)}, C_p^{(\gamma)}, \sigma_C^{(\gamma)} \rangle + \end{array}$ + } + \end{equation*} + \caption{Redesigned RSA refresh protocol (reveal phase)} + \label{fig:refresh-part2-rsa-redesign} +\end{figure} + + +\section{Linking Protocol} +The changes are described in \autoref{fig:refresh-link-rsa-redesign}. +\begin{figure}[htp] + \begin{equation*} + \resizebox{1.0\textwidth}{!}{$\displaystyle + \begin{array}{ l c l } + % preliminaries + \text{Customer} & & \text{Exchange} + \\ \text{knows:} & & \text{knows:} + \\ \text{coin}_0 = \langle D_{p(0)}, c_s^{(0)}, C_p^{(0)}, \sigma_{C}^{(0)} \rangle + \\ & \xrightarrow[\rule{2.5cm}{0pt}]{C_{p(0)}} & + \\ & & L := \text{LookupLink}(C_{p(0)}) + \\ & & \textbf{Comment: } \text{LookupLink}(C_p) \mapsto \{\langle \rho_L^{(i)}, + \\ & & \sigma_L^{(i)}, \overline{\sigma}_C^{(i)} \rangle\} + \\ & \xleftarrow[\rule{2.5cm}{0pt}]{L} & + \\ \pcfor \langle \rho_{L}^{(i)}, \overline{\sigma}_L^{(i)}, \sigma_C^{(i)} \rangle \in L + \\ \langle \hat{C}_p^{(i)}, D_{p(t)}^{(i)}, T_\gamma^{(i)}, \overline{m}_\gamma^{(i)} \rangle := \rho_L^{(i)} + \\ \langle e_t^{(i)}, N_t^{(i)} \rangle := D_{p(t)}^{(i)} + \\ \textbf{check } \hat{C}_p^{(i)} \equiv C_p^{(0)} + \\ \textbf{check } \text{Ed25519.Verify}(C_p^{(0)}, \rho_{L}^{(i)}, \sigma_L^{(i)}) + \\ x_i := \text{ECDH}(c_s^{(0)}, T_{\gamma}^{(i)}) + \\ c_s^{(i)} := \text{HKDF}(256,x_i,"c") + \\ C_p^{(i)} := \text{Ed25519.GetPub}(c_s^{(i)}) + \\ b_s^{(i)} := \text{HKDF}(256, x_i, \text{"b-seed"}) + \\ r_i := \text{FDH}(b_s^{(i)}) + \\ \sigma_C^{(i)} := (r_i)^{-1} \cdot \overline{m}_\gamma^{(i)} + \\ \textbf{check } (\sigma_C^{(i)})^{e_t^{(i)}} \equiv_{N_t^{(i)}} C_p^{(i)} + \\ \text{(Re-)obtain coin} \langle D_{p(t)}^{(i)},c_s^{(i)}, C_p^{(i)}, \sigma_C^{(i)} \rangle + \end{array}$ + } + \end{equation*} + \caption{Redesigned RSA linking protocol} + \label{fig:refresh-link-rsa-redesign} +\end{figure} |