780 lines
37 KiB
TeX
780 lines
37 KiB
TeX
\documentclass{scrartcl}
|
||
\usepackage[a4paper]{geometry}
|
||
\usepackage{hyperref}
|
||
\usepackage[dvipsnames]{xcolor}
|
||
\hypersetup{
|
||
colorlinks = true,
|
||
allcolors = {black},
|
||
linkcolor = DarkOrchid,
|
||
urlcolor = DarkOrchid,
|
||
}
|
||
\usepackage{url}
|
||
\usepackage[font=footnotesize]{caption}
|
||
\usepackage{amssymb}
|
||
\usepackage{amsmath}
|
||
\usepackage{pdfpages}
|
||
\usepackage{graphicx}
|
||
\usepackage{listings}
|
||
\usepackage{fontspec}
|
||
\usepackage{menukeys}
|
||
\usepackage{tikz}
|
||
\usetikzlibrary{tikzmark}
|
||
\usetikzlibrary{shapes,arrows,arrows.meta}
|
||
\usetikzlibrary{positioning,patterns}
|
||
\usetikzlibrary{calc}
|
||
\setmonofont[Path = ../fonts/,
|
||
Extension = .ttf,
|
||
UprightFont = *-Regular,
|
||
ItalicFont = *-Italic,
|
||
BoldFont = *-Bold,
|
||
Scale=0.85]{RobotoMono}
|
||
|
||
\lstdefinelanguage{typescript}{
|
||
keywords={typeof, new, true, false, catch, function, return, null, catch, switch, var, if, in, while, do, else, case, break, interface},
|
||
keywordstyle=\bfseries,
|
||
ndkeywords={class, export, boolean, number, Amount, string, Timestamp, RelativeTime, EddsaPublicKey, BrandtVickreyAuction, BrandtVickreyAuctionMessage, BrandtVickreyAuctionWinner, EddsaSignature, HashCode, throw, implements, import, this, BrandtVickreyReplayOutcome},
|
||
ndkeywordstyle=\bfseries,
|
||
identifierstyle=\color{black},
|
||
sensitive=false,
|
||
comment=[l]{//},
|
||
morecomment=[s]{/*}{*/},
|
||
commentstyle=\itshape,
|
||
%stringstyle=\color{red},
|
||
morestring=[b]',
|
||
morestring=[b]"
|
||
}
|
||
|
||
\lstset{
|
||
language=typescript,
|
||
%backgroundcolor=\color{lightgray},
|
||
extendedchars=true,
|
||
basicstyle=\footnotesize\color{NavyBlue}\ttfamily,
|
||
showstringspaces=false,
|
||
showspaces=false,
|
||
%numbers=left,
|
||
%numberstyle=\footnotesize,
|
||
%numbersep=9pt,
|
||
tabsize=2,
|
||
breaklines=true,
|
||
showtabs=false,
|
||
captionpos=b,
|
||
emphstyle=\bfseries
|
||
}
|
||
\newcommand{\TODO}[1]{{\color{orange}#1}\marginpar{{\color{orange}TODO}}}
|
||
\include{definitions}
|
||
|
||
\begin{document}
|
||
|
||
\title{AP³\\
|
||
Report for Milestone IV\\
|
||
NGI Pointer}
|
||
\author{Özgür Kesim\\
|
||
Christan Grothoff\\
|
||
Florian Dold\\
|
||
Stefan Kügel\\
|
||
Emmanuel Benoist\\[\bigskipamount]
|
||
\normalsize Mentor: Mirko Ross \href{mailto:m.ross@digital-worx.de}{<m.ross@digital-worx.de>}\\[\medskipamount]
|
||
}
|
||
|
||
\date{October 29, 2022}
|
||
|
||
\maketitle
|
||
|
||
\section*{Management summary}
|
||
\begin{abstract}
|
||
\noindent
|
||
For the \textsc{NGI Pointer} programme, the AP³ project team extended GNU Taler with
|
||
\begin{itemize}
|
||
\item age-restricted payments,
|
||
\item peer-to-peer (P2P) payments and
|
||
\item a proof-of-concept escrow functionality for
|
||
privacy-preserving auctions.
|
||
\end{itemize}
|
||
|
||
This document provides the report for the final milestone IV with details on
|
||
the results of our usability study, the state of the implementation of
|
||
the features and projected future work.
|
||
|
||
\end{abstract}
|
||
|
||
\vfill
|
||
\hfill {\footnotesize Version: 1.0}
|
||
|
||
\thispagestyle{empty}
|
||
|
||
\newpage
|
||
\tableofcontents
|
||
\newpage
|
||
|
||
|
||
\section{Age Restriction}
|
||
|
||
We designed and implemented a scheme for age restriction in GNU Taler based on
|
||
the following basic ideas:
|
||
|
||
Parents/warden can choose to \textbf{commit} a certain maximum age out of a
|
||
predefined list of age groups and bind that commitment to a particular coin.
|
||
The minors receive those coins and can now \textbf{attest} a required minimum
|
||
age (provided that age is less or equal to the committed age of the coins) to
|
||
merchants, who can \textbf{verify} the minimum age. For the rest values
|
||
(change) after an transaction, the minor/ward can \textbf{derive} new
|
||
age-restricted coins. The exchange can \textbf{compare} the equality of the
|
||
age-restriction of the old coin with the new coin (in a zero-knowledge
|
||
protocol $\DeriveCompare$, that gives the minor a 1/$\kappa$ chance to raise
|
||
the minimum age for the new coin).
|
||
|
||
Figure~\ref{scheme} gives an overview of the scheme for age restriction
|
||
detached from the payment flow.
|
||
|
||
\begin{figure}[h]
|
||
\begin{center}\footnotesize
|
||
\begin{tikzpicture}[scale=.8]
|
||
\node[circle,minimum size=25pt,fill=black!15] at ( 0:0) (Client) {$\Child$};
|
||
\node[circle,minimum size=25pt,fill=black!15] at ( 60:5) (Exchange) {$\Exchange$};
|
||
\node[circle,minimum size=25pt,fill=black!15] at ( 0:5) (Merchant) {$\Merchant$};
|
||
\node[circle,minimum size=25pt,fill=blue!15] at (130:3) (Guardian) {$\Guardian$};
|
||
|
||
\draw[orange,<->] (Client) to node[sloped,below,align=center]
|
||
{\orange{$\DeriveCompare$}} (Exchange);
|
||
\draw[blue,->] (Client) to node[sloped, below]
|
||
{\blue{$(\attest_\minage, \commitment)$}} (Merchant);
|
||
|
||
\draw[->] (Guardian) to [out=150,in=70, loop] node[above]
|
||
{$\Commit(\age)$} (Guardian);
|
||
\draw[->] (Guardian) to node[below,sloped]
|
||
{($\commitment$, $\pruf_\age$)} (Client);
|
||
\draw[->,blue] (Client) to [out=-50,in=-130, loop] node[below]
|
||
{\blue{$\Attest(\minage, \commitment, \pruf_{\age})$}} (Client);
|
||
\draw[->,blue] (Merchant) to [out=-50,in=-130, loop] node[below]
|
||
{\blue{$\Verify(\minage, \commitment, \attest_{\minage})$}} (Merchant);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
\caption{Scheme of the age restriction performed between a guardian
|
||
$\Guardian$, a child $\Child$, a merchant $\Merchant$ and an exchange
|
||
$\Exchange$, using the functions $\Commit$, $\Attest$, $\Verify$ and
|
||
the zero-knowledge protocol $\DeriveCompare$ which is based on
|
||
functions $\Derive$ and $\Compare$. $\commitment$ is the age
|
||
commitment for a maximum age $\age \in \{1,...,\Age\}$ and
|
||
$\pruf_{\age}$ is the corresponding proof. $\attest_{\minage}$ is an
|
||
attestation of a required age $\minage \leq \age$.}
|
||
\label{scheme}
|
||
\end{figure}
|
||
|
||
We have implemented all parts of this scheme in GNU Taler's exchange, wallet
|
||
and merchant code bases for the most common protocols: withdraw, purchase,
|
||
deposit and refresh.
|
||
|
||
\subsection{Technical details}
|
||
|
||
Our implementation of the five functions $\Commit$, $\Attest$, $\Verify$,
|
||
$\Derive$ and $\Compare$ is based on the following main building blocks:
|
||
|
||
\begin{itemize}
|
||
\item The exchange $\Exchange$ defines and publishes M+1 different
|
||
\textit{age groups} of increasing order: $0 < a_1 < \ldots <
|
||
a_M$ with $a_i \in \mathbb{N}$. The zeroth age group is
|
||
$\{0,\ldots,a_1-1\}$.
|
||
|
||
\item An \textit{unrestricted} age commitment is defined as a vector of
|
||
length $\Age$ of pairs of
|
||
\href{https://docs.taler.net/design-documents/024-age-restriction.html#edx25519}{Edx25519}
|
||
public and private keys on Curve25519. In other words: one key
|
||
pair for each age group after the zeroth: $\bigl\langle (p_1,
|
||
q_1), \ldots, (p_M, q_M) \bigr\rangle$. (Here, $p_i$ are
|
||
\textit{private} and $q_i$ are public keys).
|
||
|
||
\item A \textit{restricted} age commitment to age group m (or m-th age
|
||
group) is derived from an unrestricted age commitment by
|
||
removing all private keys for indices larger than m:
|
||
\[
|
||
\bigl\langle (p_1, q_1), \ldots, (p_m, q_m),
|
||
\, (\perp, q_{m+1}),
|
||
\ldots, (\perp, q_M)\bigr\rangle
|
||
\] F.e. if none of the private keys is provided, the age
|
||
commitment would be restricted to the zeroth age group.
|
||
|
||
Note that the action of dropping private keys is performed by
|
||
the guardian $\Guardian$.
|
||
|
||
\item An \textit{age commitment} (without prefix) is just the vector of
|
||
public keys: $\commitment := \langle q_1, \ldots, q_M \rangle$.
|
||
Note that from just the age commitment one can not deduce if it
|
||
was originated from an unrestricted or restricted age
|
||
commitment (and what age).
|
||
|
||
\item A child $\Child$ receives the commitment $\commitment$ along with
|
||
the proof, the restricted vector\\
|
||
$\pruf_\age := (p_1,\ldots,p_\age,\perp,\ldots,\perp)$.
|
||
$\Child$ can now create an \textit{attestation}
|
||
$\attest_\minage$ for age group $\minage \leq \age$, which is
|
||
simply a signature to some message with the private key
|
||
$p_\minage$.
|
||
|
||
\item An age commitment $\commitment$ is bound to a particular coin
|
||
$C_p$ by incorporating the SHA256 hash value of $\commitment$
|
||
into the signature of the coin. So, instead of signing the
|
||
full-domain-hash $\text{FDH}(C_p)$ with the RSA private key of
|
||
a denomination, the exchange signs $\text{FDH}(C_p,
|
||
\orange{H(\commitment)})$.
|
||
|
||
\item $\DeriveCompare$ is a zero-knowledge, cut-and-choose protocol,
|
||
using the functions $\Derive$ and $\Compare$, which allows
|
||
$\Child$ to derive new commitments from existing ones in an
|
||
unlinkable way and $\Exchange$ to statistically trust them to
|
||
be equivalent. The protocol is defined roughly as follows,
|
||
with $\kappa \in \N$ the security parameter (currently $\kappa
|
||
= 3$):
|
||
\begin{enumerate}
|
||
\item $\Child$ derives commitments $(\commitment_1,\dots,\commitment_\kappa)$
|
||
from $\commitment_0$ by calling $\Derive()$ \\ with blindings $(\beta_1,\dots,\beta_\kappa)$
|
||
\item $\Child$ calculates $h_0:=H\left(H(\commitment_1, \beta_1)||\dots||H(\commitment_\kappa, \beta_\kappa)\right)$
|
||
\item $\Child$ sends $\commitment_0$ and $h_0$ to $\Exchange$
|
||
\item $\Exchange$ chooses $\gamma \in \{1,\dots,\kappa\}$ randomly
|
||
\item $\Child$ reveals $h_\gamma:=H(\commitment_\gamma, \beta_\gamma)$ and all $(\commitment_i, \beta_i)$, except $(\commitment_\gamma, \beta_\gamma)$
|
||
\item $\Exchange$ compares $h_0$ and
|
||
$H\left(H(\commitment_1, \beta_1)||...||h_\gamma||...||H(\commitment_\kappa, \beta_\kappa)\right)$
|
||
and \\ evaluates $\Compare(\commitment_0, \commitment_i, \beta_i)$.
|
||
\end{enumerate}
|
||
|
||
\end{itemize}
|
||
|
||
The integration of both schemes for age restriction and the scheme for payment
|
||
in GNU Taler (protocols \textsf{withdraw}, \textsf{purchase}, \textsf{deposit}
|
||
and \textsf{refresh}) is sketched in Figure~\ref{bothschemes}.
|
||
\begin{figure}[ht]
|
||
\begin{center}
|
||
\begin{tikzpicture}[scale=.9]
|
||
\node[circle,minimum size=25pt,fill=black!15] at ( 0:0) (Client) {$\Child$};
|
||
\node[circle,minimum size=25pt,fill=black!15] at ( 60:5) (Exchange) {$\Exchange$};
|
||
\node[circle,minimum size=25pt,fill=black!15] at ( 0:5) (Merchant) {$\Merchant$};
|
||
\node[circle,minimum size=25pt,fill=blue!15] at (130:3) (Guardian) {$\Guardian$};
|
||
|
||
\draw[<->] (Guardian) to node[sloped,above,align=center]
|
||
{\textsf{withdraw}\orange{, using}\\ $\FDH(C_p\orange{, H(\commitment)})$} (Exchange);
|
||
\draw[<->] (Client) to node[sloped,below,align=center]
|
||
{\textsf{refresh} \orange{ + }\\ \orange{$\DeriveCompare$}} (Exchange);
|
||
\draw[<->] (Client) to node[sloped, below]
|
||
{\textsf{purchase} \blue{+ $(\attest_\minage, \commitment)$}} (Merchant);
|
||
\draw[<->] (Merchant) to node[sloped, above]
|
||
{\textsf{deposit} \orange{+ $H(\commitment)$}} (Exchange);
|
||
|
||
\draw[->] (Guardian) to [out=70,in=150, loop] node[above]
|
||
{$\Commit(\age)$} (Guardian);
|
||
\draw[->] (Guardian) to node[below,sloped]
|
||
{($\commitment$, $\pruf_\age$)} (Client);
|
||
\draw[->,blue] (Client) to [out=-50,in=-130, loop] node[below]
|
||
{\blue{$\Attest(\minage, \commitment, \pruf_{\age})$}} (Client);
|
||
\draw[->,blue] (Merchant) to [out=-50,in=-130, loop] node[below]
|
||
{\blue{$\Verify(\minage, \commitment, \attest_{\minage})$}} (Merchant);
|
||
\end{tikzpicture}
|
||
\end{center}
|
||
\caption{Sketch of the integration of the schemes for age restriction
|
||
and payment in GNU Taler.}
|
||
\label{bothschemes}
|
||
\end{figure}
|
||
|
||
The proposed solution maintains the guarantees of GNU Taler with respect to
|
||
anonymity and unlinkability. Precise formulations of the functions, protocols,
|
||
requirements and security guarantees---together with proofs---can be found in
|
||
our paper
|
||
\href{https://taler.net/papers/esorics2022-age-restriction.pdf}
|
||
{\textit{Zero-Knowledge Age Restriction for GNU Taler}},
|
||
published in the
|
||
\href{https://link.springer.com/chapter/10.1007/978-3-031-17140-6\_6}
|
||
{proceedings to ESORICS 2022}.
|
||
|
||
|
||
|
||
\subsection{Legal evaluation}
|
||
|
||
We are in correspondence with the \href{https://www.kjm-online.de/en/}{German
|
||
Commission for the Protections of Minors in the Media (KJM)}. The commission
|
||
acts as the central supervisory body for the protection of minors in private
|
||
broadcasting and media in Germany and runs a Berlin-based joint office of state
|
||
authorities for media and journalism within the Federal republic of Germany.
|
||
Its plenary congregation meets in Berlin on December 7, 2022, for which GNU
|
||
Taler applies with a systematic description and the whitepaper on Taler tokens
|
||
with age restrictions in German language. The application is assisted and
|
||
coordinated by Mr. Henning Mellage, Legal \& Supervision Officer, at the
|
||
Landesanstalt für Medien NRW in Düsseldorf which is part of the KJM.
|
||
|
||
The KJM confirmed its intention to evaluate GNU Taler as recommendable concept
|
||
for the protection of minors and to add GNU Taler to its list of positively
|
||
evaluated, so-called ``cross-channel concepts'' at
|
||
\href{https://www.kjm-online.de/en/supervision/technical-protection-of-minors-in-the-media/cross-channel-concepts}%
|
||
{\texttt{https://www.kjm-online.de/en/supervision/{\small \keys{\return}}\\
|
||
technical-protection-of-minors-in-the-media/cross-channel-concepts}}. This
|
||
includes the presentation of GNU Taler in the document
|
||
\href{https://www.kjm-online.de/fileadmin/user_upload/KJM/Aufsicht/Technischer_Jugendmedienschutz/Uebergreifende_Jugendschutzkonzepte.pdf}{\textit{Übersicht
|
||
über positiv bewertete übergreifende Jugendschutzkonzepte}}, which mirrors the
|
||
content of the mentioned website with recommended concepts of youth protection.
|
||
|
||
GNU Taler is going to be evaluated for the category ``holistic youth protection
|
||
concept''. The KJM uses this category only for concepts that are widely
|
||
accessible to the public and \textit{do not} serve a closed user group. Here,
|
||
\textit{serving a closed user group} means granting access to content or goods
|
||
only after ID-based verification of the membership in a particular group, such
|
||
as: proof of belonging to a certain age-group by presenting an official ID
|
||
card, driving licenses or the like---a type of verification which is
|
||
endangering privacy, data security, and informational self-determination.
|
||
|
||
\subsection{Future Works}
|
||
|
||
\begin{description}
|
||
\item[Finishing support for age restriction:] So far, age-restriction
|
||
is not available in P2P payments when the age data is obtained
|
||
from the KYC process. Also, the tipping protocol doesn't allow
|
||
for denominations with age restriction, yet. We will add
|
||
support for age-restriction in those scenarios.
|
||
|
||
\item[Support for minors with bank accounts:] The current design
|
||
of age restriction is based on the assumption that only
|
||
adults can have bank accounts. That is: wire transfers to the
|
||
exchange are assumed to be originated by adults.
|
||
|
||
However, in some countries, like Germany, it is possible for
|
||
minors to have bank accounts, too, starting from a certain age.
|
||
In those cases, the wire transfer record will indicate that the
|
||
originating account is owned by a minor.
|
||
|
||
We plan to extend the current design and implementation of age
|
||
restriction to handle those situations as well: After the
|
||
exchange receives a wire transfer from a bank account of a
|
||
minor, it will require in a zero-knowledge-proof for a) the
|
||
presence of age restriction and b) the appropriate
|
||
\textit{maximum} age for the age commitment during the
|
||
\textsf{withdraw} protocol.
|
||
|
||
\end{description}
|
||
|
||
|
||
\subsection{Links}
|
||
|
||
Our scheme for age restriction in GNU Taler has been
|
||
\href{https://link.springer.com/chapter/10.1007/978-3-031-17140-6\_6}{published
|
||
in the proceedings to ESORICS 2022}.
|
||
In addition,
|
||
\href{https://docs.taler.net/design-documents/024-age-restriction.html}%
|
||
{document 24} at \url{https://docs.taler.net/design-documents} also lays out
|
||
the design. The implementation is distributed across multiple repositories:
|
||
|
||
{ \small
|
||
\begin{description}
|
||
\item[Exchange:] The following REST endpoint handlers and their
|
||
accompanying helper functions in
|
||
\url{https://git.taler.net/exchange.git/tree/src}:
|
||
\begin{itemize}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/exchange/taler-exchange-httpd_deposit.c}{\texttt{TEH\_handler\_deposit}}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/exchange/taler-exchange-httpd_melt.c}{\texttt{TEH\_handler\_melt}}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/exchange/taler-exchange-httpd_refreshes_reveal.c}{\texttt{TEH\_handler\_reveal}}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/exchange/taler-exchange-httpd_recoup.c}{\texttt{TEH\_handler\_recoup}}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/exchange/taler-exchange-httpd_recoup-refresh.c}{\texttt{TEH\_handler\_recoup\_refresh}}
|
||
\end{itemize}
|
||
|
||
Under \url{https://git.taler.net/exchange.git/tree/src/exchangedb}:\\
|
||
\href{https://git.taler.net/exchange.git/tree/src/exchangedb/common.sql}{common.sql},
|
||
\href{https://git.taler.net/exchange.git/tree/src/exchangedb/exchange-0001.sql}{exchange-0001.sql},
|
||
\href{https://git.taler.net/exchange.git/tree/src/exchangedb/plugin\_exchangedb\_postgres.c}{plugin\_exchangedb\_postgres.c}.
|
||
\item[Merchant:]
|
||
Under \url{https://git.taler.net/merchant.git/tree/src/},
|
||
\begin{itemize}
|
||
\item schema changes in
|
||
\href{https://git.taler.net/merchant.git/tree/src/backenddb/merchant-0001.sql}{backenddb/merchant-0001.sql} and\\
|
||
\href{https://git.taler.net/merchant.git/tree/src/backenddb/plugin_merchantdb_postgres.c}{backenddb/plugin\_merchantdb\_postgres.c}
|
||
\item functions \verb|process_pay_with_exchange| and \verb|parse_pay| in\\
|
||
\href{https://git.taler.net/merchant.git/tree/src/backend/taler-merchant-httpd_post-orders-ID-pay.c}{backend/taler-merchant-httpd\_post-orders-ID-pay.c}
|
||
\end{itemize}
|
||
|
||
\item[Wallet:]
|
||
Under \url{https://git.taler.net/wallet-core.git/tree/packages/taler-util}
|
||
\begin{itemize}
|
||
\item low-level cryptographic primitives in
|
||
\href{https://git.taler.net/wallet-core.git/tree/packages/taler-util/src/nacl-fast.ts}{\texttt{crypto\_edx25519}} and
|
||
\href{https://git.taler.net/wallet-core.git/tree/packages/taler-util/src/talerCrypto.ts#n851}{namespace \texttt{Edx25519}}
|
||
\item high-level cryptographic primitives in
|
||
\href{https://git.taler.net/wallet-core.git/tree/packages/taler-util/src/talerCrypto.ts#n966}{namespace \texttt{AgeRestrictions}}
|
||
\item API changes to wallet-core RPC API in
|
||
\href{https://git.taler.net/wallet-core.git/tree/packages/taler-util/src/walletTypes.ts}{\texttt{restrictAge}}
|
||
\end{itemize}
|
||
Under \url{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/}
|
||
\begin{itemize}
|
||
\item withdrawal and refresh primitives in \href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/crypto/cryptoImplementation.ts}{\texttt{crypto/cryptoImplementation.ts}}
|
||
\item wallet database requests and HTTP requests in \\
|
||
\href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/db.ts}{\texttt{db.ts}},
|
||
\href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/operations/withdraw.ts}{\texttt{withdraw.ts}} and
|
||
\href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/operations/refresh.ts}{\texttt{refresh.ts}}
|
||
\item coin/denomination selection in
|
||
\href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/util/coinSelection.ts}{\texttt{util/coinSelection.ts}}
|
||
\end{itemize}
|
||
|
||
|
||
\item[Tests:] Under \url{https://git.taler.net/exchange.git/tree/src}:
|
||
\begin{itemize}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/util/test\_crypto.c}{util/test\_crypto.c}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/util/test\_age\_restriction.c}{util/test\_age\_restriction.c}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/util/tv\_age\_restriction.c}{util/tv\_age\_restriction.c}
|
||
\item \href{https://git.taler.net/exchange.git/tree/src/testing/test\_exchange\_api.c}{testing/test\_exchange\_api.c}
|
||
\end{itemize}
|
||
\end{description}
|
||
|
||
|
||
The definition of Edx25519, a variant of EdDSA that we designed for usage in
|
||
our age restriction scheme in GNU Taler, and its implementation is located at
|
||
\url{https://git.gnunet.org/gnunet.git/} in file
|
||
\href{https://git.gnunet.org/gnunet.git/tree/src/util/crypto\_edx25519.c}{util/crypto\_edx25519.c}.
|
||
|
||
}
|
||
|
||
|
||
|
||
\newpage
|
||
\section{P2P Payments}
|
||
|
||
We implemented two styles of P2P payments: \textbf{push payments} where a
|
||
user sends money to another Taler wallet (which can then accept the
|
||
payment), and \textbf{pull payments} where a user sends an invoice to
|
||
another Taler wallet (which can then pay the invoice).
|
||
|
||
Both styles of payment only require one asynchronous uni-directional
|
||
secure communication between the wallets to make the payment. The
|
||
information that is exchanged is in both cases a short \texttt{taler://}-URI
|
||
which allows the wallet to obtain further details from the payment service
|
||
provider. These further details include the contract/invoice that the payment
|
||
is for. The contract/invoice is stored encrypted at the exchange and thus
|
||
cannot be learned by the exchange.
|
||
|
||
The actual P2P payment works by having the initiator wallet first
|
||
communicate with the Taler exchange to setup the payment. Then the
|
||
Taler URI is communicated to the other wallet, for now usually via
|
||
QR code or NFC transmission; however, users could also copy the URI
|
||
to the clipboard and exchange it via some (secure) messenger. Upon
|
||
receiving the URI, the other wallet then again interacts with the
|
||
exchange to obtain more details and complete the payment.
|
||
|
||
If the recipient of a push payment does not accept the payment
|
||
(say because the message was lost in transmission, or they do not
|
||
like the attached contract terms) the money is automatically refunded
|
||
to the payer after some expiration date is reached.
|
||
|
||
\subsection{Technical details}
|
||
|
||
P2P payments always work by establishing a \textbf{purse} at the
|
||
exchange. A purse has an expiration date, target amount, minimum age,
|
||
associated business contract (or invoice), an actual balance and two
|
||
public-private key pairs representing permissions to operate on the
|
||
purse. For a push payment, the wallet of the sending user creates a
|
||
purse (with contract and expiration time) and immediately ensures that
|
||
the balance of the purse is the target amount. The payer then sends
|
||
the merge-capability key of the purse to the payee. The payee can
|
||
then use the merge-capability key to merge (move) the balance of the
|
||
purse into a KYC%
|
||
\footnote{KYC: Know-Your-Customer, a legally required procedure for customers
|
||
to identify themselves with the bank.}ed
|
||
reserve of the receiving wallet. A KYCed reserve basically is a long-term
|
||
public-private key pair that identifies a wallet and a user at an exchange,
|
||
ensuring income transparency. Once the money is in the reserve, the wallet can
|
||
then use the reserve private key to withdraw fresh coins.
|
||
|
||
When invoicing, the initiator again creates a purse, but this time
|
||
does not put any money into it and keeps the merge capability key
|
||
private. The initiator wallet instead immediately specifies its own
|
||
KYCed reserve as the one the purse should be merged into. The
|
||
initiator then shares a contract-download capability key with the
|
||
payer. The payer downloads the contract (including the purse public
|
||
key) and can then decide to put money into the purse. Once the purse
|
||
balance reaches the target amount, it is then automatically merged
|
||
with the initiator's reserve. The initiator's wallet (long) polls the
|
||
reserve and withdraws the funds as soon as they become available.
|
||
|
||
The protocol and implementation includes a few refinements, like fees
|
||
to be paid to the exchange for managing a purse and age-restrictions
|
||
on the coins used to pay an invoice.
|
||
|
||
\subsection{Future Work}
|
||
|
||
The following features (from tiny to major) have been discussed in
|
||
the team and ought to be implemented as part of future work.
|
||
|
||
\begin{itemize}
|
||
\item \textbf{Wallets:} The wallet UIs currently do not allow the user to actually specify
|
||
any age-restrictions on the payer when sending P2P pull payment requests
|
||
(invoicing). This mostly is about adding one more drop-down widget.
|
||
\item \textbf{Wallets:} The wallet UIs currently do not allow the user to actually specify
|
||
the expiration date for the purse. Instead, the duration is hard-coded
|
||
to a few hours (likely too short). This mostly is about adding one more
|
||
input field.
|
||
\item \textbf{Auditor:} The Taler auditor was extended to support P2P transactions in
|
||
its audits, but the code has not been adequately tested (no
|
||
fault injection).
|
||
\item \textbf{Exchange:} P2P payments currently only work if both wallets are using the
|
||
same exchange. If multiple exchanges operate in the same currency
|
||
domain and the recipient has made their (expensive) KYC process
|
||
at one exchange and the payer has withdrawn from the other, a
|
||
direct payment between the wallets is not possible right now. We
|
||
envision federation protocol using periodic aggregated
|
||
(``wad'') payments between exchanges should be added to support
|
||
P2P payments involing multiple exchanges in the future.
|
||
\item \textbf{Mailbox (NEW):} Currently, sending the payment URI is largely left to the user.
|
||
We would like to implement a ``mailbox'' service for Taler wallets
|
||
that would enable wallets to asynchronously exchange URIs over the
|
||
Internet. Once a wallet knows the mailbox address of another wallet
|
||
(which would include a public key to encrypt messages to), the user
|
||
would no longer be required to manually exchange the QR code.
|
||
\item \textbf{TalDir (NEW):} To lookup the mailbox address of another wallet, we would like
|
||
to implement a directory service that maps existing addresses like
|
||
e-mail addresses, phone numbers or accounts in messengers or social
|
||
media platforms to a mailbox. When establishing the directory service
|
||
entry, the directory service would validate that the user registering
|
||
the wallet has control over the respective address. Naturally, the
|
||
directory service would need to be trusted to return the correct
|
||
mapping.
|
||
\item Both the mailbox and the directory service operators could
|
||
themselves be paid via Taler for their service. That should help
|
||
ensure a high quality of service from those operators. Naturally,
|
||
using the mailbox or the directory service would be optional.
|
||
\item \textbf{Messaging:} In the long term, we would like to see more direct integration
|
||
of Taler payment functionality with messaging applications, especially
|
||
for spam prevention (``The recipient has configured its software to
|
||
demand a payment of 50 cents before displaying a message from an unknown
|
||
sender to the user. If they like your message, they promise they would
|
||
refund this attention fee. Do you want to pay to have your message
|
||
shown? (Y/N)'').
|
||
\end{itemize}
|
||
|
||
|
||
\subsection{Links}
|
||
|
||
\href{https://docs.taler.net/design-documents/013-peer-to-peer-payments.html}{Document
|
||
013} at \url{https://docs.taler.net/design-documents/} presents the design.
|
||
The main implementation parts for P2P are distributed over various code
|
||
locations under \url{https://git.taler.net/wallet-core.git/tree/packages/}
|
||
(wallet) and \url{https://git.taler.net/exchange.git/tree/src/exchange/}
|
||
(exchange):
|
||
\begin{description}
|
||
\item[Payment operations:] \href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/operations/pay-peer.ts}{taler-wallet-core/src/operations/pay-peer.ts}
|
||
\item[Database schema related:] \href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-core/src/db.ts#n2065}{taler-wallet-core/src/db.ts}
|
||
\item[Transaction list type declarations:] \href{https://git.taler.net/wallet-core.git/tree/packages/taler-util/src/transactions-types.ts#n251}{taler-util/src/transactions-types.ts}
|
||
\item[WebExtension UI:] \href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-webextension/src/cta/InvoiceCreate}{taler-wallet-webextension/src/cta/InvoiceCreate} and \href{https://git.taler.net/wallet-core.git/tree/packages/taler-wallet-webextension/src/cta/InvoicePay}{InvoicePay}
|
||
\item[Exchange] \url{https://git.taler.net/exchange.git/tree/src/exchange/},
|
||
specifically:\\
|
||
\texttt{taler-exchange-httpd\_purses\_*.c}, \texttt{taler-exchange-httpd\_reserves\_purse\_*.c},
|
||
\texttt{taler-exchange-httpd\_contract.*},
|
||
\texttt{taler-exchange-expire.c} (plus related changes in the database, client libraries, history, auditor),
|
||
and the main test case at
|
||
\href{https://git.taler.net/exchange.git/tree/src/testing/test\_exchange\_p2p.c}{testing/test\_exchange\_p2p.c}
|
||
\end{description}
|
||
|
||
|
||
|
||
|
||
\newpage
|
||
\section{Brandt-Vickrey Auctions}
|
||
|
||
\href{https://pub.dss.in.tum.de/brandt-research/ijis2006.pdf}{In 2006, Felix
|
||
Brandt} designed cryptographic Vickrey-style auction protocols that only yield
|
||
the winners’ identities and the selling price. Losing bidders learn no
|
||
information at all, except that they lost. This approach does not rely on
|
||
trusted third parties, e.g., auctioneers or---in our case---the payment service
|
||
provider.
|
||
\href{https://grothoff.org/christian/teich2017ms.pdf}{In 2017, Marcus Teich}
|
||
updated the cryptographic primitives in the Brandt-Vickrey protocols to use
|
||
elliptic curves and provided an implementation in
|
||
\url{https://git.gnunet.org/libbrandt.git/}.
|
||
|
||
Based on that work, we implemented a Proof-of-Concept for \textsc{NGI Pointer}
|
||
of conditional payments in GNU Taler in the form of sealed-bid auctions of type
|
||
Brandt-Vickrey:
|
||
|
||
Bidders put coins in escrow with the exchange in order to participate in a
|
||
particular auction. The coins are locked and can only be unlocked by timeout
|
||
or by winning the auction. After successfully running the Brandt-Vickrey
|
||
auction, the seller has to provide the transcript of all (signed) messages
|
||
received from all bidders. The exchange then replays the transcript and
|
||
determines the winning bidder(s) and price(s) and pays the seller accordingly.
|
||
Non-winning coins and rest amounts can be claimed by the bidders.
|
||
|
||
\subsection{Technical details}
|
||
|
||
We designed and implemented a general framework for conditional payments with
|
||
GNU Taler---so-called \textit{policies}. Our proof-of-concept of sealed-bid
|
||
auction support is implemented as an policy extension to GNU Taler. In
|
||
particular, we implemented the following parts:
|
||
|
||
\begin{description}
|
||
\item[Transcript generation:] \texttt{libbrandt} has been extended to
|
||
generate a transcript of the auction including all
|
||
cryptographically signed messages from all bidders in
|
||
JSON-encoding.
|
||
|
||
\item[Transcript replay:] An external program to replay a transcript
|
||
has been implemented as part of \texttt{libbrandt}. It
|
||
consumes transcript of an auction in JSON-encoding, generates
|
||
an Brandt-Vickrey-auction and replays all provided messages.
|
||
On success, it returns the winning bidder(s) and price(s)
|
||
according the transcript.
|
||
|
||
\item[Policy extension for auctions:] A policy extension for GNU Taler
|
||
has been implemented that handles deposit requests with set
|
||
policy of type \texttt{\small
|
||
policy\_brandt\_vickrey\_auction}. It locks the coins and
|
||
persists the policy details under a hash-code, that it
|
||
generates by calculating the hash $H(h_a || p_b)$, where $h_a$
|
||
is the hash of the auction meta data and $p_b$ is the public
|
||
key of the bidder. Both parameters are part of the policy
|
||
structure provided during a deposit.
|
||
|
||
\item[POST handler for auction transcripts:] A POST handler for the
|
||
policy extension of that type has been implemented that expects
|
||
a valid transcript of a Brandt-Vickrey-auction. It uses the
|
||
external program to perform a replay of the auction and
|
||
determine the winning bidder(s) and price(s). Based on the
|
||
outcome information, the exchange unlocks the corresponding
|
||
winning coins' value for transfer to the seller---minus an
|
||
auction fee---and the rest value of all coins for refresh.
|
||
|
||
\end{description}
|
||
|
||
|
||
\subsection{Future Works}
|
||
|
||
For a fully functional and maintainable solution, further development is needed
|
||
in the following areas:
|
||
|
||
\begin{description}
|
||
|
||
\item[libbrandt upgrade:] The code base of this library is from 2017 and doesn't
|
||
compile with the latest version of
|
||
\href{https://git.gnunet.org/gnunet.git}{GNUnet}. It also
|
||
uses \href{https://gnupg.org/software/libgcrypt/index.html}%
|
||
{\ttfamily libgcrypt} as cryptographic library, which is quite
|
||
slow compared to its modern alternative
|
||
\href{https://doc.libsodium.org/}{\ttfamily libsodium}, at
|
||
least with respect to the primitives used in libbrandt.
|
||
For future work we plan to refactor libbrandt to use libsodium
|
||
and the current version of GNUnet.
|
||
|
||
\item[Brandt-Vickrey-auction continuation:] The current code is a
|
||
proof-of-concept. The following known problem exist:
|
||
\begin{itemize}
|
||
\item Signature verification of the transcript and its messages
|
||
is missing
|
||
\item Unit- and integration-tests with the exchange are missing
|
||
\item A fully featured auction(er) system, including billboard
|
||
and client software, is missing.
|
||
\end{itemize}
|
||
|
||
We will address at least the first two issues and plan to
|
||
address the lack of an auction system once we find volunteers
|
||
and funding for it.
|
||
|
||
\item[Policy framework continuation:] Based on the current design of policy
|
||
extensions for deposit---aka conditional payments---we plan to add
|
||
following policy extensions to the GNU Taler exchange:
|
||
\begin{itemize}
|
||
\item{\itshape Merchant refunds:} Merchant can grant customers refundable
|
||
payments. Right now, this policy is implicit and optional in
|
||
the usual deposit-flow. Future work on Taler will lift
|
||
this into a policy-extension.
|
||
|
||
\item{\itshape Escrowed payments:} A trustor puts coins into escrow
|
||
with the exchange. It can be claimed by a beneficiary until a
|
||
certain deadline, when the claim is signed by
|
||
both, the beneficiary’s and the trustor’s keys.
|
||
\end{itemize}
|
||
|
||
\end{description}
|
||
|
||
\subsection{Links}
|
||
|
||
\begin{description}
|
||
\item[Changes to libbrandt:]
|
||
\href{https://git.kesim.org/oec/libbrandt/src/branch/transcript/test\_brandt.c}{\ttfamily test\_brandt.c}
|
||
has been extended to generate and print a transcript in JSON
|
||
encoding for each auction. The new file
|
||
\href{https://git.kesim.org/oec/libbrandt/src/branch/transcript/replay.c}{\ttfamily
|
||
replay.c} implements a standalone program to replay an auction.
|
||
\item[Changes to the Exchange:]
|
||
The changes to the exchange can be found at\\
|
||
\url{https://git.kesim.org/taler/exchange/src/branch/auction\_brandt/},\\
|
||
in particular:
|
||
\begin{description}
|
||
\item[\href{https://git.kesim.org/taler/exchange/src/branch/auction\_brandt/src/extensions/policy\_brandt\_vickrey\_auction/policy\_brandt\_vickrey\_auction.c\#L767-L821}{\ttfamily auction\_create\_policy\_details}]
|
||
This implements the {\ttfamily create\_policy\_details}
|
||
function of the policy extension interface.
|
||
|
||
\item[\href{https://git.kesim.org/taler/exchange/src/branch/auction\_brandt/src/extensions/policy\_brandt\_vickrey\_auction/policy\_brandt\_vickrey\_auction.c\#L694-L764}{\ttfamily auction\_policy\_post\_handler}]
|
||
This implements the {\ttfamily policy\_post\_handler} function
|
||
of the policy extension interface.
|
||
\end{description}
|
||
\end{description}
|
||
|
||
|
||
\newpage
|
||
\section{Usability Study}
|
||
|
||
For the \textsc{NGI Pointer} programme, the AP³ project team performed a
|
||
usability study to gather feedback and inform further development of the
|
||
age-restricted and P2P payment functionalities.
|
||
|
||
The BFH ``Digitaltag'' is an annual day-long event where the
|
||
university presents itself to the public. It is held right next to the
|
||
central train station of Biel/Bienne, and is open to the general
|
||
public. It was attended by a mixture of prospective students, normal
|
||
adults, Swiss executives and retirees.
|
||
|
||
We used the opportunity to both present GNU Taler to the public, and
|
||
to conduct usability studies with interested volunteers.
|
||
|
||
\begin{figure}[h!]
|
||
\includegraphics[width=\textwidth]{pics/b.jpg}
|
||
\caption{Our booth, with GNU Taler publications (including on
|
||
age-restrictions), NGI stickers, and a Taler-enabled coffee machine.}
|
||
\end{figure}
|
||
|
||
|
||
\subsection{Preparation}
|
||
|
||
We prepared several notebooks with a browser running a Taler wallet as
|
||
well as several Android phones with the Taler Android wallet. We
|
||
set up the coffee machine and three Taler backends, one for CHF (used
|
||
by the coffee machine), one for KUDOS (used with age-restrictions in
|
||
the browser-based setup) and one for Bitcoin (used for P2P payments).
|
||
We also prepared a rough write-up describing what we would like users
|
||
to do. These intended user stories are included in the appendix. We
|
||
note that during the day, we permitted participants to deviate from
|
||
the script if they desired to do so, sometimes leading them to explore
|
||
other GNU Taler features (and us learning interesting lessons about
|
||
those).
|
||
|
||
For the UX study, we prepared four tables: two tables with the coffee
|
||
machine and information materials, and two tables with additional
|
||
chairs for guests for the actual UX experiment.
|
||
|
||
\begin{figure}[h!]
|
||
\includegraphics[width=\textwidth]{pics/a.jpg}
|
||
\caption{Tables for the UX study with Prof. Benoist.}
|
||
\end{figure}
|
||
|
||
\subsection{Data collection}
|
||
|
||
We did not collect any PII on the participants.\footnote{Except for
|
||
one executive who had come just for our booth from Zug and who gave us
|
||
his business card as he hopes to collaborate with us in the future.}
|
||
Instead, each team member wrote down their observations. We
|
||
afterwards de-duplicated the observations and turned those that could
|
||
lead to improvements into over 20 new issues on the GNU Taler
|
||
bug-tracker (\#7334--\#7354).
|
||
|
||
\subsection{Key conclusions}
|
||
|
||
The day revealed the existence of several previously unknown bugs
|
||
(like refresh not working properly with the new features) as well
|
||
as quite a few surprising difficulties of users (not finding the
|
||
QR code button, not finding the account balance, not understanding
|
||
that the \texttt{shop.demo.taler.net} page is the shop where they should buy
|
||
things). We have made changes to GNU Taler in an attempt to rectify most of
|
||
these issues.
|
||
|
||
|
||
\end{document}
|