donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit d64bbee1bfeaa1d00aabd2d62d46475a77c87820
parent 8b93ff887412ca8b1db3e13bd33b45fa16b756f6
Author: Casaburi Johannes <johannes.casaburi@students.bfh.ch>
Date:   Mon, 15 Apr 2024 16:20:34 +0200

added more tests, work on doc

Diffstat:
Mdoc/flows/protocol/definitions.tex | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Mdoc/flows/protocol/main.pdf | 0
Mdoc/flows/protocol/main.tex | 22+++++++++++-----------
Msrc/donaudb/pg_insert_issued_receipt.c | 17++++++++---------
Msrc/donaudb/pg_insert_issued_receipt.h | 18+++++++++---------
Msrc/donaudb/pg_insert_submitted_receipt.c | 15+++++++--------
Msrc/donaudb/pg_insert_submitted_receipt.h | 16++++++++--------
Msrc/donaudb/test_donaudb.c | 21+++++++++++++++++++++
8 files changed, 165 insertions(+), 84 deletions(-)

diff --git a/doc/flows/protocol/definitions.tex b/doc/flows/protocol/definitions.tex @@ -6,22 +6,75 @@ \subsection{Definitions} \begin{itemize} - \item \textbf{Cryptographic Hash Function} $h := H(m)$ where $m$ is a message and $h$ the resulting hash. - - \item \textbf{BlindKeygen} $\langle K_x^{pub}, K_x^{priv} \rangle := Keygen^B(\omega)$ where $\omega$ is a source of entropy and $x$ is the associated value (e.g. 2 EUR). - The resulting key pair represents a donation unit. The result is a public key $K_x^{pub}$ and private key $K_x^{priv}$. The equivalent in Taler is a "denomination". + \item \textbf{Cryptographic Hash Function} + \begin{displaymath} + h := H(m) + \end{displaymath} + where $m$ is a message and $h$ the resulting hash. - \item \textbf{DonauKeygen} $\langle D^{pub}, D^{priv} \rangle := Keygen^D(\omega)$ + \item \textbf{Blinding Function} + \begin{displaymath} + \overline{u} := blind(u, b, K_x^{pub}) + \end{displaymath} + where $u$ is the value to blind, $b$ the blinding factor to apply and $K_x^{pub}$ the public key of the Donation Unit that will be used for signing. - \item \textbf{CharityKeygen} $\langle C^{pub}, C^{priv} \rangle := Keygen^C(\omega)$ + The blinding can be done with either the \textbf{RSA} blind signature scheme or the Blinded \textbf{Clause-Schnorr} signature scheme. - \item \textbf{Donor Identifier} $i := H(\texttt{taxid}, s)$ where $s$ is a random salt with sufficient entropy to prevent guessing attacks to invert the hash function. - - \item \textbf{Unique Donor Identifier} $u := \langle i, n \rangle$ where $n$ is a high-entropy nonce to make the resulting hash unique per donation. + \item \textbf{Unblinding Function} + \begin{displaymath} + \beta := unblind(\overline{\beta}, b, K_x^{pub}) + \end{displaymath} + where $\overline{\beta}$ is the value to unblind, $b$ the blinding factor to apply and $K_x^{pub}$ the public key of the Donation Unit that was used for signing. - \item \textbf{Blinding function} $\overline{u} := blind(u, b, K_x^{pub})$ where $u$ is the value to blind, $b$ the blinding factor to apply and $K_x^{pub}$ the public key of - the donation unit that will be used for signing. The blinding can be done with either the RSA blind signature scheme or the Blinded Clause-Schnorr signature scheme. - The $\overline{u}$ is a blinded unique donor identifier which is blinded to protect the privacy of the donor. + The unblinding must be carried out using the \textbf{same} signature scheme that has already been used for the blinding. + + \item \textbf{Donation Unit Key generation} + \begin{displaymath} + \langle K_x^{pub}, K_x^{priv} \rangle := Keygen^B(\omega) + \end{displaymath} + where $\omega$ is a source of entropy. The resulting key pair represents a \textbf{Donation Unit}. The result is a public key $K_x^{pub}$ and private key $K_x^{priv}$. The equivalent used in Taler system is a \texttt{Denomination}. + + \item \textbf{Donau Key generation} + \begin{displaymath} + \langle D^{pub}, D^{priv} \rangle := Keygen^D(\omega) + \end{displaymath} + where $D^{pub}$ and $D^{priv}$ are the respective public and private Donau keys. + + \item \textbf{Charity Key generation} + \begin{displaymath} + \langle C^{pub}, C^{priv} \rangle := Keygen^C(\omega) + \end{displaymath} + where $C^{pub}$ and $C^{priv}$ are the respective public and private Charity keys. + + \item \textbf{Donation Unit (DU)} + \begin{displaymath} + \langle K_x^{pub}, K_x^{priv} \rangle + \end{displaymath} + A Donation Unit consists of a public and private key where $x$ is the associated value (e.g. 2 EUR). + + \item \textbf{Donor Identifier (DI)} + \begin{displaymath} + i := H(\texttt{TAXID}, S) + \end{displaymath} + where $S$ is a random salt with sufficient entropy to prevent guessing attacks to invert the hash function. + + \item \textbf{Unique Donor Identifier (UDI)} + \begin{displaymath} + u := \langle i, N \rangle + \end{displaymath} + where $N$ is a high-entropy nonce to make the resulting hash \textbf{unique} per donation. + + \item \textbf{Blinded Unique Donor Identifier (BUDI)} + \begin{displaymath} + \overline{u} := blind( u, b, K_x^{pub} ) + \end{displaymath} + A \textbf{BUDI} is the result of blinding a Unique Donor Identifier $u$ where $b$ is the blinding factor and $K_x^{pub}$ the associated Key. The blinding is done to protect the privacy of the donor. + + \item \textbf{Blinded Unique Donor Identifier Key Pair (BKP)} + \begin{displaymath} + p := \langle \overline{u}, H(K_x^{pub}) \rangle + \end{displaymath} + A \textbf{Blinded Unique Donor Identifier Key Pair} is the result of adding the corresponding hash of the \textbf{Donation Unit} public key to the \textbf{Blinded Unique Donor Identifier} $\overline{u}$ where $H(K_x^{pub})$ is the hash of the \textbf{Donation Unit} public key. \item \textbf{Signing} \begin{itemize} @@ -29,55 +82,64 @@ \begin{align} \fbox{$s := sign(m,k^{priv})$} \end{align} - where $m$ is a message and $k^{priv}$ is the private key used to sign the message, for example $k^{priv} = D^{priv}$ or $k^{priv} = C^{priv}$.\\ + where $m$ is a message and $k^{priv}$ is the private key used to sign the message, for example the Donau private key $D^{priv}$ or the Charity private key $C^{priv}$.\\ + Applications: \begin{itemize} - \item Signatures over \textbf{Blinded Unique Donor Identifier-key-pair} or \textbf{BUDI-key-pairs}: + \item Signatures over a \textbf{Blinded Unique Donor Identifier Key Pair}: \begin{align} - \mu := \langle \overline{u}, H(K_x^{pub}) \rangle \\ - \fbox{$\vec{\mu}_s := sign(\vec{\mu},C^{priv})$} + \fbox{$\vec{\mu}_s := sign(\vec{p},C^{priv})$} \end{align} - where $H(K_x^{pub})$ indicates which donation unit key should be used by the Donau to sign the resulting donation receipt. Thus, this hash carries the information about the exact value the final donation receipt should carry. + where $H(K_x^{pub})$ indicates which \textbf{Donation Unit} key should be used by the Donau to sign the resulting \textbf{Donation Receipt}. Thus, this hash carries the information about the exact value, the final Donation Receipt should carry. - A charity signs a collection of \emph{BUDI-key-pair} before transfering them to the Donau to issue \emph{Donation Receipts} - \item Signing over \textbf{Donation Statement signatures}: - \begin{align} - \sigma := \langle i, a_\Sigma, \texttt{year} \rangle \\ - \fbox{$\sigma_s := sign(\sigma, D^{priv})$} - \end{align} - where $D^{priv}$ is the private key from the Donau. - These signatures attest the amount donated in a particular year by a specific donor. + A charity signs a collection of \textbf{Blinded Unique Donor Identifier Key Pairs} before transfering them to the Donau to issue the \textbf{Donation Receipts} - The Donau computes the \emph{donation statement signature} for a donor for a specific year + \item Generation of the \textbf{Donation Statement} \end{itemize} - + \item \textbf{Blind signing(e.g. RSA/CS):} \begin{align} \fbox{$\overline{\beta} := blind\_sign(\overline{u},K_x^{priv})$} \end{align} where $\overline{u}$ is a blinded value and $K_x^{priv}$ is the private key used to blind sign the message.\\ + Application: \begin{itemize} - \item The Donau blind signs \emph{Blinded Unique Donor Identifier}s received from the charity with the private key matching the public key in the received \emph{BUDI-key-pair} + \item The Donau blind signs \textbf{Blinded Unique Donor Identifiers} received from the Charity with the private key matching the public key in the received \textbf{Blinded Unique Donor Identifier Key Pair} \end{itemize} \end{itemize} - - \item \textbf{Unblinding function} $\beta := Unblind(\overline{\beta}, b, K_x^{pub})$ where $\overline{\beta}$ is the value to unblind, $b$ the blinding factor to apply and $K_x^{pub}$ the public key of the donation unit that was used for signing. The unblinding must be carried out using the same signature scheme that has already been used for blinding. - The unblinded value $\beta$ is a unique donor identifier. + \item \textbf{Verify Functions} + + To verify the signatures $m$ corresponds to the message and $s$ to the signature: - \item \textbf{Verify functions} - to verify the signatures \\ - $m$ corresponds to the message and $s$ to the signature: \begin{itemize} - \item \textbf{normal verify} \\ - $verify(m,s, P^{pub})$ where $P^{pub}$ can be the public key of the Donau $D^{pub}$ or of the charity $C^{pub}$. + \item \textbf{normal verify} + \begin{displaymath} + verify(m,s, P^{pub}) + \end{displaymath} + where $P^{pub}$ can be the Donau public key $D^{pub}$ or Charity public key $C^{pub}$. \end{itemize} \begin{itemize} - \item \textbf{blind verify} - verify a signature that was made blind\\ - $verify\_blind(m,s,K_x^{pub})$ verifies only signatures made with $K_x^{priv}$. + \item \textbf{blind verify} + \begin{displaymath} + verify\_blind(m,s,K_x^{pub}) + \end{displaymath} + verify a signature that was made blind and made with a Donation Unit private key $K_x^{priv}$. \end{itemize} - - \item \textbf{Donation Receipt} $r := \langle u, \beta, H(K_x^{pub}) \rangle$ where $\beta$ is the unblinded signature: Sent to the Donau to get the donation Statement. + \item \textbf{Donation Receipt} + \begin{displaymath} + r := \langle u, \beta, H(K_x^{pub}) \rangle + \end{displaymath} + where $\beta$ is the unblinded signature sent to the Donau to get the \textbf{Donation Statement}. + + \item \textbf{Donation Statement} + \begin{displaymath} + \omega := sign(\langle i, \texttt{Amount}_total, \texttt{Year}\rangle, D^{priv}) + \end{displaymath} + The Donation Statement is the signature over the total amount a donor has donated throughout the year where $\beta$ is the unblinded signature sent to the Donau to get the \textbf{Donation Statement}. + + These signatures attest the amount donated in a particular year by a specific donor. \end{itemize} diff --git a/doc/flows/protocol/main.pdf b/doc/flows/protocol/main.pdf Binary files differ. diff --git a/doc/flows/protocol/main.tex b/doc/flows/protocol/main.tex @@ -25,14 +25,14 @@ \input{definitions.tex} -\newpage - -\section{Overview} -\subsection{Donation: spend and get donation receipt} -\includegraphics[width=\textwidth]{02-donate} - -\subsection{Get donation statement for taxes after tax period} -\includegraphics[width=\textwidth]{03-donation-statement} +% \newpage +% FIXME +% \section{Overview} +% \subsection{Donation: spend and get donation receipt} +% \includegraphics[width=\textwidth]{02-donate} +% +% \subsection{Get donation statement for taxes after tax period} +% \includegraphics[width=\textwidth]{03-donation-statement} %\input{diagrams.tex} @@ -153,9 +153,9 @@ \item The donor unblinds the signatures of the $BUDI$'s to get the signatures of the $UDI$'s. This results in a collection of \textbf{Donation Receipts} $DR$'s each consisting of the $UDI$, the signature $\beta$ and the Hash of the \emph{donation unit public key} $h(K_x^{pub})$. \begin{align} - \beta_1 &= Unblind(\overline{\beta_1}, b_1, K_1^{pub}) \\ - \beta_2 &= Unblind(\overline{\beta_2}, b_2, K_2^{pub}) \\ - \beta_3 &= Unblind(\overline{\beta_3}, b_3, K_4^{pub}) + \beta_1 &= unblind(\overline{\beta_1}, b_1, K_1^{pub}) \\ + \beta_2 &= unblind(\overline{\beta_2}, b_2, K_2^{pub}) \\ + \beta_3 &= unblind(\overline{\beta_3}, b_3, K_4^{pub}) \end{align} \begin{align} r_1 &= \langle UDI_1, \beta_1, h(K_1^{pub}) \rangle \\ diff --git a/src/donaudb/pg_insert_issued_receipt.c b/src/donaudb/pg_insert_issued_receipt.c @@ -30,15 +30,14 @@ #include "donau_pq_lib.h" enum GNUNET_DB_QueryStatus -DH_PG_insert_issued_receipt (void *cls, - const size_t num_blinded_sig, - const struct - DONAU_BlindedDonationUnitSignature signatures[ - num_blinded_sig], - const uint64_t charity_id, - const struct DONAU_DonationReceiptHashP *h_receipt, - const struct TALER_Amount *amount_receipts_request, - const struct TALER_Amount *charity_new_amount) +DH_PG_insert_issued_receipt ( + void *cls, + const size_t num_blinded_sig, + const struct DONAU_BlindedDonationUnitSignature signatures[num_blinded_sig], + const uint64_t charity_id, + const struct DONAU_DonationReceiptHashP *h_receipt, + const struct TALER_Amount *amount_receipts_request, + const struct TALER_Amount *charity_new_amount) { struct PostgresClosure *pc = cls; diff --git a/src/donaudb/pg_insert_issued_receipt.h b/src/donaudb/pg_insert_issued_receipt.h @@ -38,14 +38,14 @@ * @return transaction status code */ enum GNUNET_DB_QueryStatus -DH_PG_insert_issued_receipt (void *cls, - const size_t num_blinded_sig, - const struct - DONAU_BlindedDonationUnitSignature signatures[ - num_blinded_sig], - const uint64_t charity_id, - const struct DONAU_DonationReceiptHashP *h_receipt, - const struct TALER_Amount *amount_receipts_request, - const struct TALER_Amount *charity_new_amount); +DH_PG_insert_issued_receipt ( + void *cls, + const size_t num_blinded_sig, + const struct DONAU_BlindedDonationUnitSignature signatures[num_blinded_sig], + const uint64_t charity_id, + const struct DONAU_DonationReceiptHashP *h_receipt, + const struct TALER_Amount *amount_receipts_request, + const struct TALER_Amount *charity_new_amount + ); #endif diff --git a/src/donaudb/pg_insert_submitted_receipt.c b/src/donaudb/pg_insert_submitted_receipt.c @@ -27,14 +27,13 @@ #include "donau_service.h" enum GNUNET_DB_QueryStatus -DH_PG_insert_submitted_receipt (void *cls, - const struct DONAU_HashDonorTaxId *h_tax_number, - const union GNUNET_CRYPTO_BlindSessionNonce * - nonce, - const struct - DONAU_DonationUnitPublicKey *donation_unit_pub, - const struct DONAU_DonauSignatureP *donau_sig, - const uint64_t donation_year) +DH_PG_insert_submitted_receipt ( + void *cls, + const struct DONAU_HashDonorTaxId *h_tax_number, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, + const struct DONAU_DonationUnitPublicKey *donation_unit_pub, + const struct DONAU_DonauSignatureP *donau_sig, + const uint64_t donation_year) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { diff --git a/src/donaudb/pg_insert_submitted_receipt.h b/src/donaudb/pg_insert_submitted_receipt.h @@ -38,13 +38,13 @@ * @return transaction status code */ enum GNUNET_DB_QueryStatus -DH_PG_insert_submitted_receipt (void *cls, - const struct DONAU_HashDonorTaxId *h_tax_number, - const union GNUNET_CRYPTO_BlindSessionNonce * - nonce, - const struct - DONAU_DonationUnitPublicKey *donation_unit_pub, - const struct DONAU_DonauSignatureP *donau_sig, - const uint64_t donation_year); +DH_PG_insert_submitted_receipt ( + void *cls, + const struct DONAU_HashDonorTaxId *h_tax_number, + const union GNUNET_CRYPTO_BlindSessionNonce *nonce, + const struct DONAU_DonationUnitPublicKey *donation_unit_pub, + const struct DONAU_DonauSignatureP *donau_sig, + const uint64_t donation_year + ); #endif diff --git a/src/donaudb/test_donaudb.c b/src/donaudb/test_donaudb.c @@ -92,6 +92,10 @@ run (void *cls) uint64_t validity_year; struct TALER_Amount du_value; + // Signing key information + struct DONAU_DonauPublicKeyP donau_pubkey; + struct SigningKey *sk; + if (NULL == (plugin = DONAUDB_plugin_load (cfg))) { @@ -169,6 +173,23 @@ run (void *cls) NULL, NULL)); + /* test insert signing key */ + RND_BLK (&donau_pubkey); + sk->donau_pub = donau_pubkey; + sk->meta.expire_legal + sk->meta.expire_sign + sk->meta.valid_from + + FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->insert_signing_key (plugin->cls, + &sk->donau_pub, + &sk->meta)); + + /* test iterate signing key */ + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->iterate_active_signing_keys (plugin->cls, + NULL, + NULL)); // TODO Add more tests drop: