summaryrefslogtreecommitdiff
path: root/doc/anastasis.texi
diff options
context:
space:
mode:
Diffstat (limited to 'doc/anastasis.texi')
-rw-r--r--doc/anastasis.texi6093
1 files changed, 6093 insertions, 0 deletions
diff --git a/doc/anastasis.texi b/doc/anastasis.texi
new file mode 100644
index 0000000..a5d8b11
--- /dev/null
+++ b/doc/anastasis.texi
@@ -0,0 +1,6093 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename anastasis.info
+@documentencoding UTF-8
+@ifinfo
+@*Generated by Sphinx 3.4.3.@*
+@end ifinfo
+@settitle Anastasis Manual
+@defindex ge
+@paragraphindent 0
+@exampleindent 4
+@finalout
+@dircategory CATEGORY
+@direntry
+* MENU ENTRY: (anastasis.info). DESCRIPTION
+@end direntry
+
+@definfoenclose strong,`,'
+@definfoenclose emph,`,'
+@c %**end of header
+
+@copying
+@quotation
+GNU Anastasis 0.0.0, Jul 30, 2021
+
+Anastasis SARL
+
+Copyright @copyright{} 2020-2021 Anastasis SARL (AGPLv3+ or GFDL 1.3+)
+@end quotation
+
+@end copying
+
+@titlepage
+@title Anastasis Manual
+@insertcopying
+@end titlepage
+@contents
+
+@c %** start of user preamble
+
+@c %** end of user preamble
+
+@ifnottex
+@node Top
+@top Anastasis Manual
+@insertcopying
+@end ifnottex
+
+@c %**start of body
+@anchor{index doc}@anchor{0}
+@c This file is part of GNU Anastasis.
+@c Copyright (C) 2020-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+
+GNU Anastasis is Free Software protocol and implementation that allows
+users to securely deposit @strong{core secrets} with an open set of escrow
+providers and to recover these secrets if their original copies are
+lost.
+
+Anastasis is intended for users that want to make backups of key
+material, such as OpenPGP encryption keys, hard disk encryption keys
+or master keys of electronic wallets. Anastasis is NOT intended to
+store large amounts of secret data, it is only designed to safeguard
+key material.
+
+Anastasis solves the issue of keeping key material both available
+to the authorized user(s), and confidential from anyone else.
+
+With Anastasis, the @strong{core secrets} are protected from the Anastasis
+escrow providers by encrypting each with a @strong{master key}. The
+@strong{master key} can be split and distributed across the escrow
+providers to ensure that no single escrow provider can recover the
+@strong{master key} on its own. Which subset(s) of Anastasis providers
+must be contacted to recover a @strong{master key} is freely configurable.
+
+With Anastasis, users can reliably recover their @strong{core secret},
+while Anastasis makes this difficult for everyone else. This is even
+true if the user is unable to reliably remember any secret with
+sufficiently high entropy: Anastasis does not simply reduce the
+problem to encrypting the @strong{core secret} using some other key
+material in possession of the user.
+
+@menu
+* Documentation Overview::
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Documentation Overview
+
+* Introduction::
+* Installation::
+* Configuration::
+* Cryptography::
+* REST API::
+* Reducer API::
+* Authentication Methods::
+* DB Schema::
+* Design Documents::
+* Anastasis licensing information::
+* Man Pages::
+* Complete Index::
+* GNU Free Documentation License::
+
+Introduction
+
+* User Identifiers::
+* Adversary models::
+* The recovery document::
+
+Installation
+
+* Installing from source::
+* Installing Anastasis binary packages on Debian::
+* Installing Anastasis binary packages on Ubuntu::
+
+Installing from source
+
+* Installing GNUnet::
+* Installing the Taler Exchange::
+* Installing the Taler Merchant::
+* Installing Anastasis::
+* Installing GNUnet-gtk::
+* Installing Anastasis-gtk::
+
+Installing Anastasis binary packages on Debian
+
+* Installing the graphical front-end::
+* Installing the backend::
+
+Installing Anastasis binary packages on Ubuntu
+
+* Installing the graphical front-end: Installing the graphical front-end<2>.
+* Installing the backend: Installing the backend<2>.
+
+Configuration
+
+* Configuration format::
+* Using anastasis-config::
+
+Cryptography
+
+* Key derivations::
+* Key Usage::
+* Availability Considerations::
+
+Key derivations
+
+* Verification::
+* Encryption::
+
+Key Usage
+
+* Encryption: Encryption<2>.
+* Signatures::
+
+REST API
+
+* HTTP Request and Response::
+* Protocol Version Ranges::
+* Common encodings::
+
+Common encodings
+
+* Binary Data::
+* Hash codes::
+* Large numbers::
+* Timestamps::
+* Integers::
+* Objects::
+* Keys::
+* Signatures: Signatures<2>.
+* Amounts::
+* Time::
+* Cryptographic primitives::
+* Signatures: Signatures<3>.
+* Receiving Configuration::
+* Receiving Terms of Service::
+* Manage policy::
+* Managing truth::
+
+Reducer API
+
+* States::
+* Backup Reducer::
+* Recovery Reducer::
+* Reducer transitions::
+
+Reducer transitions
+
+* Initial state::
+* Common transitions::
+* Backup transitions::
+* Recovery transitions::
+
+Authentication Methods
+
+* SMS (sms): SMS sms.
+* Email verification (email): Email verification email.
+* Video identification (vid): Video identification vid.
+* Security question (qa): Security question qa.
+* Snail mail verification (post): Snail mail verification post.
+
+Design Documents
+
+* Design Doc 001; Anastasis User Experience: Design Doc 001 Anastasis User Experience.
+* Template::
+
+Design Doc 001: Anastasis User Experience
+
+* Summary::
+* Motivation::
+* Setup Steps::
+* Show Service Status After Setup::
+* Recovery Steps::
+
+Setup Steps
+
+* Entry point; Settings: Entry point Settings.
+* Providing Identification::
+* Add Authentication Methods::
+* Confirm/Change Service Providers::
+* Defining Recovery Options::
+* Pay for Setup::
+
+Recovery Steps
+
+* Entry point; Settings: Entry point Settings<2>.
+* Providing Identification: Providing Identification<2>.
+* Select Authentication Challenge::
+* Payment::
+* Enter Challenge Response::
+* Success::
+
+Template
+
+* Summary: Summary<2>.
+* Motivation: Motivation<2>.
+* Requirements::
+* Proposed Solution::
+* Alternatives::
+* Drawbacks::
+* Discussion / Q&A::
+
+Anastasis licensing information
+
+* Anastasis (git;//git.taler.net/anastasis): Anastasis git //git taler net/anastasis.
+* Anastasis-gtk (git;//git.taler.net/anastasis-gtk): Anastasis-gtk git //git taler net/anastasis-gtk.
+* Documentation::
+
+Anastasis (git://git.taler.net/anastasis)
+
+* Runtime dependencies::
+
+Anastasis-gtk (git://git.taler.net/anastasis-gtk)
+
+* Runtime dependencies: Runtime dependencies<2>.
+
+Man Pages
+
+* anastasis-config(1): anastasis-config 1.
+* anastasis-gtk(1): anastasis-gtk 1.
+* anastasis-httpd(1): anastasis-httpd 1.
+* anastasis-reducer(1): anastasis-reducer 1.
+* anastasis.conf(5): anastasis conf 5.
+
+anastasis-config(1)
+
+* Synopsis::
+* Description::
+* See Also::
+* Bugs::
+
+anastasis-gtk(1)
+
+* Synopsis: Synopsis<2>.
+* Description: Description<2>.
+* See Also: See Also<2>.
+* Bugs: Bugs<2>.
+
+anastasis-httpd(1)
+
+* Synopsis: Synopsis<3>.
+* Description: Description<3>.
+* Signals::
+* See also::
+* Bugs: Bugs<3>.
+
+anastasis-reducer(1)
+
+* Synopsis: Synopsis<4>.
+* Description: Description<4>.
+* See Also: See Also<3>.
+* Bugs: Bugs<4>.
+
+anastasis.conf(5)
+
+* Description: Description<5>.
+* SEE ALSO::
+* BUGS::
+
+Description
+
+* GLOBAL OPTIONS::
+* Authorization options::
+* Postgres database configuration::
+
+GNU Free Documentation License
+
+* 0. PREAMBLE: 0 PREAMBLE.
+* 1. APPLICABILITY AND DEFINITIONS: 1 APPLICABILITY AND DEFINITIONS.
+* 2. VERBATIM COPYING: 2 VERBATIM COPYING.
+* 3. COPYING IN QUANTITY: 3 COPYING IN QUANTITY.
+* 4. MODIFICATIONS: 4 MODIFICATIONS.
+* 5. COMBINING DOCUMENTS: 5 COMBINING DOCUMENTS.
+* 6. COLLECTIONS OF DOCUMENTS: 6 COLLECTIONS OF DOCUMENTS.
+* 7. AGGREGATION WITH INDEPENDENT WORKS: 7 AGGREGATION WITH INDEPENDENT WORKS.
+* 8. TRANSLATION: 8 TRANSLATION.
+* 9. TERMINATION: 9 TERMINATION.
+* 10. FUTURE REVISIONS OF THIS LICENSE: 10 FUTURE REVISIONS OF THIS LICENSE.
+* 11. RELICENSING: 11 RELICENSING.
+* ADDENDUM; How to use this License for your documents: ADDENDUM How to use this License for your documents.
+
+@end detailmenu
+@end menu
+
+@node Documentation Overview,,Top,Top
+@anchor{index anastasis-documentation}@anchor{1}@anchor{index documentation-overview}@anchor{2}
+@chapter Documentation Overview
+
+
+@c This file is part of Anastasis
+@c Copyright (C) 2019-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+@c @author Dominik Meister
+@c @author Dennis Neufeld
+
+@menu
+* Introduction::
+* Installation::
+* Configuration::
+* Cryptography::
+* REST API::
+* Reducer API::
+* Authentication Methods::
+* DB Schema::
+* Design Documents::
+* Anastasis licensing information::
+* Man Pages::
+* Complete Index::
+* GNU Free Documentation License::
+
+@end menu
+
+@node Introduction,Installation,,Documentation Overview
+@anchor{introduction doc}@anchor{3}@anchor{introduction introduction}@anchor{4}
+@section Introduction
+
+
+To understand how Anastasis works, you need to understand three key
+concepts: user identifiers, our adversary model and the role of the
+recovery document.
+
+@menu
+* User Identifiers::
+* Adversary models::
+* The recovery document::
+
+@end menu
+
+@node User Identifiers,Adversary models,,Introduction
+@anchor{introduction user-identifiers}@anchor{5}
+@subsection User Identifiers
+
+
+To uniquely identify users, an “unforgettable” @strong{identifier} is used. This
+identifier should be difficult to guess for anybody but the user. However, the
+@strong{identifier} is not expected to have sufficient entropy or secrecy to be
+cryptographically secure. Examples for such identifier would be a
+concatenation of the full name of the user and their social security or
+passport number(s). For Swiss citizens, the AHV number could also be used.
+
+@node Adversary models,The recovery document,User Identifiers,Introduction
+@anchor{introduction adversary-models}@anchor{6}
+@subsection Adversary models
+
+
+The adversary model of Anastasis has two types of adversaries: weak
+adversaries which do not know the user’s @strong{identifier}, and strong
+adversaries which somehow do know a user’s @strong{identifier}. For weak
+adversaries the system guarantees full confidentiality. For strong
+adversaries, breaking confidentiality additionally requires that Anastasis
+escrow providers must have colluded. The user is able to specify a set of
+@strong{policies} which determine which Anastasis escrow providers would need to
+collude to break confidentiality. These policies also set the bar for the user
+to recover their core secret.
+
+@node The recovery document,,Adversary models,Introduction
+@anchor{introduction the-recovery-document}@anchor{7}
+@subsection The recovery document
+
+
+A @strong{recovery document} includes all of the information a user needs to
+recover access to their core secret. It specifies a set of @strong{escrow
+methods}, which specify how the user should convince the Anastasis server
+that they are “real”. Escrow methods can for example include SMS-based
+verification, video identification or a security question. For each escrow
+method, the Anastasis server is provided with @strong{truth}, that is data the
+Anastasis operator may learn during the recovery process to authenticate the
+user. Examples for truth would be a phone number (for SMS), a picture of the
+user (for video identification), or the (hash of) a security answer. A strong
+adversary is assumed to be able to learn the truth, while weak adversaries
+must not. In addition to a set of escrow methods and associated Anastasis
+server operators, the @strong{recovery document} also specifies @strong{policies}, which
+describe the combination(s) of the escrow methods that suffice to obtain
+access to the core secret. For example, a @strong{policy} could say that the
+escrow methods (A and B) suffice, and a second policy may permit (A and C). A
+different user may choose to use the policy that (A and B and C) are all
+required. Anastasis imposes no limit on the number of policies in a
+@strong{recovery document}, or the set of providers or escrow methods involved in
+guarding a user’s secret. Weak adversaries must not be able to deduce
+information about a user’s @strong{recovery document} (except for its length, which
+may be exposed to an adversary which monitors the user’s network traffic).
+
+@c This file is part of Anastasis
+@c Copyright (C) 2019-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+@c @author Dominik Meister
+@c @author Dennis Neufeld
+
+@node Installation,Configuration,Introduction,Documentation Overview
+@anchor{installation doc}@anchor{8}@anchor{installation installation}@anchor{9}
+@section Installation
+
+
+Please install the following packages before proceeding with the
+exchange compilation.
+
+
+@itemize -
+
+@item
+libsqlite3 >= 3.16.2
+
+@item
+GNU libunistring >= 0.9.3
+
+@item
+libcurl >= 7.26 (or libgnurl >= 7.26)
+
+@item
+libqrencode >= 4.0.0
+
+@item
+GNU libgcrypt >= 1.6
+
+@item
+libsodium >= 1.0
+
+@item
+libargon2 >= 20171227
+
+@item
+libjansson >= 2.7
+
+@item
+Postgres >= 9.6, including libpq
+
+@item
+GNU libmicrohttpd >= 0.9.71
+
+@item
+GNUnet >= 0.14.0 (from source tarball@footnote{http://ftpmirror.gnu.org/gnunet/})
+
+@item
+GNU Taler exchange
+
+@item
+GNU Taler merchant backend
+@end itemize
+
+Except for the last two, these are available in most GNU/Linux distributions
+and should just be installed using the respective package manager.
+
+@menu
+* Installing from source::
+* Installing Anastasis binary packages on Debian::
+* Installing Anastasis binary packages on Ubuntu::
+
+@end menu
+
+@node Installing from source,Installing Anastasis binary packages on Debian,,Installation
+@anchor{installation installing-from-source}@anchor{a}
+@subsection Installing from source
+
+
+The following instructions will show how to install libgnunetutil and
+the GNU Taler exchange from source.
+
+@menu
+* Installing GNUnet::
+* Installing the Taler Exchange::
+* Installing the Taler Merchant::
+* Installing Anastasis::
+* Installing GNUnet-gtk::
+* Installing Anastasis-gtk::
+
+@end menu
+
+@node Installing GNUnet,Installing the Taler Exchange,,Installing from source
+@anchor{installation installing-gnunet}@anchor{b}
+@subsubsection Installing GNUnet
+
+
+Before you install GNUnet, you must download and install the dependencies
+mentioned in the previous section, otherwise the build may succeed, but could
+fail to export some of the tooling required by GNU Taler.
+
+To install GNUnet, unpack the tarball and change
+into the resulting directory, then proceed as follows:
+
+@example
+$ ./configure [--prefix=GNUNETPFX]
+$ # Each dependency can be fetched from non standard locations via
+$ # the '--with-<LIBNAME>' option. See './configure --help'.
+$ make
+# make install
+# ldconfig
+@end example
+
+If you did not specify a prefix, GNUnet will install to @code{/usr/local},
+which requires you to run the last step as @code{root}.
+The @code{ldconfig} command (also run as @code{root}) makes the
+shared object libraries (@code{.so} files)
+visible to the various installed programs.
+
+@node Installing the Taler Exchange,Installing the Taler Merchant,Installing GNUnet,Installing from source
+@anchor{installation installing-the-taler-exchange}@anchor{c}
+@subsubsection Installing the Taler Exchange
+
+
+After installing GNUnet, unpack the GNU Taler exchange tarball,
+change into the resulting directory, and proceed as follows:
+
+@example
+$ ./configure [--prefix=EXCHANGEPFX] \
+ [--with-gnunet=GNUNETPFX]
+$ # Each dependency can be fetched from non standard locations via
+$ # the '--with-<LIBNAME>' option. See './configure --help'.
+$ make
+# make install
+@end example
+
+If you did not specify a prefix, the exchange will install to @code{/usr/local},
+which requires you to run the last step as @code{root}. You have to specify
+@code{--with-gnunet=/usr/local} if you installed GNUnet to @code{/usr/local} in the
+previous step.
+
+@node Installing the Taler Merchant,Installing Anastasis,Installing the Taler Exchange,Installing from source
+@anchor{installation installing-the-taler-merchant}@anchor{d}
+@subsubsection Installing the Taler Merchant
+
+
+GNU Taler merchant has these additional dependencies:
+
+
+@itemize -
+
+@item
+libqrencode >= 4.0.0
+@end itemize
+
+The following steps assume all dependencies are installed.
+
+First, unpack the GNU Taler merchant tarball and change into
+the resulting directory.
+Then, use the following commands to build and install the merchant backend:
+
+@example
+$ ./configure [--prefix=PFX] \
+ [--with-gnunet=GNUNETPFX] \
+ [--with-exchange=EXCHANGEPFX]
+$ # Each dependency can be fetched from non standard locations via
+$ # the '--with-<LIBNAME>' option. See './configure --help'.
+$ make
+# make install
+@end example
+
+If you did not specify a prefix, the exchange will install to
+@code{/usr/local}, which requires you to run the last step as @code{root}.
+
+You have to specify @code{--with-exchange=/usr/local} and/or
+@code{--with-gnunet=/usr/local} if you installed the exchange and/or
+GNUnet to @code{/usr/local} in the previous steps.
+
+Depending on the prefixes you specified for the installation and the
+distribution you are using, you may have to edit @code{/etc/ld.so.conf}, adding
+lines for @code{GNUNETPFX/lib/} and @code{EXCHANGEPFX/lib/} and @code{PFX/lib/}
+(replace the prefixes with the actual paths you used). Afterwards, you should
+run @code{ldconfig}. Without this step, it is possible that the linker may not
+find the installed libraries and launching the Taler merchant backend would
+then fail.
+
+@node Installing Anastasis,Installing GNUnet-gtk,Installing the Taler Merchant,Installing from source
+@anchor{installation installing-anastasis}@anchor{e}
+@subsubsection Installing Anastasis
+
+
+The following steps assume all dependencies are installed.
+
+First, unpack the Anastasis tarball and change into
+the resulting directory.
+Then, use the following commands to build and install Anastasis:
+
+@example
+$ ./configure [--prefix=PFX] \
+ [--with-gnunet=GNUNETPFX] \
+ [--with-exchange=EXCHANGEPFX]
+$ # Each dependency can be fetched from non standard locations via
+$ # the '--with-<LIBNAME>' option. See './configure --help'.
+$ make
+# make install
+@end example
+
+If you did not specify a prefix, Anastasis will be installed to
+@code{/usr/local}, which requires you to run the last step as @code{root}.
+
+You have to specify @code{--with-exchange=/usr/local} and/or
+@code{--with-gnunet=/usr/local} if you installed the exchange and/or
+GNUnet to @code{/usr/local} in the previous steps.
+
+Depending on the prefixes you specified for the installation and the
+distribution you are using, you may have to edit @code{/etc/ld.so.conf}, adding
+lines for @code{GNUNETPFX/lib/} and @code{EXCHANGEPFX/lib/} and @code{PFX/lib/}
+(replace the prefixes with the actual paths you used). Afterwards, you should
+run @code{ldconfig}. Without this step, it is possible that the linker may not
+find the installed libraries and launching the Anastasis backend would
+then fail.
+
+@node Installing GNUnet-gtk,Installing Anastasis-gtk,Installing Anastasis,Installing from source
+@anchor{installation installing-gnunet-gtk}@anchor{f}
+@subsubsection Installing GNUnet-gtk
+
+
+The following steps assume at least the GNUnet and Gtk+ dependencies are installed.
+
+First, unpack the gnunet-gtk tarball and change into the resulting directory.
+Then, use the following commands to build and install gnunet-gtk:
+
+@example
+$ ./configure [--prefix=$PFX] \
+ [--with-gnunet=$GNUNETPFX]
+$ # Each dependency can be fetched from non standard locations via
+$ # the '--with-<LIBNAME>' option. See './configure --help'.
+$ make
+# make install
+@end example
+
+It is highly recommended to use the same prefix ($PFX) for gnunet-gtk that was
+used for GNUnet ($GNUNETPFX). If you did not specify a prefix, gnunet-gtk
+will be installed to @code{/usr/local}, which requires you to run the last step
+as @code{root}.
+
+You have to specify @code{--with-gnunet=/usr/local} if you installed
+GNUnet to @code{/usr/local} in the previous steps.
+
+Depending on the prefixes you specified for the installation and the
+distribution you are using, you may have to edit @code{/etc/ld.so.conf}, adding
+lines for @code{$GNUNETPFX/lib/} and @code{$PFX/lib/} (replace the prefixes with the
+actual paths you used). Afterwards, you should run @code{ldconfig}. Without this
+step, it is possible that the linker may not find the installed libraries and
+launching gnunet-gtk would then fail.
+
+@node Installing Anastasis-gtk,,Installing GNUnet-gtk,Installing from source
+@anchor{installation installing-anastasis-gtk}@anchor{10}
+@subsubsection Installing Anastasis-gtk
+
+
+The following steps assume at least the GNUnet, gnunet-gtk and Anastasis
+dependencies are installed.
+
+First, unpack the anastasis-gtk tarball and change into the resulting
+directory. Then, use the following commands to build and install
+anastasis-gtk:
+
+@example
+$ ./configure [--prefix=PFX] \
+ [--with-gnunet=GNUNETPFX] \
+ [--with-exchange=EXCHANGEPFX] \
+ [--with-anastasis=ANASTASISPFX]
+$ # Each dependency can be fetched from non standard locations via
+$ # the '--with-<LIBNAME>' option. See './configure --help'.
+$ make
+# make install
+@end example
+
+If you did not specify a prefix, anastasis-gtk will be installed to
+@code{/usr/local}, which requires you to run the last step as @code{root}.
+
+You have to specify @code{-with-anastasis=/usr/local}, @code{--with-exchange=/usr/local} and/or
+@code{--with-gnunet=/usr/local} if you installed the exchange and/or
+GNUnet to @code{/usr/local} in the previous steps.
+
+Depending on the prefixes you specified for the installation and the
+distribution you are using, you may have to edit @code{/etc/ld.so.conf}, adding
+lines for @code{GNUNETPFX/lib/} and @code{EXCHANGEPFX/lib/} and @code{PFX/lib/}
+(replace the prefixes with the actual paths you used). Afterwards, you should
+run @code{ldconfig}. Without this step, it is possible that the linker may not
+find the installed libraries and launching anastasis-gtk would then fail.
+
+@node Installing Anastasis binary packages on Debian,Installing Anastasis binary packages on Ubuntu,Installing from source,Installation
+@anchor{installation installing-anastasis-binary-packages-on-debian}@anchor{11}
+@subsection Installing Anastasis binary packages on Debian
+
+
+To install the GNU Taler Debian packages, first ensure that you have
+the right Debian distribution. At this time, the packages are built for
+Sid, which means you should use a system which at least includes
+unstable packages in its source list. We recommend using APT pinning
+to limit unstable packages to those explicitly requested. To do this,
+set your @code{/etc/apt/preferences} as follows:
+
+@example
+Package: *
+Pin: release a=stable
+Pin-Priority: 700
+
+Package: *
+Pin: release a=testing
+Pin-Priority: 650
+
+Package: *
+Pin: release a=unstable
+Pin-Priority: 600
+
+Package: *
+Pin: release l=Debian-Security
+Pin-Priority: 1000
+@end example
+
+A typical @code{/etc/apt/sources.list} file for this setup
+which combines Debian stable with more recent packages
+from testing and unstable would look like this:
+
+@example
+deb http://ftp.ch.debian.org/debian/ buster main
+deb http://security.debian.org/debian-security buster/updates main
+deb http://ftp.ch.debian.org/debian/ testing main
+deb http://ftp.ch.debian.org/debian/ unstable main
+@end example
+
+Naturally, you may want to use different mirrors depending on your region.
+Additionally, you must add a file to import the GNU Taler packages. Typically,
+this is done by adding a file @code{/etc/apt/sources.list.d/taler.list} that
+looks like this:
+
+@example
+deb https://deb.taler.net/apt/debian sid main
+@end example
+
+Next, you must import the Taler Systems SA public package signing key
+into your keyring and update the package lists:
+
+@example
+# wget -O - https://taler.net/taler-systems.gpg.key | apt-key add -
+# apt update
+@end example
+
+@cartouche
+@quotation Note
+You may want to verify the correctness of the Taler Systems key out-of-band.
+@end quotation
+@end cartouche
+
+Now your system is ready to install the official GNU Taler binary packages
+using apt.
+
+@menu
+* Installing the graphical front-end::
+* Installing the backend::
+
+@end menu
+
+@node Installing the graphical front-end,Installing the backend,,Installing Anastasis binary packages on Debian
+@anchor{installation installing-the-graphical-front-end}@anchor{12}
+@subsubsection Installing the graphical front-end
+
+
+To install the Anastasis Gtk+ frontend, you can simply run:
+
+@example
+# apt install anastasis-gtk
+@end example
+
+To use @code{anastasis-gtk}, you can simply run:
+
+@example
+$ anastasis-gtk
+@end example
+
+@node Installing the backend,,Installing the graphical front-end,Installing Anastasis binary packages on Debian
+@anchor{installation installing-the-backend}@anchor{13}
+@subsubsection Installing the backend
+
+
+If you want to install the Anastasis backend-end (which normal users do not
+need), you should run:
+
+@example
+# apt install -t sid anastasis-httpd
+@end example
+
+Note that the latter package does not perform all of the configuration work.
+It does setup the user users and the systemd service scripts, but you still
+must configure the database backup, HTTP reverse proxy (typically with TLS
+certificates), Taler merchant backend for payments, authentication services,
+prices and the terms of service.
+
+Sample configuration files for the HTTP reverse proxy can be found in
+@code{/etc/anastasis.conf}.
+
+Note that the package does not complete the integration of the backend
+with the HTTP reverse proxy (typically with TLS certificates). A
+configuration fragment for Nginx or Apache will be placed in
+@code{/etc/@{apache,nginx@}/conf-available/anastasis.conf}.
+
+To operate an Anastasis backend with payments, you additionally
+need to install a Taler merchant backend via:
+
+@example
+# apt install -t sid taler-merchant-httpd
+@end example
+
+@node Installing Anastasis binary packages on Ubuntu,,Installing Anastasis binary packages on Debian,Installation
+@anchor{installation installing-anastasis-binary-packages-on-ubuntu}@anchor{14}
+@subsection Installing Anastasis binary packages on Ubuntu
+
+
+To install the GNU Taler Ubuntu packages, first ensure that you have
+the right Ubuntu distribution. At this time, the packages are built for
+Ubuntu 20.04 LTS (Focal Fossa).
+
+A typical @code{/etc/apt/sources.list.d/taler.list} file for this setup
+would look like this:
+
+@example
+deb https://deb.taler.net/apt/ubuntu/ focal-fossa main
+@end example
+
+The last line is crucial, as it adds the GNU Taler packages.
+
+Next, you must import the Taler Systems SA public package signing key
+into your keyring and update the package lists:
+
+@example
+# wget -O - https://taler.net/taler-systems.gpg.key | apt-key add -
+# apt update
+@end example
+
+@cartouche
+@quotation Note
+You may want to verify the correctness of the Taler Systems key out-of-band.
+@end quotation
+@end cartouche
+
+Now your system is ready to install the official GNU Taler binary packages
+using apt.
+
+@menu
+* Installing the graphical front-end: Installing the graphical front-end<2>.
+* Installing the backend: Installing the backend<2>.
+
+@end menu
+
+@node Installing the graphical front-end<2>,Installing the backend<2>,,Installing Anastasis binary packages on Ubuntu
+@anchor{installation id1}@anchor{15}
+@subsubsection Installing the graphical front-end
+
+
+To install the Anastasis front-end, you can now simply run:
+
+@example
+# apt install -t focal-fossa anastasis-gtk
+@end example
+
+To use @code{anastasis-gtk}, you can simply run:
+
+@example
+$ anastasis-gtk
+@end example
+
+@node Installing the backend<2>,,Installing the graphical front-end<2>,Installing Anastasis binary packages on Ubuntu
+@anchor{installation id2}@anchor{16}
+@subsubsection Installing the backend
+
+
+If you want to install the Anastasis backend-end (which normal users do not
+need), you should run:
+
+@example
+# apt install -t focal-fossa anastasis-httpd
+@end example
+
+Note that the latter package does not perform all of the configuration work.
+It does setup the user users and the systemd service scripts, but you still
+must configure the database backup, HTTP reverse proxy (typically with TLS
+certificates), Taler merchant backend for payments, authentication services,
+prices and the terms of service.
+
+Sample configuration files for the HTTP reverse proxy can be found in
+@code{/etc/anastasis.conf}.
+
+To operate an Anastasis backend with payments, you additionally
+need to install a Taler merchant backend via:
+
+@example
+# apt install -t sid taler-merchant-httpd
+@end example
+
+@c This file is part of Anastasis
+@c Copyright (C) 2019-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+@c @author Dominik Meister
+@c @author Dennis Neufeld
+
+@node Configuration,Cryptography,Installation,Documentation Overview
+@anchor{configuration doc}@anchor{17}@anchor{configuration configuration}@anchor{18}
+@section Configuration
+
+
+Details about the contents of the configuration file are describe in
+the @code{anastasis.conf(5)} chapter. This chapter only describes the
+configuration format.
+
+@menu
+* Configuration format::
+* Using anastasis-config::
+
+@end menu
+
+@node Configuration format,Using anastasis-config,,Configuration
+@anchor{configuration configuration-format}@anchor{19}
+@subsection Configuration format
+
+
+In Taler realm, any component obeys to the same pattern to get
+configuration values. According to this pattern, once the component has
+been installed, the installation deploys default values in
+$@{prefix@}/share/taler/config.d/, in .conf files. In order to override
+these defaults, the user can write a custom .conf file and either pass
+it to the component at execution time, or name it taler.conf and place
+it under $HOME/.config/.
+
+A config file is a text file containing sections, and each section
+contains its values. The right format follows:
+
+@example
+[section1]
+value1 = string
+value2 = 23
+
+[section2]
+value21 = string
+value22 = /path22
+@end example
+
+Throughout any configuration file, it is possible to use @code{$}-prefixed
+variables, like @code{$VAR}, especially when they represent filesystem
+paths. It is also possible to provide defaults values for those
+variables that are unset, by using the following syntax:
+@code{$@{VAR:-default@}}. However, there are two ways a user can set
+@code{$}-prefixable variables:
+
+by defining them under a @code{[paths]} section, see example below,
+
+@example
+[paths]
+TALER_DEPLOYMENT_SHARED = $@{HOME@}/shared-data
+..
+[section-x]
+path-x = $@{TALER_DEPLOYMENT_SHARED@}/x
+@end example
+
+or by setting them in the environment:
+
+@example
+$ export VAR=/x
+@end example
+
+The configuration loader will give precedence to variables set under
+@code{[path]}, though.
+
+The utility @code{taler-config}, which gets installed along with the
+exchange, serves to get and set configuration values without directly
+editing the .conf. The option @code{-f} is particularly useful to resolve
+pathnames, when they use several levels of @code{$}-expanded variables. See
+@code{taler-config --help}.
+
+Note that, in this stage of development, the file
+@code{$HOME/.config/taler.conf} can contain sections for @emph{all} the
+component. For example, both an exchange and a bank can read values from
+it.
+
+The repository @code{git://taler.net/deployment} contains examples of
+configuration file used in our demos. See under @code{deployment/config}.
+
+@quotation
+
+@strong{Note}
+
+Expectably, some components will not work just by using default
+values, as their work is often interdependent. For example, a
+merchant needs to know an exchange URL, or a database name.
+@end quotation
+
+@node Using anastasis-config,,Configuration format,Configuration
+@anchor{configuration using-anastasis-config}@anchor{1a}
+@subsection Using anastasis-config
+
+
+The tool @code{anastasis-config} can be used to extract or manipulate
+configuration values; however, the configuration use the well-known INI
+file format and can also be edited by hand.
+
+Run
+
+@example
+$ anastasis-config -s $SECTION
+@end example
+
+to list all of the configuration values in section @code{$SECTION}.
+
+Run
+
+@example
+$ anastasis-config -s $section -o $option
+@end example
+
+to extract the respective configuration value for option @code{$option} in
+section @code{$section}.
+
+Finally, to change a setting, run
+
+@example
+$ anastasis-config -s $section -o $option -V $value
+@end example
+
+to set the respective configuration value to @code{$value}. Note that you
+have to manually restart the Taler backend after you change the
+configuration to make the new configuration go into effect.
+
+Some default options will use $-variables, such as @code{$DATADIR} within
+their value. To expand the @code{$DATADIR} or other $-variables in the
+configuration, pass the @code{-f} option to @code{anastasis-config}. For example,
+compare:
+
+@example
+$ anastasis-config -s ACCOUNT-bank \
+ -o WIRE_RESPONSE
+$ anastasis-config -f -s ACCOUNT-bank \
+ -o WIRE_RESPONSE
+@end example
+
+While the configuration file is typically located at
+@code{$HOME/.config/taler.conf}, an alternative location can be specified
+to @code{taler-merchant-httpd} and @code{anastasis-config} using the @code{-c}
+option.
+
+@c This file is part of Anastasis
+@c Copyright (C) 2019-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+@c @author Dominik Meister
+@c @author Dennis Neufeld
+
+@node Cryptography,REST API,Configuration,Documentation Overview
+@anchor{cryptography doc}@anchor{1b}@anchor{cryptography cryptography}@anchor{1c}
+@section Cryptography
+
+
+When a user needs to interact with Anastasis, the system first derives some key
+material, but not the master secret, from the user’s @strong{identifier} using
+different HKDFs. These HKDFs are salted using the respective escrow
+provider’s @strong{server salt}, which ensures that the accounts for the same user
+cannot be easily correlated across the various Anastasis servers.
+
+Each Anastasis server uses an EdDSA @strong{account key} to identify the account of
+the user. The account private key is derived from the user’s @strong{identifier} using
+a computationally expensive cryptographic hash function. Using an
+expensive hash algorithm is assumed to make it infeasible for a weak adversary to
+determine account keys by brute force (without knowing the user’s identifier).
+However, it is assumed that a strong adversary performing a targeted attack can
+compute the account key pair.
+
+The public account key is Crockford base32-encoded in the URI to identify the
+account, and used to sign requests. These signatures are also provided in
+base32-encoding and transmitted using the HTTP header
+@code{Anastasis-Account-Signature}.
+
+When confidential data is uploaded to an Anastasis server, the respective
+payload is encrypted using AES-GCM with a symmetric key and initialization
+vector derived from the @strong{identifier} and a high-entropy @strong{nonce}. The
+nonce and the GCM tag are prepended to the ciphertext before being uploaded to
+the Anastasis server. This is done whenever confidential data is stored with
+the server.
+
+The @strong{core secret} of the user is (AES) encrypted using a symmetric @strong{master
+key}. Recovering this master key requires the user to satisfy a particular
+@strong{policy}. Policies specify a set of @strong{escrow methods}, each of which leads
+the user to a @strong{key share}. Combining those key shares (by hashing) allows
+the user to obtain a @strong{policy key}, which can be used to decrypt the @strong{master
+key}. There can be many policies, satisfying any of these will allow the
+user to recover the master key. A @strong{recovery document} contains the
+encrypted @strong{core secret}, a set of escrow methods and a set of policies.
+
+@menu
+* Key derivations::
+* Key Usage::
+* Availability Considerations::
+
+@end menu
+
+@node Key derivations,Key Usage,,Cryptography
+@anchor{cryptography key-derivations}@anchor{1d}
+@subsection Key derivations
+
+
+EdDSA and ECDHE public keys are always points on Curve25519 and represented
+using the standard 256 bit Ed25519 compact format. The binary representation
+is converted to Crockford Base32 when transmitted inside JSON or as part of
+URLs.
+
+To start, a user provides their private, unique and unforgettable
+@strong{identifier} as a seed to identify their account. For example, this could
+be a social security number together with their full name. Specifics may
+depend on the cultural context, in this document we will simply refer to this
+information as the @strong{identifier}.
+
+This identifier will be first hashed with Argon2, to provide a @strong{kdf_id}
+which will be used to derive other keys later. The Hash must also include the
+respective @strong{server_salt}. This also ensures that the @strong{kdf_id} is different
+on each server. The use of Argon2 and the respective @strong{server_salt} is intended
+to make it difficult to brute-force @strong{kdf_id} values and help protect the user’s
+privacy. Also this ensures that the @strong{kdf_id}s on every server differs. However,
+we do not assume that the @strong{identifier} or the @strong{kdf_id} cannot be
+determined by an adversary performing a targeted attack, as a user’s
+@strong{identifier} is likely to always be known to state actors and may
+likely also be available to other actors.
+
+@example
+kdf_id := Argon2( identifier, server_salt, keysize )
+@end example
+
+@strong{identifier}: The secret defined from the user beforehand.
+
+@strong{server_salt}: The salt from the Server.
+
+@strong{keysize}: The desired output size of the KDF, here 32 bytes.
+
+@menu
+* Verification::
+* Encryption::
+
+@end menu
+
+@node Verification,Encryption,,Key derivations
+@anchor{cryptography verification}@anchor{1e}
+@subsubsection Verification
+
+
+For users to authorize “policy” operations we need an EdDSA key pair. As we
+cannot assure that the corresponding private key is truly secret, such policy
+operations must never be destructive: Should an adversary learn the private
+key, they could access (and with the @strong{kdf_id}, decrypt) the user’s policy (but
+not the core secret), or upload a new version of the
+@strong{encrypted recovery document} (but not delete an existing version).
+
+For the generation of the private key we use the @strong{kdf_id} as the entropy source,
+hash it to derive a base secret which will then be processed to fit the
+requirements for EdDSA private keys. From the private key we can then
+generate the corresponding public key. Here, “ver” is used as a salt for the
+HKDF to ensure that the result differs from other cases where we hash
+@strong{kdf_id}.
+
+@example
+ver_secret := HKDF(kdf_id, "ver", keysize)
+eddsa_priv := eddsa_d_to_a(ver_secret)
+eddsa_pub := get_EdDSA_Pub(eddsa_priv)
+@end example
+
+@strong{HKDF()}: The HKDF-function uses two phases: First we use HMAC-SHA512 for the extraction phase, then HMAC-SHA256 is used for expansion phase.
+
+@strong{kdf_id}: Hashed identifier.
+
+@strong{key_size}: Size of the output, here 32 bytes.
+
+@strong{ver_secret}: Derived key from the @code{kdf_id}, serves as intermediate step for the generation of the private key.
+
+@strong{eddsa_d_to_a()}: Function which converts the ver_key to a valid EdDSA private key. Specifically, assuming the value @code{eddsa_priv} is in a 32-byte array “digest”, the function clears and sets certain bits as follows:
+
+@example
+digest[0] = (digest[0] & 0x7f) | 0x40;
+digest[31] &= 0xf8;
+@end example
+
+@strong{eddsa_priv}: The generated EdDSA private key.
+
+@strong{eddsa_pub}: The generated EdDSA public key.
+
+@node Encryption,,Verification,Key derivations
+@anchor{cryptography encryption}@anchor{1f}
+@subsubsection Encryption
+
+
+For symmetric encryption of data we use AES256-GCM. For this we need a
+symmetric key and an initialization vector (IV). To ensure that the
+symmetric key changes for each encryption operation, we compute the
+key material using an HKDF over a @code{nonce} and the @code{kdf_id}.
+
+@example
+(iv,key) := HKDF(kdf_id, nonce, keysize + ivsize)
+@end example
+
+@strong{HKDF()}: The HKDF-function uses two phases: First we use HMAC-SHA512 for the extraction phase, then HMAC-SHA256 is used for expansion phase.
+
+@strong{kdf_id}: Hashed identifier.
+
+@strong{keysize}: Size of the AES symmetric key, here 32 bytes.
+
+@strong{ivsize}: Size of the AES GCM IV, here 12 bytes.
+
+@strong{prekey}: Original key material.
+
+@strong{nonce}: 32-byte nonce, must never match “ver” (which it cannot as the length is different). Of course, we must
+avoid key reuse. So, we have to use different nonces to get different keys and IVs (see below).
+
+@strong{key}: Symmetric key which is later used to encrypt the documents with AES256-GCM.
+
+@strong{iv}: IV which will be used for AES-GCM.
+
+@node Key Usage,Availability Considerations,Key derivations,Cryptography
+@anchor{cryptography key-usage}@anchor{20}
+@subsection Key Usage
+
+
+The keys we have generated are then used to encrypt the @strong{recovery document} and
+the @strong{key_share} of the user.
+
+@menu
+* Encryption: Encryption<2>.
+* Signatures::
+
+@end menu
+
+@node Encryption<2>,Signatures,,Key Usage
+@anchor{cryptography id1}@anchor{21}
+@subsubsection Encryption
+
+
+Before every encryption a 32-byte nonce is generated.
+From this the symmetric key is computed as described above.
+We use AES256-GCM for the encryption of the @strong{recovery document} and
+the @strong{key_share}. To ensure that the key derivation for the encryption
+of the @strong{recovery document} differs fundamentally from that of an
+individual @strong{key share}, we use different salts (“erd” and “eks”, respectively).
+
+@example
+(iv0, key0) := HKDF(key_id, nonce0, "erd", keysize + ivsize)
+(encrypted_recovery_document, aes_gcm_tag) := AES256_GCM(recovery_document, key0, iv0)
+(iv_i, key_i) := HKDF(key_id, nonce_i, "eks", [optional data], keysize + ivsize)
+(encrypted_key_share_i, aes_gcm_tag_i) := AES256_GCM(key_share_i, key_i, iv_i)
+@end example
+
+@strong{encrypted_recovery_document}: The encrypted @strong{recovery document} which contains the escrow methods, policies
+and the encrypted @strong{core secret}.
+
+@strong{nonce0}: Nonce which is used to generate @emph{key0} and @emph{iv0} which are used for the encryption of the @emph{recovery document}.
+Nonce must contain the string “ERD”.
+
+@strong{optional data}: Key material that optionally is contributed from the authentication method to further obfuscate the key share from the escrow provider.
+
+@strong{encrypted_key_share_i}: The encrypted @strong{key_share} which the escrow provider must release upon successful authentication.
+Here, @strong{i} must be a positive number used to iterate over the various @strong{key shares} used for the various @strong{escrow methods}
+at the various providers.
+
+@strong{nonce_i}: Nonce which is used to generate @emph{key_i} and @emph{iv_i} which are used for the encryption of the @strong{key share}. @strong{i} must be
+the same number as specified above for @emph{encrypted_key_share_i}. Nonce must contain the string “EKS” plus the according @emph{i}.
+
+As a special rule, when a @strong{security question} is used to authorize access to an
+@strong{encrypted_key_share_i}, then the salt “eks” is replaced with an (expensive) hash
+of the answer to the security question as an additional way to make the key share
+inaccessible to those who do not have the answer:
+
+@example
+powh := POW_HASH (qsalt, answer)
+ekss := HKDF("Anastasis-secure-question-uuid-salting",
+ powh,
+ uuid);
+(iv_i, key_i) := HKDF(key_id, nonce_i, ekss, [optional data], keysize + ivsize)
+@end example
+
+@strong{qsalt}: Salt value used to hash answer to satisfy the challenge to prevent the provider from determining the answer via guessing.
+
+@strong{answer}: Answer to the security question, in UTF-8, as entered by the user.
+
+@strong{powh}: Result of the (expensive, proof-of-work) hash algorithm.
+
+@strong{uuid}: UUID of the challenge associated with the security question and the encrypted key share.
+
+@strong{ekss}: Replacement salt to be used instead of “eks” when deriving the key to encrypt/decrypt the key share.
+
+@node Signatures,,Encryption<2>,Key Usage
+@anchor{cryptography signatures}@anchor{22}
+@subsubsection Signatures
+
+
+The EdDSA keys are used to sign the data sent from the client to the
+server. Everything the client sends to server is signed. The following
+algorithm is equivalent for @strong{Anastasis-Policy-Signature}.
+
+@example
+(anastasis-account-signature) := eddsa_sign(h_body, eddsa_priv)
+ver_res := eddsa_verifiy(h_body, anastasis-account-signature, eddsa_pub)
+@end example
+
+@strong{anastasis-account-signature}: Signature over the SHA-512 hash of the body using the purpose code @code{TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD} (1400) (see GNUnet EdDSA signature API for the use of purpose).
+
+@strong{h_body}: The hashed body.
+
+@strong{ver_res}: A boolean value. True: Signature verification passed, False: Signature verification failed.
+
+When requesting policy downloads, the client must also provide a signature:
+
+@example
+(anastasis-account-signature) := eddsa_sign(version, eddsa_priv)
+ver_res := eddsa_verifiy(version, anastasis-account-signature, eddsa_pub)
+@end example
+
+@strong{anastasis-account-signature}: Signature over the SHA-512 hash of the body using the purpose code @code{TALER_SIGNATURE_ANASTASIS_POLICY_DOWNLOAD} (1401) (see GNUnet EdDSA signature API for the use of purpose).
+
+@strong{version}: The version requested as a 64-bit integer, 2^64-1 for the “latest version”.
+
+@strong{ver_res}: A boolean value. True: Signature verification passed, False: Signature verification failed.
+
+@node Availability Considerations,,Key Usage,Cryptography
+@anchor{cryptography availability-considerations}@anchor{23}
+@subsection Availability Considerations
+
+
+Anastasis considers two main threats against availability. First, the
+Anastasis server operators must be protected against denial-of-service attacks
+where an adversary attempts to exhaust the operator’s resources. The API protects
+against these attacks by allowing operators to set fees for all
+operations. Furthermore, all data stored comes with an expiration logic, so an
+attacker cannot force servers to store data indefinitely.
+
+A second availability issue arises from strong adversaries that may be able to
+compute the account keys of some user. While we assume that such an adversary
+cannot successfully authenticate against the truth, the account key does
+inherently enable these adversaries to upload a new policy for the account.
+This cannot be prevented, as the legitimate user must be able to set or change
+a policy using only the account key. To ensure that an adversary cannot
+exploit this, policy uploads first of all never delete existing policies, but
+merely create another version. This way, even if an adversary uploads a
+malicious policy, a user can still retrieve an older version of the policy to
+recover access to their data. This append-only storage for policies still
+leaves a strong adversary with the option of uploading many policies to
+exhaust the Anastasis server’s capacity. We limit this attack by requiring a
+policy upload to include a reference to a @strong{payment identifier} from a payment
+made by the user. Thus, a policy upload requires both knowledge of the
+@strong{identity} and making a payment. This effectively prevents an adversary
+from using the append-only policy storage from exhausting Anastasis server
+capacity.
+
+@c This file is part of Anastasis
+@c Copyright (C) 2019-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+@c @author Dominik Meister
+@c @author Dennis Neufeld
+
+@node REST API,Reducer API,Cryptography,Documentation Overview
+@anchor{rest doc}@anchor{24}@anchor{rest rest-api}@anchor{25}
+@section REST API
+
+
+@c This file is part of Anastasis
+@c
+@c Copyright (C) 2014-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+
+@menu
+* HTTP Request and Response::
+* Protocol Version Ranges::
+* Common encodings::
+
+@end menu
+
+@node HTTP Request and Response,Protocol Version Ranges,,REST API
+@anchor{rest http-common}@anchor{26}@anchor{rest http-request-and-response}@anchor{27}
+@subsection HTTP Request and Response
+
+
+Certain response formats are common for all requests. They are documented here
+instead of with each individual request. Furthermore, we note that clients may
+theoretically fail to receive any response. In this case, the client should
+verify that the Internet connection is working properly, and then proceed to
+handle the error as if an internal error (500) had been returned.
+
+@anchor{rest any--*}@anchor{28}
+@deffn {HTTP Any} ANY /*
+
+@strong{Request:}
+
+Unless specified otherwise, HTTP requests that carry a message body must
+have the content type @code{application/json}.
+
+@*Request Headers:
+
+@itemize *
+
+@item
+Content-Type@footnote{https://tools.ietf.org/html/rfc7231#section-3.1.1.5} – application/json
+@end itemize
+
+
+@strong{Response:}
+
+@*Response Headers:
+
+@itemize *
+
+@item
+Content-Type@footnote{https://tools.ietf.org/html/rfc7231#section-3.1.1.5} – application/json
+@end itemize
+
+
+
+@table @asis
+
+@item 200 Ok@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1}:
+
+The request was successful.
+
+@item 400 Bad request@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1}:
+
+One of the arguments to the request is missing or malformed.
+
+@item 500 Internal server error@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1}:
+
+This always indicates some serious internal operational error of the Anastasis
+provider, such as a program bug, database problems, etc., and must not be used for
+client-side problems. When facing an internal server error, clients should
+retry their request after some delay. We recommended initially trying after
+1s, twice more at randomized times within 1 minute, then the user should be
+informed and another three retries should be scheduled within the next 24h.
+If the error persists, a report should ultimately be made to the auditor,
+although the auditor API for this is not yet specified. However, as internal
+server errors are always reported to the exchange operator, a good operator
+should naturally be able to address them in a timely fashion, especially
+within 24h.
+@end table
+
+Unless specified otherwise, all error status codes (4xx and 5xx) have a message
+body with an @ref{29,,ErrorDetail} JSON object.
+
+@strong{Details:}
+
+@example
+interface ErrorDetail @{
+
+ // Numeric error code unique to the condition, see `@w{`}gnu-taler-error-codes`@w{`} in GANA.
+ // The other arguments are specific to the error value reported here.
+ code: number;
+
+ // Human-readable description of the error, i.e. "missing parameter", "commitment violation", ...
+ // Should give a human-readable hint about the error's nature. Optional, may change without notice!
+ hint?: string;
+
+@}
+@end example
+@end deffn
+
+@node Protocol Version Ranges,Common encodings,HTTP Request and Response,REST API
+@anchor{rest protocol-version-ranges}@anchor{2a}
+@subsection Protocol Version Ranges
+
+
+Anastasis services expose the range of API versions they support. Clients in
+turn have an API version range they support. These version ranges are written
+down in the libtool version format@footnote{https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html}.
+
+A protocol version is a positive, non-zero integer. A protocol version range consists of three components:
+
+
+@enumerate
+
+@item
+The @code{current} version. This is the latest version of the protocol supported by the client or service.
+
+@item
+The @code{revision} number. This value should usually not be interpreted by the client/server, but serves
+purely as a comment. Each time a service/client for a protocol is updated while supporting the same
+set of protocol versions, the revision should be increased.
+In rare cases, the revision number can be used to work around unintended breakage in deployed
+versions of a service. This is discouraged and should only be used in exceptional situations.
+
+@item
+The @code{age} number. This non-zero integer identifies with how many previous protocol versions this
+implementation is compatible. An @code{age} of 0 implies that the implementation only supports
+the @code{current} protocol version. The @code{age} must be less or equal than the @code{current} protocol version.
+@end enumerate
+
+To avoid confusion with semantic versions, the protocol version range is written down in the following format:
+
+@example
+current[:revision[:age]]
+@end example
+
+The angle brackets mark optional components. If either @code{revision} or @code{age} are omitted, they default to 0.
+
+Examples:
+
+
+@itemize *
+
+@item
+“1” and “1” are compatible
+
+@item
+“1” and “2” are @strong{incompatible}
+
+@item
+“2:0:1” and “1:0:0” are compatible
+
+@item
+“2:5:1” and “1:10:0” are compatible
+
+@item
+“4:0:1” and “2:0:0” are @strong{incompatible}
+
+@item
+“4:0:1” and “3:0:0” are compatible
+@end itemize
+
+@cartouche
+@quotation Note
+Semantic versions@footnote{https://semver.org/} are not a good tool for this job, as we concisely want to express
+that the client/server supports the last @code{n} versions of the protocol.
+Semantic versions don’t support this, and semantic version ranges are too complex for this.
+@end quotation
+@end cartouche
+
+@cartouche
+@quotation Warning
+A client doesn’t have one single protocol version range. Instead, it has
+a protocol version range for each type of service it talks to.
+@end quotation
+@end cartouche
+
+@cartouche
+@quotation Warning
+For privacy reasons, the protocol version range of a client should not be
+sent to the service. Instead, the client should just use the two version ranges
+to decide whether it will talk to the service.
+@end quotation
+@end cartouche
+
+@node Common encodings,,Protocol Version Ranges,REST API
+@anchor{rest common-encodings}@anchor{2b}@anchor{rest encodings-ref}@anchor{2c}
+@subsection Common encodings
+
+
+This section describes how certain types of values are represented throughout the API.
+
+@menu
+* Binary Data::
+* Hash codes::
+* Large numbers::
+* Timestamps::
+* Integers::
+* Objects::
+* Keys::
+* Signatures: Signatures<2>.
+* Amounts::
+* Time::
+* Cryptographic primitives::
+* Signatures: Signatures<3>.
+* Receiving Configuration::
+* Receiving Terms of Service::
+* Manage policy::
+* Managing truth::
+
+@end menu
+
+@node Binary Data,Hash codes,,Common encodings
+@anchor{rest base32}@anchor{2d}@anchor{rest binary-data}@anchor{2e}
+@subsubsection Binary Data
+
+
+@example
+type Base32 = string;
+@end example
+
+Binary data is generally encoded using Crockford’s variant of Base32
+(@indicateurl{http://www.crockford.com/wrmg/base32.html}), except that “U” is not excluded
+but also decodes to “V” to make OCR easy. We will still simply use the JSON
+type “base32” and the term “Crockford Base32” in the text to refer to the
+resulting encoding.
+
+@node Hash codes,Large numbers,Binary Data,Common encodings
+@anchor{rest hash-codes}@anchor{2f}
+@subsubsection Hash codes
+
+
+Hash codes are strings representing base32 encoding of the respective
+hashed data. See @ref{2d,,base32}.
+
+@example
+// 64-byte hash code.
+type HashCode = string;
+@end example
+
+@example
+// 32-byte hash code.
+type ShortHashCode = string;
+@end example
+
+@node Large numbers,Timestamps,Hash codes,Common encodings
+@anchor{rest large-numbers}@anchor{30}
+@subsubsection Large numbers
+
+
+Large numbers such as 256 bit keys, are transmitted as other binary data in
+Crockford Base32 encoding.
+
+@node Timestamps,Integers,Large numbers,Common encodings
+@anchor{rest timestamps}@anchor{31}
+@subsubsection Timestamps
+
+
+Timestamps are represented by the following structure:
+
+@example
+interface Timestamp @{
+ // Milliseconds since epoch, or the special
+ // value "never" to represent an event that will
+ // never happen.
+ t_ms: number | "never";
+@}
+@end example
+
+@example
+interface Duration @{
+ // Duration in milliseconds or "forever"
+ // to represent an infinite duration.
+ d_ms: number | "forever";
+@}
+@end example
+
+@node Integers,Objects,Timestamps,Common encodings
+@anchor{rest integers}@anchor{32}@anchor{rest publickey}@anchor{33}
+@subsubsection Integers
+
+
+@example
+// JavaScript numbers restricted to integers.
+type Integer = number;
+@end example
+
+@node Objects,Keys,Integers,Common encodings
+@anchor{rest objects}@anchor{34}
+@subsubsection Objects
+
+
+@example
+// JavaScript objects, no further restrictions.
+type Object = object;
+@end example
+
+@node Keys,Signatures<2>,Objects,Common encodings
+@anchor{rest keys}@anchor{35}
+@subsubsection Keys
+
+
+@example
+// EdDSA and ECDHE public keys always point on Curve25519
+// and represented using the standard 256 bits Ed25519 compact format,
+// converted to Crockford `Base32`.
+type EddsaPublicKey = string;
+@end example
+
+@example
+// EdDSA and ECDHE public keys always point on Curve25519
+// and represented using the standard 256 bits Ed25519 compact format,
+// converted to Crockford `Base32`.
+type EddsaPrivateKey = string;
+@end example
+
+@node Signatures<2>,Amounts,Keys,Common encodings
+@anchor{rest signature}@anchor{36}@anchor{rest signatures}@anchor{37}
+@subsubsection Signatures
+
+
+@example
+// EdDSA signatures are transmitted as 64-bytes `base32`
+// binary-encoded objects with just the R and S values (base32_ binary-only).
+type EddsaSignature = string;
+@end example
+
+@node Amounts,Time,Signatures<2>,Common encodings
+@anchor{rest amount}@anchor{38}@anchor{rest amounts}@anchor{39}
+@subsubsection Amounts
+
+
+@example
+type Amount = string;
+@end example
+
+Amounts of currency are serialized as a string of the format
+@code{<Currency>:<DecimalAmount>}. Taler treats monetary amounts as
+fixed-precision numbers, with 8 decimal places. Unlike floating point numbers,
+this allows accurate representation of monetary amounts.
+
+The following constrains apply for a valid amount:
+
+
+@enumerate
+
+@item
+The @code{<Currency>} part must be at most 11 characters long and may only consist
+of ASCII letters (@code{a-zA-Z}).
+
+@item
+The integer part of @code{<DecimalAmount>} may be at most 2^52.
+
+@item
+The fractional part of @code{<DecimalAmount>} may contain at most 8 decimal digits.
+@end enumerate
+
+@cartouche
+@quotation Note
+“EUR:1.50” and “EUR:10” are valid amounts. These are all invalid amounts: “A:B:1.5”, “EUR:4503599627370501.0”, “EUR:1.”, “EUR:.1”.
+@end quotation
+@end cartouche
+
+An amount that is prefixed with a @code{+} or @code{-} character is also used in certain contexts.
+When no sign is present, the amount is assumed to be positive.
+
+@node Time,Cryptographic primitives,Amounts,Common encodings
+@anchor{rest time}@anchor{3a}
+@subsubsection Time
+
+
+In signed messages, time is represented using 64-bit big-endian values,
+denoting microseconds since the UNIX Epoch. @code{UINT64_MAX} represents “never”.
+
+@example
+struct GNUNET_TIME_Absolute @{
+ uint64_t timestamp_us;
+@};
+struct GNUNET_TIME_AbsoluteNBO @{
+ uint64_t abs_value_us__; // in network byte order
+@};
+@end example
+
+@node Cryptographic primitives,Signatures<3>,Time,Common encodings
+@anchor{rest cryptographic-primitives}@anchor{3b}
+@subsubsection Cryptographic primitives
+
+
+All elliptic curve operations are on Curve25519. Public and private keys are
+thus 32 bytes, and signatures 64 bytes. For hashing, including HKDFs, Taler
+uses 512-bit hash codes (64 bytes).
+
+@example
+struct GNUNET_HashCode @{
+ uint8_t hash[64]; // usually SHA-512
+@};
+@end example
+@anchor{rest taler-ecdhephemeralpublickeyp}@anchor{3c}
+@example
+struct TALER_EcdhEphemeralPublicKeyP @{
+ uint8_t ecdh_pub[32];
+@};
+@end example
+
+@example
+struct UUID @{
+ uint32_t value[4];
+@};
+@end example
+
+@node Signatures<3>,Receiving Configuration,Cryptographic primitives,Common encodings
+@anchor{rest id1}@anchor{3d}@anchor{rest id2}@anchor{3e}
+@subsubsection Signatures
+
+
+Any piece of signed data, complies to the abstract data structure given below.
+
+@example
+struct Data @{
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+ type1_t payload1;
+ type2_t payload2;
+ ...
+@};
+
+/*From gnunet_crypto_lib.h*/
+struct GNUNET_CRYPTO_EccSignaturePurpose @{
+ /**
+
+ The following constraints apply for a valid amount:
+
+ * This field is used to express the context in
+ * which the signature is made, ensuring that a
+ * signature cannot be lifted from one part of the protocol
+ * to another. See `src/include/taler_signatures.h` within the
+ * exchange's codebase (git://taler.net/exchange).
+ */
+ uint32_t purpose;
+ /**
+ * This field equals the number of bytes being signed,
+ * namely 'sizeof (struct Data)'.
+ */
+ uint32_t size;
+@};
+@end example
+@anchor{rest salt}@anchor{3f}
+@node Receiving Configuration,Receiving Terms of Service,Signatures<3>,Common encodings
+@anchor{rest config}@anchor{40}@anchor{rest receiving-configuration}@anchor{41}
+@subsubsection Receiving Configuration
+
+
+@anchor{rest get--config}@anchor{42}
+@deffn {HTTP Get} GET /config
+
+Obtain the configuration details of the escrow provider.
+
+@strong{Response:}
+
+Returns an @ref{43,,EscrowConfigurationResponse}.
+@anchor{rest escrowconfigurationresponse}@anchor{43}
+@example
+interface EscrowConfigurationResponse @{
+
+ // Protocol identifier, clarifies that this is an Anastasis provider.
+ name: "anastasis";
+
+ // libtool-style representation of the Exchange protocol version, see
+ // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ // The format is "current:revision:age".
+ version: string;
+
+ // Currency in which this provider processes payments.
+ currency: string;
+
+ // Supported authorization methods.
+ methods: AuthorizationMethodConfig[];
+
+ // Maximum policy upload size supported.
+ storage_limit_in_megabytes: number;
+
+ // Payment required to maintain an account to store policy documents for a year.
+ // Users can pay more, in which case the storage time will go up proportionally.
+ annual_fee: Amount;
+
+ // Payment required to upload truth. To be paid per upload.
+ truth_upload_fee: Amount;
+
+ // Limit on the liability that the provider is offering with
+ // respect to the services provided.
+ liability_limit: Amount;
+
+ // Salt value with 128 bits of entropy.
+ // Different providers
+ // will use different high-entropy salt values. The resulting
+ // **provider salt** is then used in various operations to ensure
+ // cryptographic operations differ by provider. A provider must
+ // never change its salt value.
+ server_salt: string;
+
+@}
+@end example
+@anchor{rest authorizationmethodconfig}@anchor{44}
+@example
+interface AuthorizationMethodConfig @{
+ // Name of the authorization method.
+ type: string;
+
+ // Fee for accessing key share using this method.
+ cost: Amount;
+
+@}
+@end example
+@end deffn
+
+@node Receiving Terms of Service,Manage policy,Receiving Configuration,Common encodings
+@anchor{rest receiving-terms-of-service}@anchor{45}@anchor{rest terms}@anchor{46}
+@subsubsection Receiving Terms of Service
+
+
+@anchor{rest get--terms}@anchor{47}
+@deffn {HTTP Get} GET /terms
+
+Obtain the terms of service provided by the escrow provider.
+
+@strong{Response:}
+
+Returns the terms of service of the provider, in the best language
+and format available based on the client’s request.
+@end deffn
+
+@anchor{rest get--privacy}@anchor{48}
+@deffn {HTTP Get} GET /privacy
+
+Obtain the privacy policy of the service provided by the escrow provider.
+
+@strong{Response:}
+
+Returns the privacy policy of the provider, in the best language
+and format available based on the client’s request.
+@end deffn
+
+@node Manage policy,Managing truth,Receiving Terms of Service,Common encodings
+@anchor{rest id3}@anchor{49}@anchor{rest manage-policy}@anchor{4a}
+@subsubsection Manage policy
+
+
+This API is used by the Anastasis client to deposit or request encrypted
+recovery documents with the escrow provider. Generally, a client will deposit
+the same encrypted recovery document with each escrow provider, but provide
+a different truth to each escrow provider.
+
+Operations by the client are identified and authorized by @code{$ACCOUNT_PUB}, which
+should be kept secret from third parties. @code{$ACCOUNT_PUB} should be an account
+public key using the Crockford base32-encoding.
+
+In the following, UUID is always defined and used according to RFC 4122@footnote{https://tools.ietf.org/html/rfc4122}.
+
+@anchor{rest get--policy-$ACCOUNT_PUB[?version=$NUMBER]}@anchor{4b}
+@deffn {HTTP Get} GET /policy/$ACCOUNT_PUB[?version=$NUMBER]
+
+Get the customer’s encrypted recovery document. If @code{version}
+is not specified, the server returns the latest available version. If
+@code{version} is specified, returns the policy with the respective
+@code{version}. The response must begin with the nonce and
+an AES-GCM tag and continue with the ciphertext. Once decrypted, the
+plaintext is expected to contain:
+
+
+@itemize *
+
+@item
+the escrow policy
+
+@item
+the separately encrypted master public key
+@end itemize
+
+Note that the key shares required to decrypt the master public key are
+not included, as for this the client needs to obtain authorization.
+The policy does provide sufficient information for the client to determine
+how to authorize requests for @strong{truth}.
+
+The client MAY provide an @code{If-None-Match} header with an Etag.
+In that case, the server MUST additionally respond with an @code{304} status
+code in case the resource matches the provided Etag.
+
+@strong{Response}:
+
+
+@table @asis
+
+@item 200 OK@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1}:
+
+The escrow provider responds with an @ref{4c,,EncryptedRecoveryDocument} object.
+
+@item 304 Not modified@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5}:
+
+The client requested the same resource it already knows.
+
+@item 400 Bad request@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1}:
+
+The @code{$ACCOUNT_PUB} is not an EdDSA public key.
+
+@item 402 Payment Required@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}:
+
+The account’s balance is too low for the specified operation.
+See the Taler payment protocol specification for how to pay.
+
+@item 403 Forbidden@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4}:
+
+The required account signature was invalid.
+
+@item 404 Not found@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5}:
+
+The requested resource was not found.
+@end table
+
+@emph{Anastasis-Version}: $NUMBER — The server must return actual version of the encrypted recovery document via this header.
+If the client specified a version number in the header of the request, the server must return that version. If the client
+did not specify a version in the request, the server returns latest version of the @ref{4c,,EncryptedRecoveryDocument}.
+
+@emph{Etag}: Set by the server to the Base32-encoded SHA512 hash of the body. Used for caching and to prevent redundancies. The server MUST send the Etag if the status code is @code{200 OK}.
+
+@emph{If-None-Match}: If this is not the very first request of the client, this contains the Etag-value which the client has received before from the server.
+The client SHOULD send this header with every request (except for the first request) to avoid unnecessary downloads.
+
+@emph{Anastasis-Account-Signature}: The client must provide Base-32 encoded EdDSA signature over hash of body with @code{$ACCOUNT_PRIV}, affirming desire to download the requested encrypted recovery document. The purpose used MUST be @code{TALER_SIGNATURE_ANASTASIS_POLICY_DOWNLOAD} (1401).
+@end deffn
+
+@anchor{rest post--policy-$ACCOUNT_PUB}@anchor{4d}
+@deffn {HTTP Post} POST /policy/$ACCOUNT_PUB
+
+Upload a new version of the customer’s encrypted recovery document.
+While the document’s structure is described in JSON below, the upload
+should just be the bytestream of the raw data (i.e. 32-byte nonce followed
+by 16-byte tag followed by the encrypted document).
+If the request has been seen before, the server should do nothing, and otherwise store the new version.
+The body must begin with a nonce, an AES-GCM tag and continue with the ciphertext. The format
+is the same as specified for the response of the GET method. The
+Anastasis server cannot fully validate the format, but MAY impose
+minimum and maximum size limits.
+
+@strong{Request}:
+
+@*Query Parameters:
+
+@itemize *
+
+@item
+@code{storage_duration=YEARS} – For how many years from now would the client like us to
+store the recovery document? Defaults to 0 (that is, do
+not extend / prolong existing storage contract).
+The server will respond with a @code{402 Payment required}, but only
+if the rest of the request is well-formed (account
+signature must match). Clients that do not actually
+intend to make a new upload but that only want to pay
+may attempt to upload the latest backup again, as this
+option will be checked before the @code{304 Not modified}
+case.
+
+@item
+@code{timeout_ms=NUMBER} – @emph{Optional.} If specified, the Anastasis server will
+wait up to @code{timeout_ms} milliseconds for completion of the payment before
+sending the HTTP response. A client must never rely on this behavior, as the
+backend may return a response immediately.
+@end itemize
+
+
+@emph{If-None-Match}: This header MUST be present and set to the SHA512 hash (Etag) of the body by the client.
+The client SHOULD also set the @code{Expect: 100-Continue} header and wait for @code{100 continue}
+before uploading the body. The server MUST
+use the Etag to check whether it already knows the encrypted recovery document that is about to be uploaded.
+The server MUST refuse the upload with a @code{304} status code if the Etag matches
+the latest version already known to the server.
+
+@emph{Anastasis-Policy-Signature}: The client must provide Base-32 encoded EdDSA signature over hash of body with @code{$ACCOUNT_PRIV}, affirming desire to upload an encrypted recovery document.
+
+@emph{Payment-Identifier}: Base-32 encoded 32-byte payment identifier that was included in a previous payment (see @code{402} status code). Used to allow the server to check that the client paid for the upload (to protect the server against DoS attacks) and that the client knows a real secret of financial value (as the @strong{kdf_id} might be known to an attacker). If this header is missing in the client’s request (or the associated payment has exceeded the upload limit), the server must return a @code{402} response. When making payments, the server must include a fresh, randomly-generated payment-identifier in the payment request.
+
+@strong{Response}:
+
+
+@table @asis
+
+@item 204 No content@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5}:
+
+The encrypted recovery document was accepted and stored. @code{Anastasis-Version} and @code{Anastasis-UUID} headers
+indicate what version and UUID was assigned to this encrypted recovery document upload by the server.
+
+@item 304 Not modified@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5}:
+
+The same encrypted recovery document was previously accepted and stored. @code{Anastasis-Version} header
+indicates what version was previously assigned to this encrypted recovery document.
+
+@item 400 Bad request@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1}:
+
+The @code{$ACCOUNT_PUB} is not an EdDSA public key or mandatory headers are missing.
+The response body MUST elaborate on the error using a Taler error code in the typical JSON encoding.
+
+@item 402 Payment required@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}:
+
+The account’s balance is too low for the specified operation.
+See the Taler payment protocol specification for how to pay.
+The response body MAY provide alternative means for payment.
+
+@item 403 Forbidden@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4}:
+
+The required account signature was invalid. The response body may elaborate on the error.
+
+@item 413 Request entity too large@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14}:
+
+The upload is too large @emph{or} too small. The response body may elaborate on the error.
+@end table
+
+@strong{Details:}
+@anchor{rest encryptedrecoverydocument}@anchor{4c}
+@example
+interface EncryptedRecoveryDocument @{
+ // Nonce used to compute the (iv,key) pair for encryption of the
+ // encrypted_compressed_recovery_document.
+ nonce: [32]; //bytearray
+
+ // Authentication tag.
+ aes_gcm_tag: [16]; //bytearray
+
+ // Variable-size encrypted recovery document. After decryption,
+ // this contains a gzip compressed JSON-encoded `RecoveryDocument`.
+ // The nonce of the HKDF for this encryption must include the
+ // string "ERD".
+ encrypted_compressed_recovery_document: []; //bytearray of undefined length
+
+@}
+@end example
+@anchor{rest recoverydocument}@anchor{4e}
+@example
+interface RecoveryDocument @{
+ // Account identifier at backup provider, AES-encrypted with
+ // the (symmetric) master_key, i.e. an URL
+ // https://sync.taler.net/$BACKUP_ID and
+ // a private key to decrypt the backup. Anastasis is oblivious
+ // to the details of how this is ultimately encoded.
+ backup_account: []; //bytearray of undefined length
+
+ // List of escrow providers and selected authentication method.
+ methods: EscrowMethod[];
+
+ // List of possible decryption policies.
+ policy: DecryptionPolicy[];
+
+@}
+@end example
+@anchor{rest escrowmethod}@anchor{4f}
+@example
+interface EscrowMethod @{
+ // URL of the escrow provider (including possibly this Anastasis server).
+ provider_url : string;
+
+ // Type of the escrow method (e.g. security question, SMS etc.).
+ escrow_type: string;
+
+ // UUID of the escrow method (see /truth/ API below).
+ uuid: string;
+
+ // Key used to encrypt the `Truth` this `EscrowMethod` is related to.
+ // Client has to provide this key to the server when using `@w{`}/truth/`@w{`}.
+ truth_encryption_key: [32]; //bytearray
+
+ // Salt used to encrypt the truth on the Anastasis server.
+ truth_salt: [32]; //bytearray
+
+ // The challenge to give to the user (i.e. the security question
+ // if this is challenge-response).
+ // (Q: as string in base32 encoding?)
+ // (Q: what is the mime-type of this value?)
+ //
+ // For some methods, this value may be absent.
+ //
+ // The plaintext challenge is not revealed to the
+ // Anastasis server.
+ challenge: []; //bytearray of undefined length
+
+@}
+@end example
+@anchor{rest decryptionpolicy}@anchor{50}
+@example
+interface DecryptionPolicy @{
+ // Salt included to encrypt master key share when
+ // using this decryption policy.
+ policy_salt: [32]; //bytearray
+
+ // Master key, AES-encrypted with key derived from
+ // salt and keyshares revealed by the following list of
+ // escrow methods identified by UUID.
+ encrypted_master_key: [32]; //bytearray
+
+ // List of escrow methods identified by their UUID.
+ uuid: string[];
+
+@}
+@end example
+@end deffn
+
+@node Managing truth,,Manage policy,Common encodings
+@anchor{rest managing-truth}@anchor{51}@anchor{rest truth}@anchor{52}
+@subsubsection Managing truth
+
+
+This API is used by the Anastasis client to deposit @strong{truth} or request a (encrypted) @strong{key share} with
+the escrow provider.
+
+An @strong{escrow method} specifies an Anastasis provider and how the user should
+authorize themself. The @strong{truth} API allows the user to provide the
+(encrypted) key share to the respective escrow provider, as well as auxiliary
+data required for such a respective escrow method.
+
+An Anastasis-server may store truth for free for a certain time period, or
+charge per truth operation using GNU Taler.
+
+@anchor{rest post--truth-$UUID}@anchor{53}
+@deffn {HTTP Post} POST /truth/$UUID
+
+Upload a @ref{54,,TruthUploadRequest}-Object according to the policy the client created before (see @ref{4e,,RecoveryDocument}).
+If request has been seen before, the server should do nothing, and otherwise store the new object.
+
+@strong{Request:}
+
+@*Query Parameters:
+
+@itemize *
+
+@item
+@code{timeout_ms=NUMBER} – @emph{Optional.} If specified, the Anastasis server will
+wait up to @code{timeout_ms} milliseconds for completion of the payment before
+sending the HTTP response. A client must never rely on this behavior, as the
+backend may return a response immediately.
+@end itemize
+
+
+@strong{Response:}
+
+
+@table @asis
+
+@item 204 No content@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5}:
+
+Truth stored successfully.
+
+@item 304 Not modified@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5}:
+
+The same truth was previously accepted and stored under this UUID. The
+Anastasis server must still update the expiration time for the truth when returning
+this response code.
+
+@item 402 Payment required@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}:
+
+This server requires payment to store truth per item.
+See the Taler payment protocol specification for how to pay.
+The response body MAY provide alternative means for payment.
+
+@item 409 Conflict@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10}:
+
+The server already has some truth stored under this UUID. The client should check that it
+is generating UUIDs with enough entropy.
+
+@item 412 Precondition failed@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13}:
+
+The selected authentication method is not supported on this provider.
+@end table
+
+@strong{Details:}
+@anchor{rest truthuploadrequest}@anchor{54}
+@example
+interface TruthUploadRequest @{
+ // Contains the information of an interface `EncryptedKeyShare`, but simply
+ // as one binary block (in Crockford Base32 encoding for JSON).
+ key_share_data: []; //bytearray
+
+ // Key share method, i.e. "security question", "SMS", "e-mail", ...
+ type: string;
+
+ // Nonce used to compute the (iv,key) pair for encryption of the
+ // encrypted_truth.
+ nonce: [32]; //bytearray
+
+ // Authentication tag of `@w{`}encrypted_truth`@w{`}.
+ aes_gcm_tag: [16]; //bytearray
+
+ // Variable-size truth. After decryption,
+ // this contains the ground truth, i.e. H(challenge answer),
+ // phone number, e-mail address, picture, fingerprint, ...
+ // **base32 encoded**.
+ //
+ // The nonce of the HKDF for this encryption must include the
+ // string "ECT".
+ encrypted_truth: [80]; //bytearray
+
+ // MIME type of truth, i.e. text/ascii, image/jpeg, etc.
+ truth_mime: string;
+
+ // For how many years from now would the client like us to
+ // store the truth?
+ storage_duration_years: Integer;
+
+@}
+@end example
+@end deffn
+
+@anchor{rest get--truth-$UUID[?response=$H_RESPONSE]}@anchor{55}
+@deffn {HTTP Get} GET /truth/$UUID[?response=$H_RESPONSE]
+
+Get the stored encrypted key share. If @code{$H_RESPONSE} is specified by the client, the server checks
+if @code{$H_RESPONSE} matches the expected response specified before within the @ref{54,,TruthUploadRequest} (see @code{encrypted_truth}).
+Also, the user has to provide the correct @emph{truth_encryption_key} with every get request (see below).
+When @code{$H_RESPONSE} is correct, the server responds with the encrypted key share.
+The encrypted key share is returned simply as a byte array and not in JSON format.
+
+@strong{Response}:
+
+
+@table @asis
+
+@item 200 OK@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1}:
+
+@ref{56,,EncryptedKeyShare} is returned in body (in binary).
+
+@item 202 Accepted@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3}:
+
+The escrow provider will respond out-of-band (i.e. SMS).
+The body may contain human-readable instructions on next steps.
+
+@item >>208 Already Reported<<:
+
+An authentication challenge was recently send, client should
+simply respond to the pending challenge.
+
+@item 303 See other@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4}:
+
+The provider redirects for authentication (i.e. video identification/WebRTC).
+If the client is not a browser, it should launch a browser at the URL
+given in the @code{Location} header and allow the user to re-try the operation
+after successful authorization.
+
+@item 402 Payment required@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3}:
+
+The service requires payment for access to truth.
+See the Taler payment protocol specification for how to pay.
+The response body MAY provide alternative means for payment.
+
+@item 403 Forbidden@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4}:
+
+The server requires a valid “response” to the challenge associated with the UUID.
+
+@item 404 Not found@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5}:
+
+The server does not know any truth under the given UUID.
+
+@item 410 Gone@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11}:
+
+The server has not (recently) issued a challenge under the given UUID,
+but a reply was provided. (This does not apply for secure question.)
+
+@item 417 Expectation Failed@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18}:
+
+The decrypted @code{truth} does not match the expectations of the authentication
+backend, i.e. a phone number for sending an SMS is not a number, or
+an e-mail address for sending an E-mail is not a valid e-mail address.
+
+@item 503 Service Unavailable@footnote{http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4}:
+
+Server is out of Service.
+@end table
+
+@emph{Truth-Decryption-Key}: Key used to encrypt the @strong{truth} (see encrypted_truth within @ref{54,,TruthUploadRequest}) and which has to provided by the user. The key is stored with
+the according @ref{4f,,EscrowMethod}. The server needs this key to get the info out of @ref{54,,TruthUploadRequest} needed to verify the @code{$RESPONSE}.
+
+@strong{Details:}
+@anchor{rest encryptedkeyshare}@anchor{56}
+@example
+interface EncryptedKeyShare @{
+ // Nonce used to compute the decryption (iv,key) pair.
+ nonce_i: [32]; //bytearray
+
+ // Authentication tag.
+ aes_gcm_tag_i: [16]; //bytearray
+
+ // Encrypted key-share in base32 encoding.
+ // After decryption, this yields a `KeyShare`. Note that
+ // the `KeyShare` MUST be encoded as a fixed-size binary
+ // block (instead of in JSON encoding).
+ //
+ // HKDF for the key generation must include the
+ // string "eks" as salt.
+ // Depending on the method,
+ // the HKDF may additionally include
+ // bits from the response (i.e. some hash over the
+ // answer to the security question).
+ encrypted_key_share_i: [32]; //bytearray
+
+@}
+@end example
+@anchor{rest keyshare}@anchor{57}
+@example
+interface KeyShare @{
+ // Key material to concatenate with policy_salt and KDF to derive
+ // the key to decrypt the master key.
+ key_share: [32]; //bytearray
+
+ // Signature over method, UUID, and `@w{`}key_share`@w{`}.
+ account_sig: EddsaSignature;
+
+@}
+@end example
+@end deffn
+
+@c This file is part of Anastasis
+@c Copyright (C) 2019-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+@c @author Dominik Meister
+@c @author Dennis Neufeld
+
+@node Reducer API,Authentication Methods,REST API,Documentation Overview
+@anchor{reducer doc}@anchor{58}@anchor{reducer reducer-api}@anchor{59}
+@section Reducer API
+
+
+This section describes the Anastasis Reducer API which is used by client applications
+to store or load the different states the client application can have.
+The reducer takes a @ref{5a,,state} in JSON syntax and returns the new state in JSON syntax.
+
+For example a @strong{state} may take the following structure:
+
+@example
+@{
+ "backup_state": "CONTINENT_SELECTING",
+ "continents": [
+ "Europe",
+ "North_America"
+ ]
+@}
+@end example
+
+The new state depends on the previous one and on the transition @ref{5b,,action} with its
+arguments given to the reducer. A @strong{transition argument} also is a statement in JSON syntax:
+
+@example
+@{
+ "continent": "Europe"
+@}
+@end example
+
+The new state returned by the reducer with the state and transition argument defined
+above would look like following for the transition @ref{5b,,action} @code{select_continent}:
+
+@example
+@{
+ "backup_state": "COUNTRY_SELECTING",
+ "continents": [
+ "Europe",
+ "North_America"
+ ],
+ "selected_continent": "Europe",
+ "countries": [
+ @{
+ "code": "ch",
+ "name": "Switzerland",
+ "continent": "Europe",
+ "name_i18n": @{
+ "de_DE": "Schweiz",
+ "de_CH": "Schwiiz",
+ "fr": "Suisse",
+ "en": "Swiss"
+ @},
+ "currency": "CHF"
+ @},
+ @{
+ "code": "de",
+ "name": "Germany",
+ "continent": "Europe",
+ "continent_i18n": @{
+ "de": "Europa"
+ @},
+ "name_i18n": @{
+ "de_DE": "Deutschland",
+ "de_CH": "Deutschland",
+ "fr": "Allemagne",
+ "en": "Germany"
+ @},
+ "currency": "EUR"
+ @}
+ ]
+@}
+@end example
+
+@menu
+* States::
+* Backup Reducer::
+* Recovery Reducer::
+* Reducer transitions::
+
+@end menu
+
+@node States,Backup Reducer,,Reducer API
+@anchor{reducer states}@anchor{5c}
+@subsection States
+
+
+Overall, the reducer knows the following states:
+
+@quotation
+
+
+@itemize -
+
+@item
+
+@table @asis
+
+@item @strong{ERROR}: The transition led to an error. No further transitions are possible from
+
+this state, but the client may want to continue from a previous state.
+@end table
+
+@item
+
+@table @asis
+
+@item @strong{CONTINENT_SELECTING}: The user should specify the continent where they are living,
+
+so that we can show a list of countries to choose from.
+@end table
+
+@item
+
+@table @asis
+
+@item @strong{COUNTRY_SELECTING}: The user should specify the country where they are living,
+
+so that we can determine appropriate attributes, currencies and Anastasis
+providers.
+@end table
+
+@item
+
+@table @asis
+
+@item @strong{USER_ATTRIBUTES_COLLECTING}: The user should provide the country-specific personal
+
+attributes.
+@end table
+
+@item
+
+@table @asis
+
+@item @strong{AUTHENTICATIONS_EDITING}: The user should add authentication methods to be used
+
+during recovery.
+@end table
+
+@item
+@strong{POLICIES_REVIEWING}: The user should review the recovery policies.
+
+@item
+@strong{SECRET_EDITING}: The user should edit the secret to be backed up.
+
+@item
+
+@table @asis
+
+@item @strong{TRUTHS_PAYING}: The user needs to pay for one or more uploads of data associated
+
+with an authentication method.
+@end table
+
+@item
+@strong{POLICIES_PAYING}: The user needs to pay for storing the recovery policy document.
+
+@item
+@strong{BACKUP_FINISHED}: A backup has been successfully generated.
+
+@item
+
+@table @asis
+
+@item @strong{SECRET_SELECTING}: The user needs to select a recovery policy document with
+
+the secret that is to be recovered.
+@end table
+
+@item
+
+@table @asis
+
+@item @strong{CHALLENGE_SELECTING}: The user needs to select an authorization challenge to
+
+proceed with recovery.
+@end table
+
+@item
+@strong{CHALLENGE_PAYING}: The user needs to pay to proceed with the authorization challenge.
+
+@item
+@strong{CHALLENGE_SOLVING}: The user needs to solve the authorization challenge.
+
+@item
+@strong{RECOVERY_FINISHED}: The secret of the user has been recovered.
+@end itemize
+@end quotation
+
+State names:
+
+@quotation
+
+
+@itemize -
+
+@item
+In SELECTING-states, the user has to choose one value out of a predefined set of values (for example a continent out of a set of continents).
+
+@item
+In COLLECTING-states, the user has to give certain values.
+
+@item
+In EDITING-states, the user is free to choose which values he wants to give.
+
+@item
+In REVEIWING-states, the user may make a few choices, but primarily is expected to affirm something.
+
+@item
+in PAYING-states, the user must make a payment.
+
+@item
+in FINISHED-states, the operation has definitively concluded.
+@end itemize
+@end quotation
+
+@node Backup Reducer,Recovery Reducer,States,Reducer API
+@anchor{reducer backup-reducer}@anchor{5d}
+@subsection Backup Reducer
+
+@anchor{reducer state}@anchor{5a}@anchor{reducer action}@anchor{5b}
+
+@float Figure
+
+@image{anastasis-figures/anastasis_reducer_backup,,,fig-anastasis_reducer_backup,png}
+
+@caption{Backup states and their transitions.}
+
+@end float
+
+
+The illustration above shows the different states the reducer can have during a backup
+process.
+
+@node Recovery Reducer,Reducer transitions,Backup Reducer,Reducer API
+@anchor{reducer recovery-reducer}@anchor{5e}
+@subsection Recovery Reducer
+
+
+
+@float Figure
+
+@image{anastasis-figures/anastasis_reducer_recovery,,,fig-anastasis_reducer_recovery,png}
+
+@caption{Recovery states and their transitions.}
+
+@end float
+
+
+The illustration above shows the different states the reducer can have during a recovery
+process.
+
+@node Reducer transitions,,Recovery Reducer,Reducer API
+@anchor{reducer reducer-transitions}@anchor{5f}
+@subsection Reducer transitions
+
+
+In the following, the individual transitions will be specified in more detail.
+Note that we only show fields added by the reducer, typically the previous
+state is preserved to enable “back” transitions to function smoothly.
+
+@menu
+* Initial state::
+* Common transitions::
+* Backup transitions::
+* Recovery transitions::
+
+@end menu
+
+@node Initial state,Common transitions,,Reducer transitions
+@anchor{reducer initial-state}@anchor{60}
+@subsubsection Initial state
+
+
+The initial states for backup and recovery processes are:
+
+@strong{Initial backup state:}
+
+@example
+@{
+ "backup_state": "CONTINENT_SELECTING",
+ "continents": [
+ "Europe",
+ "North America"
+ ]
+@}
+@end example
+
+@strong{Initial recovery state:}
+
+@example
+@{
+ "recovery_state": "CONTINENT_SELECTING",
+ "continents": [
+ "Europe",
+ "North America"
+ ]
+@}
+@end example
+
+Here, “continents” is an array of English strings with the names of the
+continents which contain countries for which Anastasis could function (based
+on having providers that are known to operate and rules being provided for
+user attributes from those countries).
+
+For internationalization, another field @code{continents_i18n} may be present.
+This field would be a map of language names to arrays of translated
+continent names:
+
+@example
+@{
+ "recovery_state": "CONTINENT_SELECTING",
+ "continents": [
+ "Europe",
+ "North America"
+ ]
+ "continents_i18n":
+ @{
+ "de_DE" : [
+ "Europa",
+ "Nordamerika"
+ ],
+ "de_CH" : [
+ "Europa",
+ "Nordamerika"
+ ]
+ @}
+@}
+@end example
+
+Translations must be given in the same order as the main English array.
+
+@node Common transitions,Backup transitions,Initial state,Reducer transitions
+@anchor{reducer common-transitions}@anchor{61}
+@subsubsection Common transitions
+
+
+@strong{select_continent:}
+
+Here the user specifies the continent they live on. Arguments (example):
+
+@example
+@{
+ "continent": "Europe"
+@}
+@end example
+
+The continent must be given using the English name from the @code{continents} array.
+Using a translated continent name is invalid and may result in failure.
+
+The reducer returns an updated state with a list of countries to choose from,
+for example:
+
+@example
+@{
+ "backup_state": "COUNTRY_SELECTING",
+ "selected_continent": "Europe",
+ "countries": [
+ @{
+ "code": "ch",
+ "name": "Switzerland",
+ "continent": "Europe",
+ "name_i18n": @{
+ "de_DE": "Schweiz",
+ "de_CH": "Schwiiz",
+ "fr": "Suisse",
+ "en": "Swiss"
+ @},
+ "currency": "CHF"
+ @},
+ @{
+ "code": "de",
+ "name": "Germany",
+ "continent": "Europe",
+ "continent_i18n": @{
+ "de": "Europa"
+ @},
+ "name_i18n": @{
+ "de_DE": "Deutschland",
+ "de_CH": "Deutschland",
+ "fr": "Allemagne",
+ "en": "Germany"
+ @},
+ "currency": "EUR"
+ @}
+ ]
+@}
+@end example
+
+Here @code{countries} is an array of countries on the @code{selected_continent}. For
+each country, the @code{code} is the ISO 3166-1 alpha-2 country code. The
+@code{continent} is only present because some countries span continents, the
+information is redundant and will always match @code{selected_continent}. The
+@code{name} is the name of the country in English, internationalizations of the
+name may be provided in @code{name_i18n}. The @code{currency} is @strong{an} official
+currency of the country, if a country has multiple currencies, it may appear
+multiple times in the list. In this case, the user should select the entry
+with the currency they intend to pay with. It is also possible for users
+to select a currency that does not match their country, but user interfaces
+should by default try to use currencies that match the user’s residence.
+
+@strong{select_country:}
+
+Selects the country (via the country code) and specifies the currency.
+The latter is needed as some countries have more than one currency,
+and some use-cases may also involve users insisting on paying with
+foreign currency.
+
+Arguments (example):
+
+@example
+@{
+ "country_code": "de",
+ "currency": "EUR"
+@}
+@end example
+
+The @code{country_code} must be an ISO 3166-1 alpha-2 country code from
+the array of @code{countries} of the reducer’s state. The @code{currency}
+field must be a valid currency accepted by the Taler payment system.
+
+The reducer returns a new state with the list of attributes the
+user is expected to provide, as well as possible authentication
+providers that accept payments in the selected currency:
+
+@example
+@{
+ "backup_state": "USER_ATTRIBUTES_COLLECTING",
+ "selected_country": "de",
+ "currency": "EUR",
+ "required_attributes": [
+ @{
+ "type": "string",
+ "name": "full_name",
+ "label": "Full name",
+ "label_i18n": @{
+ "de_DE": "Vollstaendiger Name",
+ "de_CH": "Vollstaendiger. Name",
+ "fr": "Nom complet",
+ "en": "Full name"
+ @},
+ "widget": "anastasis_gtk_ia_full_name",
+ "uuid" : "9e8f463f-575f-42cb-85f3-759559997331"
+ @},
+ @{
+ "type": "date",
+ "name": "birthdate",
+ "label": "Birthdate",
+ "label_i18n": @{
+ "de_DE": "Geburtsdatum",
+ "de_CH": "Geburtsdatum",
+ "fr": "Date de naissance",
+ "en": "Birthdate"
+ @},
+ "uuid" : "83d655c7-bdb6-484d-904e-80c1058c8854"
+ "widget": "anastasis_gtk_ia_birthdate"
+ @},
+ @{
+ "type": "string",
+ "name": "tax_number",
+ "label": "Taxpayer identification number",
+ "label_i18n":@{
+ "de_DE": "Steuerliche Identifikationsnummer",
+ "de_CH": "Steuerliche Identifikationsnummer",
+ "en": "German taxpayer identification number"
+ @},
+ "widget": "anastasis_gtk_ia_tax_de",
+ "uuid": "dae48f85-e3ff-47a4-a4a3-ed981ed8c3c6",
+ "validation-regex": "^[0-9]@{11@}$",
+ "validation-logic": "DE_TIN_check"
+ @},
+ @{
+ "type": "string",
+ "name": "social_security_number",
+ "label": "Social security number",
+ "label_i18n": @{
+ "de_DE": "Sozialversicherungsnummer",
+ "de_CH": "Sozialversicherungsnummer",
+ "fr": "Numéro de sécurité sociale",
+ "en": "Social security number"
+ @},
+ "widget": "anastasis_gtk_ia_ssn",
+ "validation-regex": "^[0-9]@{8@}[[:upper:]][0-9]@{3@}$",
+ "validation-logic": "DE_SVN_check"
+ "optional" : true
+ @}
+ ],
+ "authentication_providers": @{
+ "http://localhost:8089/": @{
+ "http_status": 200,
+ "methods": [
+ @{ "type" : "question",
+ "usage_fee" : "EUR:0.0" @},
+ @{ "type" : "sms",
+ "usage_fee" : "EUR:0.5" @}
+ ],
+ "annual_fee": "EUR:4.99",
+ "truth_upload_fee": "EUR:4.99",
+ "liability_limit": "EUR:1",
+ "currency": "EUR",
+ "truth_lifetime": @{ "d_ms" : 50000000 @},
+ "storage_limit_in_megabytes": 1,
+ "provider_name": "Anastasis 4",
+ "salt": "CXAPCKSH9D3MYJTS9536RHJHCW"
+ @},
+ "http://localhost:8088/": @{
+ "http_status": 200,
+ "methods": [
+ @{ "type" : "question",
+ "usage_fee" : "EUR:0.01" @},
+ @{ "type" : "sms",
+ "usage_fee" : "EUR:0.55" @}
+ ],
+ "annual_fee": "EUR:0.99",
+ "truth_upload_fee": "EUR:3.99",
+ "liability_limit": "EUR:1",
+ "currency": "EUR",
+ "truth_lifetime": @{ "d_ms" : 50000000 @},
+ "storage_limit_in_megabytes": 1,
+ "provider_name": "Anastasis 4",
+ "salt": "CXAPCKSH9D3MYJTS9536RHJHCW"
+ @}
+ @}
+@}
+@end example
+
+The array of @code{required_attributes} contains attributes about the user
+that must be provided includes:
+
+@quotation
+
+
+@itemize -
+
+@item
+@strong{type}: The type of the attribute, for now only @code{string} and @code{date} are
+supported.
+
+@item
+@strong{name}: The name of the attribute, this is the key under which the
+attribute value must be provided later. The name must be unique per response.
+
+@item
+@strong{label}: A human-readable description of the attribute in English.
+Translated descriptions may be provided under @strong{label_i18n}.
+
+@item
+@strong{uuid}: A UUID that uniquely identifies identical attributes across
+different countries. Useful to preserve values should the user enter
+some attributes, and then switch to another country. Note that
+attributes must not be preserved if they merely have the same @strong{name},
+only the @strong{uuid} will be identical if the semantics is identical.
+
+@item
+@strong{widget}: An optional name of a widget that is known to nicely render
+the attribute entry in user interfaces where named widgets are
+supported.
+
+@item
+@strong{validation-regex}: An optional extended POSIX regular expression
+that is to be used to validate (string) inputs to ensure they are
+well-formed.
+
+@item
+@strong{validation-logic}: Optional name of a function that should be called
+to validate the input. If the function is not known to the particular
+client, the respective validation can be skipped (at the expense of
+typos by users not being detected, possibly rendering secrets
+irrecoverable).
+
+@item
+@strong{optional}: Optional boolean field that, if @code{true}, indicates that
+this attribute is not actually required but optional and users MAY leave
+it blank in case they do not have the requested information. Used for
+common fields that apply to some large part of the population but are
+not sufficiently universal to be actually required.
+@end itemize
+@end quotation
+
+The authentication providers are listed under a key that is the
+base URL of the service. For each provider, the following
+information is provided if the provider was successfully contacted:
+
+@quotation
+
+
+@itemize -
+
+@item
+@strong{http_status}: HTTP status code, always @code{200} on success.
+
+@item
+@strong{methods}: Array of authentication methods supported by this
+provider. Includes the @strong{type} of the authentication method
+and the @strong{usage_fee} (how much the user must pay for authorization
+using this method during recovery).
+
+@item
+@strong{annual_fee}: Fee the provider charges to store the recovery
+policy for one year.
+
+@item
+@strong{truth_upload_fee}: Fee the provider charges to store a key share.
+
+@item
+@strong{liability_limit}: Amount the provider can be held liable for in
+case a key share or recovery document cannot be recovered due to
+provider failures.
+
+@item
+@strong{currency}: Currency in which the provider wants to be paid,
+will match all of the fees.
+
+@item
+@strong{storage_limit_in_megabytes}: Maximum size of an upload (for
+both recovery document and truth data) in megabytes.
+
+@item
+@strong{provider_name}: Human-readable name of the provider’s business.
+
+@item
+@strong{salt}: Salt value used by the provider, used to derive the
+user’s identity at this provider. Should be unique per provider,
+and must never change for a given provider. The salt is
+base32 encoded.
+@end itemize
+@end quotation
+
+If contacting the provider failed, the information returned is:
+
+@quotation
+
+
+@itemize -
+
+@item
+@strong{http_status}: HTTP status code (if available, possibly 0 if
+we did not even obtain an HTTP response).
+
+@item
+@strong{error_code}: Taler error code, never 0.
+@end itemize
+@end quotation
+
+@strong{add_provider}:
+
+This operation can be performed in state @code{USER_ATTRIBUTES_COLLECTING}. It
+adds one or more Anastasis providers to the list of providers the reducer
+should henceforth consider. Note that removing providers is not possible at
+this time.
+
+Here, the client must provide an array with the base URLs of the
+providers to add, for example:
+
+@example
+@{
+ "urls": [
+ "http://localhost:8888/",
+ "http://localhost:8089/"
+ ]
+@}
+@end example
+
+Note that existing providers will remain in the state. The following is an
+example for an expected new state where the service on port 8089 is
+unreachable, the service on port 8088 was previously known, and service on
+port 8888 was now added:
+
+@example
+@{
+ "backup_state": "USER_ATTRIBUTES_COLLECTING",
+ "authentication_providers": @{
+ "http://localhost:8089/": @{
+ "error_code": 11,
+ "http_status": 0
+ @},
+ "http://localhost:8088/": @{
+ "http_status": 200,
+ "methods": [
+ @{ "type" : "question",
+ "usage_fee" : "EUR:0.01" @},
+ @{ "type" : "sms",
+ "usage_fee" : "EUR:0.55" @}
+ ],
+ "annual_fee": "EUR:0.99",
+ "truth_upload_fee": "EUR:3.99",
+ "liability_limit": "EUR:1",
+ "currency": "EUR",
+ "truth_lifetime": @{ "d_ms" : 50000000 @},
+ "storage_limit_in_megabytes": 1,
+ "provider_name": "Anastasis 4",
+ "salt": "CXAPCKSH9D3MYJTS9536RHJHCW"
+ @}
+ "http://localhost:8888/": @{
+ "methods": [
+ @{ "type" : "question",
+ "usage_fee" : "EUR:0.01" @},
+ @{ "type" : "sms",
+ "usage_fee" : "EUR:0.55" @}
+ ],
+ "annual_fee": "EUR:0.99",
+ "truth_upload_fee": "EUR:3.99",
+ "liability_limit": "EUR:1",
+ "currency": "EUR",
+ "truth_lifetime": @{ "d_ms" : 50000000 @},
+ "storage_limit_in_megabytes": 1,
+ "provider_name": "Anastasis 42",
+ "salt": "BXAPCKSH9D3MYJTS9536RHJHCX"
+ @}
+ @}
+@}
+@end example
+
+@node Backup transitions,Recovery transitions,Common transitions,Reducer transitions
+@anchor{reducer backup-transitions}@anchor{62}
+@subsubsection Backup transitions
+
+
+@strong{enter_user_attributes:}
+
+This transition provides the user’s personal attributes. The specific set of
+attributes required depends on the country of residence of the user. Some
+attributes may be optional, in which case they should be omitted entirely
+(that is, not simply be set to @code{null} or an empty string). Example
+arguments would be:
+
+@example
+@{
+ "identity_attributes": @{
+ "full_name": "Max Musterman",
+ "social_security_number": "123456789",
+ "birthdate": "2000-01-01",
+ "birthplace": "Earth"
+ @}
+@}
+@end example
+
+Note that at this stage, the state machines between backup and
+recovery diverge and the @code{recovery_state} will begin to look
+very different from the @code{backup_state}.
+
+For backups, if all required attributes are present, the reducer will
+transition to an @code{AUTHENTICATIONS_EDITING} state with the attributes added
+to it:
+
+@example
+@{
+ "backup_state": "AUTHENTICATIONS_EDITING",
+ "identity_attributes": @{
+ "full_name": "Max Musterman",
+ "social_security_number": "123456789",
+ "birthdate": "2000-01-01",
+ "birthplace": "Earth"
+ @}
+@}
+@end example
+
+If required attributes are missing, do not match the required regular
+expression, or fail the custom validation logic, the reducer SHOULD transition
+to an error state indicating what was wrong about the input. A reducer that
+does not support some specific validation logic MAY accept the invalid input
+and proceed anyway. The error state will include a Taler error code that
+is specific to the failure, and optional details. Example:
+
+@example
+@{
+ "backup_state": "ERROR",
+ "code": 8404,
+ "hint": "An input did not match the regular expression.",
+ "detail": "social_security_number"
+@}
+@end example
+
+Clients may safely repeat this transition to validate the user’s inputs
+until they satisfy all of the constraints. This way, the user interface
+does not have to perform the input validation directly.
+
+@strong{add_authentication}:
+
+This transition adds an authentication method. The method must be supported
+by one or more providers that are included in the current state. Adding an
+authentication method requires specifying the @code{type} and @code{instructions} to
+be given to the user. The @code{challenge} is encrypted and stored at the
+Anastasis provider. The specific semantics of the value depend on the
+@code{type}. Typical challenges values are a phone number (to send an SMS to),
+an e-mail address (to send a PIN code to) or the answer to a security
+question. Note that these challenge values will still be encrypted (and
+possibly hashed) before being given to the Anastasis providers.
+
+Note that the @code{challenge} must be given in Crockford Base32 encoding, as it
+MAY include binary data (such as a photograph of the user). In the latter
+case, the optional @code{mime_type} field must be provided to give the MIME type
+of the value encoded in @code{challenge}.
+
+@example
+@{
+ "authentication_method":
+ @{
+ "type": "question",
+ "mime_type" : "text/plain",
+ "instructions" : "What is your favorite GNU package?",
+ "challenge" : "E1QPPS8A",
+ @}
+@}
+@end example
+
+If the information provided is valid, the reducer will add the new
+authentication method to the array of authentication methods:
+
+@example
+@{
+ "backup_state": "AUTHENTICATIONS_EDITING",
+ "authentication_methods": [
+ @{
+ "type": "question",
+ "mime_type" : "text/plain",
+ "instructions" : "What is your favorite GNU package?",
+ "challenge" : "E1QPPS8A",
+ @},
+ @{
+ "type": "email",
+ "instructions" : "E-mail to user@@*le.com",
+ "challenge": "ENSPAWJ0CNW62VBGDHJJWRVFDM50"
+ @}
+ ]
+@}
+@end example
+
+@strong{delete_authentication}:
+
+This transition can be used to remove an authentication method from the
+array of authentication methods. It simply requires the index of the
+authentication method to remove. Note that the array is 0-indexed:
+
+@example
+@{
+ "authentication_method": 1
+@}
+@end example
+
+Assuming we begin with the state from the example above, this would
+remove the @code{email} authentication method, resulting in the following
+response:
+
+@example
+@{
+ "backup_state": "AUTHENTICATIONS_EDITING",
+ "authentication_methods": [
+ @{
+ "type": "question",
+ "mime_type" : "text/plain",
+ "instructions" : "What is your favorite GNU package?",
+ "challenge" : "gdb",
+ @}
+ ]
+@}
+@end example
+
+If the index is invalid, the reducer will instead
+transition into an @code{ERROR} state.
+
+@strong{next} (from @code{AUTHENTICATIONS_EDITING}):
+
+This transition confirms that the user has finished adding (or removing)
+authentication methods, and that the system should now automatically compute
+a set of reasonable recovery policies.
+
+This transition does not take any mandatory arguments. Optional arguments can
+be provided to upload the recovery document only to a specific subset of the
+providers:
+
+@example
+@{
+ "providers": [
+ "http://localhost:8088/",
+ "http://localhost:8089/"
+ ]
+@}
+@end example
+
+The resulting state provides the suggested recovery policies in a way suitable
+for presentation to the user:
+
+@example
+@{
+ "backup_state": "POLICIES_REVIEWING",
+ "policy_providers" : [
+ @{ "provider_url" : "http://localhost:8088/" @},
+ @{ "provider_url" : "http://localhost:8089/" @}
+ ],
+ "policies": [
+ @{
+ "methods": [
+ @{
+ "authentication_method": 0,
+ "provider": "http://localhost:8088/"
+ @},
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 2,
+ "provider": "http://localhost:8087/"
+ @}
+ ]
+ @},
+ @{
+ "methods": [
+ @{
+ "authentication_method": 0,
+ "provider": "http://localhost:8088/"
+ @},
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 3,
+ "provider": "http://localhost:8089/"
+ @}
+ ]
+ @}
+ ]
+@}
+@end example
+
+For each recovery policy, the state includes the specific details of which
+authentication @code{methods} must be solved to recovery the secret using this
+policy. The @code{methods} array specifies the index of the
+@code{authentication_method} in the @code{authentication_methods} array, as well as
+the provider that was selected to supervise this authentication.
+
+If no authentication method was provided, the reducer will transition into an
+@code{ERROR} state instead of suggesting policies.
+
+@strong{add_policy}:
+
+Using this transition, the user can add an additional recovery policy to the
+state. The argument format is the same that is used in the existing state.
+An example for a possible argument would thus be:
+
+@example
+@{
+ "policy": [
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8088/"
+ @},
+ @{
+ "authentication_method": 3,
+ "provider": "http://localhost:8089/"
+ @}
+ ]
+@}
+@end example
+
+Note that the specified providers must already be in the
+@code{authentication_providers} of the state. You cannot add new providers at
+this stage. The reducer will simply attempt to append the suggested policy to
+the “policies” array, returning an updated state:
+
+@example
+@{
+ "backup_state": "POLICIES_REVIEWING",
+ "policies": [
+ @{
+ "methods": [
+ @{
+ "authentication_method": 0,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8088/"
+ @}
+ ]
+ @},
+ @{
+ "methods": [
+ @{
+ "authentication_method": 0,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 2,
+ "provider": "http://localhost:8088/"
+ @}
+ ]
+ @},
+ @{
+ "methods": [
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 2,
+ "provider": "http://localhost:8088/"
+ @}
+ ]
+ @},
+ @{
+ "methods": [
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8088/"
+ @},
+ @{
+ "authentication_method": 3,
+ "provider": "http://localhost:8089/"
+ @}
+ ]
+ @}
+ ]
+@}
+@end example
+
+If the new policy is invalid, for example because it adds an unknown
+authentication method, or the selected provider does not support the type of
+authentication, the reducer will transition into an @code{ERROR} state instead of
+adding the new policy.
+
+@strong{update_policy}:
+
+Using this transition, the user can modify an existing recovery policy
+in the state.
+The argument format is the same that is used in @strong{add_policy},
+except there is an additional key @code{policy_index} which
+identifies the policy to modify.
+An example for a possible argument would thus be:
+
+@example
+@{
+ "policy_index" : 1,
+ "policy": [
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8088/"
+ @},
+ @{
+ "authentication_method": 3,
+ "provider": "http://localhost:8089/"
+ @}
+ ]
+@}
+@end example
+
+If the new policy is invalid, for example because it adds an unknown
+authentication method, or the selected provider does not support the type of
+authentication, the reducer will transition into an @code{ERROR} state instead of
+modifying the policy.
+
+@strong{delete_policy:}
+
+This transition allows the deletion of a recovery policy. The argument
+simply specifies the index of the policy to delete, for example:
+
+@example
+@{
+ "policy_index": 3
+@}
+@end example
+
+Given as input the state from the example above, the expected new state would
+be:
+
+@example
+@{
+ "backup_state": "POLICIES_REVIEWING",
+ "policies": [
+ @{
+ "methods": [
+ @{
+ "authentication_method": 0,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8088/"
+ @}
+ ]
+ @},
+ @{
+ "methods": [
+ @{
+ "authentication_method": 0,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 2,
+ "provider": "http://localhost:8088/"
+ @}
+ ]
+ @},
+ @{
+ "methods": [
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 2,
+ "provider": "http://localhost:8088/"
+ @}
+ ]
+ @}
+ ]
+@}
+@end example
+
+If the index given is invalid, the reducer will transition into an @code{ERROR} state
+instead of deleting a policy.
+
+@strong{delete_challenge:}
+
+This transition allows the deletion of an individual
+challenge from a recovery policy. The argument
+simply specifies the index of the policy and challenge
+to delete, for example:
+
+@example
+@{
+ "policy_index": 1,
+ "challenge_index" : 1
+@}
+@end example
+
+Given as input the state from the example above, the expected new state would
+be:
+
+@example
+@{
+ "backup_state": "POLICIES_REVIEWING",
+ "policies": [
+ @{
+ "methods": [
+ @{
+ "authentication_method": 0,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8088/"
+ @}
+ ]
+ @},
+ @{
+ "methods": [
+ @{
+ "authentication_method": 0,
+ "provider": "http://localhost:8089/"
+ @}
+ ]
+ @},
+ @{
+ "methods": [
+ @{
+ "authentication_method": 1,
+ "provider": "http://localhost:8089/"
+ @},
+ @{
+ "authentication_method": 2,
+ "provider": "http://localhost:8088/"
+ @}
+ ]
+ @}
+ ]
+@}
+@end example
+
+If the index given is invalid, the reducer will transition into an @code{ERROR} state
+instead of deleting a challenge.
+
+@strong{next} (from @code{POLICIES_REVIEWING}):
+
+Using this transition, the user confirms that the policies in the current
+state are acceptable. The transition does not take any arguments.
+
+The reducer will simply transition to the @code{SECRET_EDITING} state:
+
+@example
+@{
+ "backup_state": "SECRET_EDITING",
+ "upload_fees" : [ "KUDOS:42" ],
+ "expiration" : @{ "t_ms" : 1245362362 @}
+@}
+@end example
+
+Here, @code{upload_fees} is an array of applicable upload fees for the
+given policy expiration time. This is an array because fees could
+be in different currencies. The final cost may be lower if the
+user already paid for some of the time.
+
+If the array of @code{policies} is currently empty, the reducer will transition
+into an @code{ERROR} state instead of allowing the user to continue.
+
+@strong{enter_secret:}
+
+This transition provides the reducer with the actual core @code{secret} of the user
+that Anastasis is supposed to backup (and possibly recover). The argument is
+simply the Crockford-Base32 encoded @code{value} together with its @code{mime} type, or a @code{text} field with a human-readable secret text.
+For example:
+
+@example
+@{
+ "secret": @{
+ "value": "EDJP6WK5EG50",
+ "mime" : "text/plain"
+ @},
+ "expiration" : @{ "t_ms" : 1245362362 @}
+@}
+@end example
+
+If the application is unaware of the format, it set the @code{mime} field to @code{null}.
+The @code{expiration} field is optional.
+
+The reducer remains in the @code{SECRET_EDITING} state, but now the secret and
+updated expiration time are part of the state and the cost calculations will
+be updated.
+
+@example
+@{
+ "backup_state": "SECRET_EDITING",
+ "core_secret" : @{
+ "value": "EDJP6WK5EG50",
+ "mime" : "text/plain"
+ @},
+ "expiration" : @{ "t_ms" : 1245362362 @},
+ "upload_fees" : [ "KUDOS:42" ]
+@}
+@end example
+
+@strong{clear_secret:}
+
+This transition removes the core secret from the state. It is simply a
+convenience function to undo @code{enter_secret} without providing a new value
+immediately. The transition takes no arguments. The resuting state will no
+longer have the @code{core_secret} field, and be otherwise unchanged. Calling
+@strong{clear_secret} on a state without a @code{core_secret} will result in an error.
+
+@strong{enter_secret_name:}
+
+This transition provides the reducer with a name for the core @code{secret} of the user. This name will be given to the user as a hint when seleting a recovery policy document during recovery, prior to satisfying any of the challenges. The argument simply contains the name for the secret.
+Applications that have built-in support for Anastasis MUST prefix the
+secret name with an underscore and an application-specific identifier
+registered in GANA so that they can use recognize their own backups.
+An example argument would be:
+
+@example
+@{
+ "name": "_TALERWALLET_MyPinePhone",
+@}
+@end example
+
+Here, @code{MyPinePhone} might be chosen by the user to identify the
+device that was being backed up.
+
+The reducer remains in the @code{SECRET_EDITING} state, but now the
+secret name is updated:
+
+@example
+@{
+ "secret_name" : "_TALERWALLET_MyPinePhone"
+@}
+@end example
+
+@strong{update_expiration:}
+
+This transition asks the reducer to change the desired expiration time
+and to update the associated cost. For example:
+
+@example
+@{
+ "expiration" : @{ "t_ms" : 1245362362 @}
+@}
+@end example
+
+The reducer remains in the @code{SECRET_EDITING} state, but the
+expiration time and cost calculation will be updated.
+
+@example
+@{
+ "backup_state": "SECRET_EDITING",
+ "expiration" : @{ "t_ms" : 1245362362 @},
+ "upload_fees" : [ @{ "fee": "KUDOS:43" @} ]
+@}
+@end example
+
+@strong{next} (from @code{SECRET_EDITING}):
+
+Using this transition, the user confirms that the secret and expiration
+settings in the current state are acceptable. The transition does not take any
+arguments.
+
+If the secret is currently empty, the reducer will transition into an
+@code{ERROR} state instead of allowing the user to continue.
+
+After adding a secret, the reducer may transition into different states
+depending on whether payment(s) are necessary. If payments are needed, the
+@code{secret} will be stored in the state under @code{core_secret}. Applications
+should be careful when persisting the resulting state, as the @code{core_secret}
+is not protected in the @code{PAYING} states. The @code{PAYING} states only differ
+in terms of what the payments are for (key shares or the recovery document),
+in all cases the state simply includes an array of Taler URIs that refer to
+payments that need to be made with the Taler wallet.
+
+If all payments are complete, the reducer will transition into the
+@code{BACKUP_FINISHED} state and (if applicable) delete the @code{core_secret} as an
+additional safety measure.
+
+Example results are thus:
+
+@example
+@{
+ "backup_state": "TRUTHS_PAYING",
+ "secret_name" : "$NAME",
+ "core_secret" : @{ "$anything":"$anything" @},
+ "payments": [
+ "taler://pay/...",
+ "taler://pay/..."
+ ]
+@}
+@end example
+
+@example
+@{
+ "backup_state": "POLICIES_PAYING",
+ "secret_name" : "$NAME",
+ "core_secret" : @{ "$anything":"$anything" @},
+ "payments": [
+ "taler://pay/...",
+ "taler://pay/..."
+ ]
+@}
+@end example
+
+@example
+@{
+ "backup_state": "BACKUP_FINISHED",
+@}
+@end example
+
+@strong{pay:}
+
+This transition suggests to the reducer that a payment may have been made or
+is immanent, and that the reducer should check with the Anastasis service
+provider to see if the operation is now possible. The operation takes one
+optional argument, which is a @code{timeout} value that specifies how long the
+reducer may wait (in long polling) for the payment to complete:
+
+@example
+@{
+ "timeout": @{ "d_ms" : 5000 @},
+@}
+@end example
+
+The specified timeout is passed on to the Anastasis service provider(s), which
+will wait this long before giving up. If no timeout is given, the check is
+done as quickly as possible without additional delays. The reducer will continue
+to either an updated state with the remaining payment requests, to the
+@code{BACKUP_FINISHED} state (if all payments have been completed and the backup
+finished), or into an @code{ERROR} state in case there was an irrecoverable error,
+indicating the specific provider and how it failed. An example for this
+final error state would be:
+
+@example
+@{
+ "backup_state": "ERROR",
+ "http_status" : 500,
+ "upload_status" : 52,
+ "provider_url" : "https://bad.example.com/",
+@}
+@end example
+
+Here, the fields have the following meaning:
+
+@quotation
+
+
+@itemize -
+
+@item
+@strong{http_status} is the HTTP status returned by the Anastasis provider.
+
+@item
+@strong{upload_status} is the Taler error code return by the provider.
+
+@item
+@strong{provider_url} is the base URL of the failing provider.
+@end itemize
+@end quotation
+
+In the above example, 52 would thus imply that the Anastasis provider failed to
+store information into its database.
+
+@node Recovery transitions,,Backup transitions,Reducer transitions
+@anchor{reducer recovery-transitions}@anchor{63}
+@subsubsection Recovery transitions
+
+
+@strong{enter_user_attributes:}
+
+This transition provides the user’s personal attributes. The specific set of
+attributes required depends on the country of residence of the user. Some
+attributes may be optional, in which case they should be omitted entirely
+(that is, not simply be set to @code{null} or an empty string). The
+arguments are identical to the @strong{enter_user_attributes} transition from
+the backup process. Example arguments would thus be:
+
+@example
+@{
+ "identity_attributes": @{
+ "full_name": "Max Musterman",
+ "social_security_number": "123456789",
+ "birthdate": "2000-01-01",
+ "birthplace": "Earth"
+ @}
+@}
+@end example
+
+However, in contrast to the backup process, the reducer will attempt to
+retrieve the latest recovery document from all known providers for the
+selected currency given the above inputs. If a recovery document was found
+by any provider, the reducer will attempt to load it and transition to
+a state where the user can choose which challenges to satisfy:
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": @{
+ "challenges": [
+ @{
+ "uuid": "MW2R3RCBZPHNC78AW8AKWRCHF9KV3Y82EN62T831ZP54S3K5599G",
+ "cost": "TESTKUDOS:0",
+ "type": "question",
+ "instructions": "q1"
+ @},
+ @{
+ "uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "cost": "TESTKUDOS:0",
+ "type": "email",
+ "instructions": "e-mail address m?il@@f*.bar"
+ @},
+ ],
+ "policies": [
+ [
+ @{
+ "uuid": "MW2R3RCBZPHNC78AW8AKWRCHF9KV3Y82EN62T831ZP54S3K5599G"
+ @},
+ @{
+ "uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0"
+ @},
+ ],
+ ],
+ "provider_url": "http://localhost:8088/",
+ "version": 1,
+ @},
+ "recovery_document": @{
+ "...": "..."
+ @}
+@}
+@end example
+
+The @code{recovery_document} is an internal representation of the recovery
+information and of no concern to the user interface. The pertinent information
+is in the @code{recovery_information}. Here, the @code{challenges} array is a list
+of possible challenges the user could attempt to solve next, while @code{policies}
+is an array of policies, with each policy being an array of challenges.
+Satisfying all of the challenges of one of the policies will enable the secret
+to be recovered. The @code{provider_url} from where the recovery document was
+obtained and its @code{version} are also provided. Each challenge comes with
+four mandatory fields:
+
+@quotation
+
+
+@itemize -
+
+@item
+@strong{uuid}: A unique identifier of the challenge; this is what the
+UUIDs in the policies array refer to, but also this UUID may be
+included in messages sent to the user. They allow the user to
+distinguish different PIN/TANs should say the same phone number be
+used for SMS-authentication with different providers.
+
+@item
+@strong{cost}: This is the amount the Anastasis provider will charge
+to allow the user to pass the challenge.
+
+@item
+@strong{type}: This is the type of the challenge, as a string.
+
+@item
+@strong{instructions}: Contains additional important hints for the user
+to allow the user to satisfy the challenge. It typically includes
+an abbreviated form of the contact information or the security
+question. Details depend on @code{type}.
+@end itemize
+@end quotation
+
+If a recovery document was not found, either the user never performed
+a backup, entered incorrect attributes, or used a provider not yet in
+the list of Anastasis providers. Hence, the user must now either
+select a different provider, or go @code{back} and update the identity
+attributes. In the case a recovery document was not found, the
+transition fails, returning the error code and a human-readable error
+message together with a transition failure:
+
+@example
+@{
+ "recovery_state": "ERROR",
+ "error_message": "account unknown to Anastasis server",
+ "error_code": 9,
+@}
+@end example
+
+Here, the @code{error_code} is from the @code{enum ANASTASIS_RecoveryStatus}
+and describes precisely what failed about the download, while the
+@code{error_message} is a human-readable (English) explanation of the code.
+Applications may want to translate the message using GNU gettext;
+translations should be available in the @code{anastasis} text domain.
+However, in general it should be sufficient to display the slightly
+more generic Taler error code that is returned with the new state.
+
+@strong{change_version:}
+
+Even if a recovery document was found, it is possible that the user
+intended to recover a different version, or recover a backup where
+the recovery document is stored at a different provider. Thus, the
+reducer allows the user to explicitly switch to a different provider
+or recovery document version using the @code{change_version} transition,
+which takes a provider URL and policy version as arguments:
+
+@example
+@{
+ "provider_url": "https://localhost:8080/",
+ "version": 2
+@}
+@end example
+
+Note that using a version of 0 implies fetching “the latest version”. The
+resulting states are the same as those of the @code{enter_user_attributes}
+transition, except that the recovery document version is not necessarily the
+latest available version at the provider.
+
+@strong{select_challenge:}
+
+Selecting a challenge takes different, depending on the state of the payment.
+A comprehensive example for @code{select_challenge} would be:
+
+@example
+@{
+ "uuid": "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30"
+ "timeout" : @{ "d_ms" : 5000 @},
+ "payment_secret": "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG"
+@}
+@end example
+
+The @code{uuid} field is mandatory and specifies the selected challenge.
+The other fields are optional, and are needed in case the user has
+previously been requested to pay for the challenge. In this case,
+the @code{payment_secret} identifies the previous payment request, and
+@code{timeout} says how long the Anastasis service should wait for the
+payment to be completed before giving up (long polling).
+
+Depending on the type of the challenge and the need for payment, the
+reducer may transition into @code{CHALLENGE_SOLVING} or @code{CHALLENGE_PAYING}
+states. In @code{CHALLENGE_SOLVING}, the new state will primarily specify
+the selected challenge:
+
+@example
+@{
+ "backup_state": "CHALLENGE_SOLVING",
+ "selected_challenge_uuid": "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30"
+@}
+@end example
+
+In @code{CHALLENGE_PAYING}, the new state will include instructions for payment
+in the @code{challenge_feedback}. In general, @code{challenge_feedback} includes
+information about attempted challenges, with the final state being @code{solved}:
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": @{
+ "...": "..."
+ @}
+ "challenge_feedback": @{
+ "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30" : @{
+ "state" : "solved"
+ @}
+ @}
+@}
+@end example
+
+Challenges feedback for a challenge can have many different @code{state} values
+that applications must all handle. States other than @code{solved} are:
+
+@quotation
+
+
+@itemize -
+
+@item
+@strong{payment}: Here, the user must pay for a challenge. An example would be:
+
+@example
+@{
+ "backup_state": "CHALLENGE_PAYING",
+ "selected_challenge_uuid": "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30",
+ "challenge_feedback": @{
+ "80H646H5ZBR453C02Y5RT55VQSJZGM5REWFXVY0SWXY1TNE8CT30" : @{
+ "state" : "payment",
+ "taler_pay_uri" : "taler://pay/...",
+ "provider" : "https://localhost:8080/",
+ "payment_secret" : "3P4561HAMHRRYEYD6CM6J7TS5VTD5SR2K2EXJDZEFSX92XKHR4KG"
+ @}
+ @}
+@}
+@end example
+@end itemize
+
+@quotation
+
+
+@itemize -
+
+@item
+@strong{body}: Here, the server provided an HTTP reply for
+how to solve the challenge, but the reducer could not parse
+them into a known format. A mime-type may be provided and may
+help parse the details.
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SOLVING",
+ "recovery_information": @{
+ "...": "..."
+ @}
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": @{
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{
+ "state": "body",
+ "body": "CROCKFORDBASE32ENCODEDBODY",
+ "http_status": 403,
+ "mime_type" : "anything/possible"
+ @}
+ @}
+@}
+@end example
+
+@item
+@strong{hint}: Here, the server provided human-readable hint for
+how to solve the challenge. Note that the @code{hint} provided this
+time is from the Anastasis provider and may differ from the @code{instructions}
+for the challenge under @code{recovery_information}:
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SOLVING",
+ "recovery_information": @{
+ "...": "..."
+ @}
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": @{
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{
+ "state": "hint",
+ "hint": "Recovery TAN send to email mail@@DOMAIN",
+ "http_status": 403
+ @}
+ @}
+@}
+@end example
+
+@item
+@strong{details}: Here, the server provided a detailed JSON status response
+related to solving the challenge:
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SOLVING",
+ "recovery_information": @{
+ "...": "..."
+ @}
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": @{
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{
+ "state": "details",
+ "details": @{
+ "code": 8111,
+ "hint": "The client's response to the challenge was invalid.",
+ "detail" : null
+ @},
+ "http_status": 403
+ @}
+ @}
+@}
+@end example
+@end itemize
+
+@quotation
+
+
+@itemize -
+
+@item
+@strong{redirect}: To solve the challenge, the user must visit the indicated
+Web site at @code{redirect_url}, for example to perform video authentication:
+@end itemize
+
+@quotation
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SOLVING",
+ "recovery_information": @{
+ "...": "..."
+ @}
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": @{
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{
+ "state": "redirect",
+ "redirect_url": "https://videoconf.example.com/",
+ "http_status": 303
+ @}
+ @}
+@}
+@end example
+
+
+@itemize -
+
+@item
+@strong{server-failure}: This indicates that the Anastasis provider encountered
+a failure and recovery using this challenge cannot proceed at this time.
+Examples for failures might be that the provider is unable to send SMS
+messages at this time due to an outage. The body includes details about
+the failure. The user may try again later or continue with other challenges.
+@end itemize
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": @{
+ "...": "..."
+ @}
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": @{
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{
+ "state": "server-failure",
+ "http_status": "500",
+ "error_code": 52
+ @}
+ @}
+@}
+@end example
+
+
+@itemize -
+
+@item
+@strong{truth-unknown}: This indicates that the Anastasis provider is unaware of
+the specified challenge. This is typically a permanent failure, and user
+interfaces should not allow users to re-try this challenge.
+@end itemize
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": @{
+ "...": "..."
+ @}
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": @{
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{
+ "state": "truth-unknown",
+ "error_code": 8108
+ @}
+ @}
+@}
+@end example
+
+
+@itemize -
+
+@item
+@strong{rate-limit-exceeded}:
+@end itemize
+
+@example
+@{
+ "recovery_state": "CHALLENGE_SELECTING",
+ "recovery_information": @{
+ "...": "..."
+ @}
+ "selected_challenge_uuid": "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0",
+ "challenge_feedback": @{
+ "TXYKGE1SJZHJ4M2FKSV1P2RZVNTHZFB9E3A79QE956D3SCAWXPK0": @{
+ "state": "rate-limit-exceeded",
+ "error_code": 8121
+ @}
+ @}
+@}
+@end example
+@end quotation
+@end quotation
+@end quotation
+@end quotation
+
+@strong{pay:}
+
+With a @code{pay} transition, the application indicates to the reducer that
+a payment may have been made. Here, it is again possible to specify an
+optional @code{timeout} argument for long-polling, for example:
+
+@example
+@{
+ "payment_secret": "ABCDADF242525AABASD52525235ABABFDABABANALASDAAKASDAS"
+ "timeout" : @{ "d_ms" : 5000 @},
+@}
+@end example
+
+Depending on the type of the challenge and the result of the operation, the
+new state may be @code{CHALLENGE_SOLVING} (if say the SMS was now sent to the
+user), @code{CHALLENGE_SELECTING} (if the answer to the security question was
+correct), @code{RECOVERY_FINISHED} (if this was the last challenge that needed to
+be solved) or still @code{CHALLENGE_PAYING} (if the challenge was not actually
+paid for). For sample messages, see the different types of
+@code{challenge_feedback} in the section about @code{select_challenge}.
+
+@strong{solve_challenge:}
+
+Solving a challenge takes various formats, depending on the type of the
+challenge and what is known about the answer. The different supported
+formats are:
+
+@example
+@{
+ "answer": "answer to security question"
+@}
+@end example
+
+@example
+@{
+ "pin": 1234
+@}
+@end example
+
+@example
+@{
+ "hash": "SOMEBASE32ENCODEDHASHVALUE"
+@}
+@end example
+
+@c This file is part of Anastasis
+@c Copyright (C) 2019-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+@c @author Dominik Meister
+@c @author Dennis Neufeld
+
+@node Authentication Methods,DB Schema,Reducer API,Documentation Overview
+@anchor{authentication doc}@anchor{64}@anchor{authentication anastasis-auth-methods}@anchor{65}@anchor{authentication authentication-methods}@anchor{66}
+@section Authentication Methods
+
+
+This section describes the supported authentication methods in detail. We
+note that the server implements rate limiting for all authentication methods
+to ensure that malicious strong attackers cannot guess the values by
+brute-force. Typically, a user is given three attempts per hour to enter the
+correct code from 2^63 possible values. Transmitted codes also come with an
+expiration date. If the user re-requests a challenge to be sent, the same
+challenge may be transmitted (with the three attempts counter not increasing!)
+for a limited period of time (depending on the authentication method) before
+the service eventually rotates to a fresh random code with a fresh retry
+counter. Given the default value range and time intervals (which providers are
+at liberty to adjust), brute-force attacks against this are expected to
+succeed with a 50% probability after about 200000 years of attempts at the
+maximum permissible frequency.
+
+@menu
+* SMS (sms): SMS sms.
+* Email verification (email): Email verification email.
+* Video identification (vid): Video identification vid.
+* Security question (qa): Security question qa.
+* Snail mail verification (post): Snail mail verification post.
+
+@end menu
+
+@node SMS sms,Email verification email,,Authentication Methods
+@anchor{authentication sms-sms}@anchor{67}
+@subsection SMS (sms)
+
+
+Sends an SMS with a code (prefixed with @code{A-}) to the user’s phone, including
+a UUID which identifies the challenge the code is for. The user must send
+this code back with his request (see @code{$RESPONSE} under @ref{52,,Managing truth}).
+If the transmitted code is correct, the server responses with the requested
+encrypted key share.
+
+@node Email verification email,Video identification vid,SMS sms,Authentication Methods
+@anchor{authentication email-verification-email}@anchor{68}
+@subsection Email verification (email)
+
+
+Sends an email with a code (prefixed with @code{A-}) to the user’s mail address,
+including a UUID which identifies the challenge the code is for. The user
+must send this code back with his request (see @code{$RESPONSE} under @ref{52,,Managing truth}).
+If the transmitted code is correct, the server responses with the
+requested encrypted key share.
+
+@node Video identification vid,Security question qa,Email verification email,Authentication Methods
+@anchor{authentication video-identification-vid}@anchor{69}
+@subsection Video identification (vid)
+
+
+Requires the user to identify via video-call. In the video-call, the
+user is told the code (prefixed with @code{A-}) needed to authenticate.
+
+The user is expected to delete all metadata revealing personal information
+from the images before uploading them. Since the respective images must be
+passed on to the video identification service in the event of password
+recovery, it should be ensured that no further information about the user can
+be derived from them.
+
+Video identification will typically result in the Anastasis provider
+requesting the user to be redirected to a Web site (or other URL) for the
+video-call.
+
+@node Security question qa,Snail mail verification post,Video identification vid,Authentication Methods
+@anchor{authentication security-question-qa}@anchor{6a}
+@subsection Security question (qa)
+
+
+Asks the user a security question. The user sends back a @strong{salted}
+hash over the answer. The @strong{question-salt} is stored encrypted as
+part of the recovery document and never revealed to the providers. This
+ensures that providers cannot derive the answer from the hash value.
+Furthermore, the security question itself is also only in the recovery
+document and never given to the Anastasis provider. A moderately expensive
+hash function is used to further limit strong attackers that have obtained
+the recovery document from brute-forcing the answer.
+
+If the hash value matches with the one the server is expecting, the server
+answers with the requested encrypted key share. However, unlike other
+encrypted key shares, the encrypted key share of a security question uses a
+special variation of the Anastasis encryption: Here, a different hash function
+over the security answer is used to provide an additional @strong{key-salt} for the
+decryption of the (encrypted) @strong{key share}. This ensures that the key share
+remains irrecoverable without the answer even if the Anastasis provider
+storing the security question is malicious.
+
+@node Snail mail verification post,,Security question qa,Authentication Methods
+@anchor{authentication snail-mail-verification-post}@anchor{6b}
+@subsection Snail mail verification (post)
+
+
+Sends physical mail (snail mail) with a code (prefixed with @code{A-}) to the
+user’s mail address, including a UUID which identifies the challenge the code
+is for. The user must send this code back with their request (see
+@code{$RESPONSE} under @ref{52,,Managing truth}). If the transmitted code is correct,
+the server responds with the requested encrypted key share.
+
+@c This file is part of Anastasis
+@c Copyright (C) 2019-2021 Anastasis SARL
+@c
+@c Anastasis is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU Affero General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+@c
+@c You should have received a copy of the GNU Affero General Public License along with
+@c Anastasis; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+@c @author Dominik Meister
+@c @author Dennis Neufeld
+
+@node DB Schema,Design Documents,Authentication Methods,Documentation Overview
+@anchor{db doc}@anchor{6c}@anchor{db db-schema}@anchor{6d}
+@section DB Schema
+
+
+@image{anastasis-figures/anastasis-db,,,,png}
+
+@image{anastasis-figures/anastasis_challengecode,,,,png}
+
+@image{anastasis-figures/anastasis_challenge_payment,,,,png}
+
+@image{anastasis-figures/anastasis_truth,,,,png}
+
+@image{anastasis-figures/anastasis_truth_payment,,,,png}
+
+@node Design Documents,Anastasis licensing information,DB Schema,Documentation Overview
+@anchor{design-documents/index doc}@anchor{6e}@anchor{design-documents/index design-documents}@anchor{6f}
+@section Design Documents
+
+
+This is a collection of design documents related to Anastasis.
+The goal of these documents is to discuss facilitate discussion around
+new features while keeping track of the evolution of the whole system
+and protocol.
+
+@menu
+* Design Doc 001; Anastasis User Experience: Design Doc 001 Anastasis User Experience.
+* Template::
+
+@end menu
+
+@node Design Doc 001 Anastasis User Experience,Template,,Design Documents
+@anchor{design-documents/001-anastasis-ux doc}@anchor{70}@anchor{design-documents/001-anastasis-ux design-doc-001-anastasis-user-experience}@anchor{71}
+@subsection Design Doc 001: Anastasis User Experience
+
+
+@menu
+* Summary::
+* Motivation::
+* Setup Steps::
+* Show Service Status After Setup::
+* Recovery Steps::
+
+@end menu
+
+@node Summary,Motivation,,Design Doc 001 Anastasis User Experience
+@anchor{design-documents/001-anastasis-ux summary}@anchor{72}
+@subsubsection Summary
+
+
+This document describes the recommended way of implementing the user experience
+of setting up and making use of @ref{3,,Introduction} account recovery.
+
+@node Motivation,Setup Steps,Summary,Design Doc 001 Anastasis User Experience
+@anchor{design-documents/001-anastasis-ux motivation}@anchor{73}
+@subsubsection Motivation
+
+
+Wallet state consisting of digital cash, transaction history etc. should not be lost.
+Taler provides a backup mechanism to prevent that.
+As an additional protection measure Anastasis can be used to provide access to the backup,
+even if all devices and offline secrets have been lost.
+
+Access to the backup key is shared with escrow providers that can be chosen by the user.
+
+@node Setup Steps,Show Service Status After Setup,Motivation,Design Doc 001 Anastasis User Experience
+@anchor{design-documents/001-anastasis-ux setup-steps}@anchor{74}
+@subsubsection Setup Steps
+
+@image{graphviz-2d8d83202d2b7835498d2a5c18fa9e3cc05c4b6a,,,[graphviz],png}
+
+@menu
+* Entry point; Settings: Entry point Settings.
+* Providing Identification::
+* Add Authentication Methods::
+* Confirm/Change Service Providers::
+* Defining Recovery Options::
+* Pay for Setup::
+
+@end menu
+
+@node Entry point Settings,Providing Identification,,Setup Steps
+@anchor{design-documents/001-anastasis-ux entry-point-settings}@anchor{75}
+@subsubsection Entry point: Settings
+
+
+The app settings should have a section for Anastasis using a different more
+universally understood name like Wallet Recovery.
+
+The section should have an option to setup Anastasis initially. This option
+should be disabled as long as no backup has been set up. The section could
+maybe be integrated into the backup settings.
+
+@image{anastasis-figures/menu,,,,png}
+
+@image{anastasis-figures/settings,,,,png}
+
+@image{anastasis-figures/backupsettings,,,,png}
+
+@node Providing Identification,Add Authentication Methods,Entry point Settings,Setup Steps
+@anchor{design-documents/001-anastasis-ux providing-identification}@anchor{76}
+@subsubsection Providing Identification
+
+
+Instead of a forgettable freely chosen user name, Anastasis collects various
+static information from the user to generate a unique user identifier from
+that. Examples for such identifier would be a concatenation of the full name
+of the user and their social security or passport number(s).
+
+The information that can reasonably used here various from cultural context
+and jurisdiction. Therefore, one idea is to start by asking for continent and
+then the country of primary legal residence, and then continue from there with
+country-specific attributes (and also offer a stateless person option).
+
+Special care should be taken to avoid that information can later be provided
+ambiguously thus changing the user identifier and not being able to restore
+the user’s data. This can be typographic issues like someone providing
+“Seestr.” and later “Seestrasse” or “Seestraße” or “seestrasse”. But it can
+also be simple typos that we can only prevent in some instances like when
+checking checksums in passport numbers.
+
+The user should be made aware that this data will not leave the app and that
+it is only used to compute a unique identifier that can not be forgotten.
+
+If possible, we should guide the user in the country selection by accessing
+permission-less information such as the currently set language/locale and the
+country of the SIM card. But nothing invasive like the actual GPS location.
+
+@image{anastasis-figures/userid,,,,png}
+
+@node Add Authentication Methods,Confirm/Change Service Providers,Providing Identification,Setup Steps
+@anchor{design-documents/001-anastasis-ux add-authentication-methods}@anchor{77}
+@subsubsection Add Authentication Methods
+
+
+After creating a unique identifier, the user can chose one or more
+@ref{65,,Authentication Methods} supported by Anastasis.
+
+When selecting a method, the user is already asked to provide the information
+required for the recovery with that method. For example, a photo of
+themselves, their phone number or mailing address.
+
+The user interface validates that the inputs are well-formed, and refuses
+inputs that are clearly invalid. Where possible, it pre-fills the fields with
+sane values (phone number, e-mail addresses, country of residence).
+
+@image{anastasis-figures/truth,,,,png}
+
+@image{anastasis-figures/addtruth,,,,png}
+
+@image{anastasis-figures/addtruthmail,,,,png}
+
+@node Confirm/Change Service Providers,Defining Recovery Options,Add Authentication Methods,Setup Steps
+@anchor{design-documents/001-anastasis-ux confirm-change-service-providers}@anchor{78}
+@subsubsection Confirm/Change Service Providers
+
+
+From the dialog where the user is adding authentication methods, the user can
+optionally jump to a side-action with list of available providers (and their
+status) and possibly add additional providers that are not included in the
+default list provided by the wallet.
+
+@image{anastasis-figures/policy,,,,png}
+
+@image{anastasis-figures/addpolicy,,,,png}
+
+@image{anastasis-figures/addpolicymethod,,,,png}
+
+@node Defining Recovery Options,Pay for Setup,Confirm/Change Service Providers,Setup Steps
+@anchor{design-documents/001-anastasis-ux defining-recovery-options}@anchor{79}
+@subsubsection Defining Recovery Options
+
+
+After mapping authentication methods to providers, the user needs select which
+combinations are sufficient to recover the secret. Here, the system
+pre-computes a reasonably sane allocation, for small @code{n} the default could
+be @code{n-1} out of @code{n}.
+
+We should propose a mapping of authentication methods to providers by
+minimizing cost (tricky: sign-up vs. recovery costs, different currencies) and
+distributing the selected authentication methods across as many providers as
+possible.
+
+The user should be able to change the proposed default selection
+and add more than one provider to each chosen method.
+
+Using Anastatis providers usually is not free. From here on, the UI should
+show estimated recurring costs (yearly) and the cost of recovery. These costs
+should get updated with each user action affecting those costs such as
+when the user reconfigures the policies.
+
+@node Pay for Setup,,Defining Recovery Options,Setup Steps
+@anchor{design-documents/001-anastasis-ux pay-for-setup}@anchor{7a}
+@subsubsection Pay for Setup
+
+
+As the last step when all information has been properly provided, the user is
+asked to pay for the service with the regular wallet payment confirmation
+screen.
+
+@node Show Service Status After Setup,Recovery Steps,Setup Steps,Design Doc 001 Anastasis User Experience
+@anchor{design-documents/001-anastasis-ux show-service-status-after-setup}@anchor{7b}
+@subsubsection Show Service Status After Setup
+
+
+TODO
+
+@node Recovery Steps,,Show Service Status After Setup,Design Doc 001 Anastasis User Experience
+@anchor{design-documents/001-anastasis-ux recovery-steps}@anchor{7c}
+@subsubsection Recovery Steps
+
+@image{graphviz-834e5a93329dec2ccdefd2a21bdfb5a02bad1c84,,,[graphviz],png}
+
+@menu
+* Entry point; Settings: Entry point Settings<2>.
+* Providing Identification: Providing Identification<2>.
+* Select Authentication Challenge::
+* Payment::
+* Enter Challenge Response::
+* Success::
+
+@end menu
+
+@node Entry point Settings<2>,Providing Identification<2>,,Recovery Steps
+@anchor{design-documents/001-anastasis-ux id1}@anchor{7d}
+@subsubsection Entry point: Settings
+
+
+Like the backup, the recovery option should be available via
+the App settings.
+
+The section should have an option to recover from backup. If a previous
+recovery was not completed, the interaction should resume from that previous
+checkpoint instead of from the beginning.
+
+@image{anastasis-figures/menu,,,,png}
+
+@image{anastasis-figures/settings,,,,png}
+
+@image{anastasis-figures/backupsettings,,,,png}
+
+@node Providing Identification<2>,Select Authentication Challenge,Entry point Settings<2>,Recovery Steps
+@anchor{design-documents/001-anastasis-ux id2}@anchor{7e}
+@subsubsection Providing Identification
+
+
+The first dialog(s) during recovery should be identical to the first dialog
+during backup: the user is asked to select a continent, country of residence
+and then to provide country-specific inputs for identification.
+
+@image{anastasis-figures/userid,,,,png}
+
+@node Select Authentication Challenge,Payment,Providing Identification<2>,Recovery Steps
+@anchor{design-documents/001-anastasis-ux select-authentication-challenge}@anchor{7f}
+@subsubsection Select Authentication Challenge
+
+
+If Anastasis could recover the recovery document via any provider, it should
+show a dialog allowing the user to select one of the open challenges, and
+highlight which challenges still need to be satisfied for the various policies.
+
+Additionally, the specific provider and recovery document version should be shown.
+The user should be able to change the provider or recovery document version,
+resulting in a switch of the recovery document and policies. If the user has
+already satisfied some challenges of the current recovery document, switching to a
+different recovery document should only be done after a confirmation pop-up dialog
+warning the user that the existing progress will be lost.
+
+When selecting a challenge, the user may be asked to confirm making a payment
+for this challenge if the provider requires payment.
+
+@node Payment,Enter Challenge Response,Select Authentication Challenge,Recovery Steps
+@anchor{design-documents/001-anastasis-ux payment}@anchor{80}
+@subsubsection Payment
+
+
+Typcially, this would be the canonical wallet payment confirmation dialog.
+
+However, in the case of a security question, the payment confirmation should
+be combined with the dialog where the user enters the security answer (so
+instead of an @code{Ok} button, text showing the amount due and @code{Pay} should be
+used – except of course if the security question challenge is free of
+charge).
+
+@node Enter Challenge Response,Success,Payment,Recovery Steps
+@anchor{design-documents/001-anastasis-ux enter-challenge-response}@anchor{81}
+@subsubsection Enter Challenge Response
+
+
+If the challenge was not a security question, the dialog to enter the security
+code (PIN/TAN) should open after payment. The security code field should have
+a prefix @code{A-}. However, the user should be able to enter both only the
+numeric code, or the full code with the @code{A-} prefix (or ideally, the user
+cannot delete the pre-filled @code{A-} text).
+
+@node Success,,Enter Challenge Response,Recovery Steps
+@anchor{design-documents/001-anastasis-ux success}@anchor{82}
+@subsubsection Success
+
+
+The user is informed about the successful recovery. We may want to do this
+as part of a separate screen, or simply with a notification bar in the
+main wallet screen.
+
+@node Template,,Design Doc 001 Anastasis User Experience,Design Documents
+@anchor{design-documents/999-template doc}@anchor{83}@anchor{design-documents/999-template template}@anchor{84}
+@subsection Template
+
+
+@menu
+* Summary: Summary<2>.
+* Motivation: Motivation<2>.
+* Requirements::
+* Proposed Solution::
+* Alternatives::
+* Drawbacks::
+* Discussion / Q&A::
+
+@end menu
+
+@node Summary<2>,Motivation<2>,,Template
+@anchor{design-documents/999-template summary}@anchor{85}
+@subsubsection Summary
+
+
+@node Motivation<2>,Requirements,Summary<2>,Template
+@anchor{design-documents/999-template motivation}@anchor{86}
+@subsubsection Motivation
+
+
+@node Requirements,Proposed Solution,Motivation<2>,Template
+@anchor{design-documents/999-template requirements}@anchor{87}
+@subsubsection Requirements
+
+
+@node Proposed Solution,Alternatives,Requirements,Template
+@anchor{design-documents/999-template proposed-solution}@anchor{88}
+@subsubsection Proposed Solution
+
+
+@node Alternatives,Drawbacks,Proposed Solution,Template
+@anchor{design-documents/999-template alternatives}@anchor{89}
+@subsubsection Alternatives
+
+
+@node Drawbacks,Discussion / Q&A,Alternatives,Template
+@anchor{design-documents/999-template drawbacks}@anchor{8a}
+@subsubsection Drawbacks
+
+
+@node Discussion / Q&A,,Drawbacks,Template
+@anchor{design-documents/999-template discussion-q-a}@anchor{8b}
+@subsubsection Discussion / Q&A
+
+
+(This should be filled in with results from discussions on mailing lists / personal communication.)
+
+@node Anastasis licensing information,Man Pages,Design Documents,Documentation Overview
+@anchor{global-licensing doc}@anchor{8c}@anchor{global-licensing anastasis-licensing-information}@anchor{8d}
+@section Anastasis licensing information
+
+
+This file gives an overview of all Anastasis component’s licensing and
+of runtime dependencies thereof. For “component” here is meant a set
+of source files which can be retrieved from a single repository. If
+components consist of sources under different licensing regimes, i.e.
+because we want to enable third party developments to easily integrate
+with Taler, those are described as well.
+
+All Anastasis components are generally released under the Affero
+GPL.
+
+@menu
+* Anastasis (git;//git.taler.net/anastasis): Anastasis git //git taler net/anastasis.
+* Anastasis-gtk (git;//git.taler.net/anastasis-gtk): Anastasis-gtk git //git taler net/anastasis-gtk.
+* Documentation::
+
+@end menu
+
+@node Anastasis git //git taler net/anastasis,Anastasis-gtk git //git taler net/anastasis-gtk,,Anastasis licensing information
+@anchor{global-licensing anastasis-git-git-taler-net-anastasis}@anchor{8e}@anchor{global-licensing exchange-repo}@anchor{8f}
+@subsection Anastasis (git://git.taler.net/anastasis)
+
+
+Anastasis core logic is under AGPL.
+
+@menu
+* Runtime dependencies::
+
+@end menu
+
+@node Runtime dependencies,,,Anastasis git //git taler net/anastasis
+@anchor{global-licensing runtime-dependencies}@anchor{90}
+@subsubsection Runtime dependencies
+
+
+The following list encompasses all the runtime dependencies for this
+project, and gives the copyright holder for each of them:
+
+
+@itemize *
+
+@item
+libjansson: MIT License, AGPL- and LGPL-Compatible, owned by Petri Lehtinen and other individuals
+
+@item
+libgcrypt: LGPL, owned by Free Software Foundation
+
+@item
+postgresql: PostgreSQL License, AGPL- and LGPL-Compatible, owned by The PostgreSQL Global Development Group
+
+@item
+libgnunetutil (in all of its variants): GPLv3+, owned by GNUnet e.V.
+
+@item
+libgnunetjson: GPLv3+, GNUnet e.V.
+
+@item
+GNU Taler: LGPLv3+ / GPLv3+ / AGPLv3+: owned by Taler Systems SA
+@end itemize
+
+@node Anastasis-gtk git //git taler net/anastasis-gtk,Documentation,Anastasis git //git taler net/anastasis,Anastasis licensing information
+@anchor{global-licensing anastasis-gtk-git-git-taler-net-anastasis-gtk}@anchor{91}
+@subsection Anastasis-gtk (git://git.taler.net/anastasis-gtk)
+
+
+Anastasis-gtk is under AGPL.
+
+@menu
+* Runtime dependencies: Runtime dependencies<2>.
+
+@end menu
+
+@node Runtime dependencies<2>,,,Anastasis-gtk git //git taler net/anastasis-gtk
+@anchor{global-licensing id1}@anchor{92}
+@subsubsection Runtime dependencies
+
+
+The following list encompasses all the runtime dependencies for this
+project, and gives the copyright holder for each of them:
+
+
+@itemize *
+
+@item
+libjansson: MIT License, AGPL- and LGPL-Compatible, owned by Petri Lehtinen and other individuals
+
+@item
+libgcrypt: LGPL, owned by Free Software Foundation
+
+@item
+postgresql: PostgreSQL License, AGPL- and LGPL-Compatible, owned by The PostgreSQL Global Development Group
+
+@item
+libgnunetutil (in all of its variants): GPLv3+, owned by GNUnet e.V.
+
+@item
+libgnunetjson: GPLv3+, GNUnet e.V.
+
+@item
+libgnunetgtk: GPLv3+, GNUnet e.V.
+
+@item
+GNU Taler: LGPLv3+ / GPLv3+ / AGPLv3+: owned by Taler Systems SA
+@end itemize
+
+@node Documentation,,Anastasis-gtk git //git taler net/anastasis-gtk,Anastasis licensing information
+@anchor{global-licensing documentation}@anchor{93}
+@subsection Documentation
+
+
+The documentation is licensed under the GNU Free Documentation License Version 1.3 or later.
+
+@node Man Pages,Complete Index,Anastasis licensing information,Documentation Overview
+@anchor{manindex doc}@anchor{94}@anchor{manindex man-pages}@anchor{95}
+@section Man Pages
+
+
+@menu
+* anastasis-config(1): anastasis-config 1.
+* anastasis-gtk(1): anastasis-gtk 1.
+* anastasis-httpd(1): anastasis-httpd 1.
+* anastasis-reducer(1): anastasis-reducer 1.
+* anastasis.conf(5): anastasis conf 5.
+
+@end menu
+
+@node anastasis-config 1,anastasis-gtk 1,,Man Pages
+@anchor{manpages/anastasis-config 1 doc}@anchor{96}@anchor{manpages/anastasis-config 1 anastasis-config-1}@anchor{97}
+@subsection anastasis-config(1)
+
+
+
+@menu
+* Synopsis::
+* Description::
+* See Also::
+* Bugs::
+
+@end menu
+
+@node Synopsis,Description,,anastasis-config 1
+@anchor{manpages/anastasis-config 1 synopsis}@anchor{98}
+@subsubsection Synopsis
+
+
+@strong{anastasis-config}
+[@strong{-b} @emph{backend} | @strong{––supported-backend=}@emph{backend}]
+[@strong{-c} @emph{filename} | @strong{––config=}@emph{filename}]
+[@strong{-f} | @strong{––filename}]
+[@strong{-F} | @strong{––full}]
+[@strong{-h} | @strong{––help}]
+[@strong{-L} @emph{loglevel} | @strong{––loglevel=}@emph{loglevel}]
+[@strong{-l} @emph{filename} | @strong{––logfile=}‌@emph{filename}]
+[@strong{-o} @emph{option} | @strong{––option=}@emph{option}]
+[@strong{-r} | @strong{––rewrite}]
+[@strong{-S} | @strong{––list-sections}]
+[@strong{-s} @emph{section} | @strong{––section=}@emph{section}]
+[@strong{-V} @emph{value} | @strong{––value=}@emph{value}]
+[@strong{-v} | @strong{––version}]
+
+@node Description,See Also,Synopsis,anastasis-config 1
+@anchor{manpages/anastasis-config 1 description}@anchor{99}
+@subsubsection Description
+
+
+@strong{anastasis-config} can be used to read or modify Anastasis configuration files.
+
+
+@table @asis
+
+@item @strong{-b} @emph{BACKEND} | @strong{––supported-backend=}@emph{BACKEND}
+
+Tests whether the specified @emph{BACKEND} is supported by the current installation.
+The backend must match the name of a plugin, i.e. “namestore_postgres” for
+the Postgres database backend of the “NAMESTORE” service. If @emph{BACKEND} is
+supported, anastasis-config will return a status code of 0 (success), otherwise
+77 (unsupported). When this option is specified, no other options may be
+specified. Specifying this option together with other options will cause
+anastasis-config to return a status code of 1 (error).
+
+@item @strong{-c} @emph{FILENAME} | @strong{––config=}@emph{FILENAME}
+
+Use the configuration file @emph{FILENAME}.
+
+@item @strong{-f} | @strong{––filename}
+
+Try to perform expansions as if the option values represent filenames (will
+also be applied even if the option is not really a filename).
+
+@item @strong{-F} | @strong{––full}
+
+Write the full configuration file, not just the differences to the defaults.
+
+@item @strong{-h} | @strong{––help}
+
+Print short help on options.
+
+@item @strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}@emph{LOGLEVEL}
+
+Use @emph{LOGLEVEL} for logging.
+Valid values are @code{DEBUG}, @code{INFO}, @code{WARNING}, and @code{ERROR}.
+
+@item @strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME}
+
+Send logging output to @emph{FILENAME}.
+
+@item @strong{-o} @emph{OPTION} | @strong{––option=}@emph{OPTION}
+
+Which configuration option should be accessed or edited. Required to set a
+value. If not given, all values of a given section will be printed in the
+format “OPTION = VALUE”.
+
+@item @strong{-r} | @strong{––rewrite}
+
+Write the configuration file even if nothing changed. Will remove all comments!
+
+@item @strong{-S} | @strong{––list-sections}
+
+List available configuration sections for use with @code{--section}.
+
+@item @strong{-s} @emph{SECTION} | @strong{––section=}@emph{SECTION}
+
+Which configuration section should be accessed or edited.
+Required option.
+
+@item @strong{-V} @emph{VALUE} | @strong{––value=}@emph{VALUE}
+
+Configuration value to store in the given section under the given option.
+Must only be given together with @code{-s} and @code{-o} options.
+
+
+@table @asis
+
+@item Note:
+
+Changing the configuration file with @code{-V} will remove comments
+and may reorder sections and remove @code{@@INLINE@@} directives.
+@end table
+
+@item @strong{-v} | @strong{––version}
+
+Print Anastasis version number.
+@end table
+
+@node See Also,Bugs,Description,anastasis-config 1
+@anchor{manpages/anastasis-config 1 see-also}@anchor{9a}
+@subsubsection See Also
+
+
+anastasis.conf(5)
+
+@node Bugs,,See Also,anastasis-config 1
+@anchor{manpages/anastasis-config 1 bugs}@anchor{9b}
+@subsubsection Bugs
+
+
+Report bugs by using @indicateurl{https://bugs.anastasis.lu} or by sending electronic
+mail to <@email{contact@@anastasis.lu}>.
+
+@node anastasis-gtk 1,anastasis-httpd 1,anastasis-config 1,Man Pages
+@anchor{manpages/anastasis-gtk 1 doc}@anchor{9c}@anchor{manpages/anastasis-gtk 1 anastasis-gtk-1}@anchor{9d}
+@subsection anastasis-gtk(1)
+
+
+
+@menu
+* Synopsis: Synopsis<2>.
+* Description: Description<2>.
+* See Also: See Also<2>.
+* Bugs: Bugs<2>.
+
+@end menu
+
+@node Synopsis<2>,Description<2>,,anastasis-gtk 1
+@anchor{manpages/anastasis-gtk 1 synopsis}@anchor{9e}
+@subsubsection Synopsis
+
+
+@strong{anastasis-gtk}
+[@strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}]
+[@strong{-h} | @strong{––help}]
+[@strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL}]
+[@strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME}]
+[@strong{-v} | @strong{––version}]
+
+@node Description<2>,See Also<2>,Synopsis<2>,anastasis-gtk 1
+@anchor{manpages/anastasis-gtk 1 description}@anchor{9f}
+@subsubsection Description
+
+
+@strong{anastasis-gtk} is a graphical tool to run Anastasis
+key recover and backup operations.
+
+
+@table @asis
+
+@item @strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}
+
+Use the configuration from @emph{FILENAME}.
+
+@item @strong{-h} | @strong{––help}
+
+Print short help on options.
+
+@item @strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL}
+
+Specifies the log level to use. Accepted values are: @code{DEBUG}, @code{INFO},
+@code{WARNING}, @code{ERROR}.
+
+@item @strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME}
+
+Send logging output to @emph{FILENAME}.
+
+@item @strong{-v} | @strong{––version}
+
+Print version information.
+@end table
+
+@node See Also<2>,Bugs<2>,Description<2>,anastasis-gtk 1
+@anchor{manpages/anastasis-gtk 1 see-also}@anchor{a0}
+@subsubsection See Also
+
+
+anastasis-reducer(1), anastasis-httpd(1), anastasis.conf(5).
+
+@node Bugs<2>,,See Also<2>,anastasis-gtk 1
+@anchor{manpages/anastasis-gtk 1 bugs}@anchor{a1}
+@subsubsection Bugs
+
+
+Report bugs by using @indicateurl{https://bugs.anastasis.lu/} or by sending electronic
+mail to <@email{contact@@anastasis.lu}>.
+
+@node anastasis-httpd 1,anastasis-reducer 1,anastasis-gtk 1,Man Pages
+@anchor{manpages/anastasis-httpd 1 doc}@anchor{a2}@anchor{manpages/anastasis-httpd 1 anastasis-httpd-1}@anchor{a3}
+@subsection anastasis-httpd(1)
+
+
+
+@menu
+* Synopsis: Synopsis<3>.
+* Description: Description<3>.
+* Signals::
+* See also::
+* Bugs: Bugs<3>.
+
+@end menu
+
+@node Synopsis<3>,Description<3>,,anastasis-httpd 1
+@anchor{manpages/anastasis-httpd 1 synopsis}@anchor{a4}
+@subsubsection Synopsis
+
+
+@strong{anastasis-httpd}
+
+@node Description<3>,Signals,Synopsis<3>,anastasis-httpd 1
+@anchor{manpages/anastasis-httpd 1 description}@anchor{a5}
+@subsubsection Description
+
+
+Banastasis-httpd is a command line tool to run the Anastasis (HTTP
+backend). The required configuration and database must exist before
+running this command.
+
+Its options are as follows:
+
+
+@table @asis
+
+@item @strong{-C} | @strong{–connection-close}
+
+Force each HTTP connection to be closed after each request.
+
+@item @strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}
+
+Use the configuration and other resources for the merchant to operate
+from FILENAME.
+
+@item @strong{-h} | @strong{––help}
+
+Print short help on options.
+
+@item @strong{-v} | @strong{––version}
+
+Print version information.
+@end table
+
+@node Signals,See also,Description<3>,anastasis-httpd 1
+@anchor{manpages/anastasis-httpd 1 signals}@anchor{a6}
+@subsubsection Signals
+
+
+@strong{anastasis-httpd} responds to the following signals:
+
+
+@table @asis
+
+@item @code{SIGTERM}
+
+Sending a SIGTERM to the process will cause it to shutdown cleanly.
+@end table
+
+@node See also,Bugs<3>,Signals,anastasis-httpd 1
+@anchor{manpages/anastasis-httpd 1 see-also}@anchor{a7}
+@subsubsection See also
+
+
+anastasis-dbinit(1), anastasis-config(1), anastasis-gtk(1), anastasis-reducer(1)
+
+@node Bugs<3>,,See also,anastasis-httpd 1
+@anchor{manpages/anastasis-httpd 1 bugs}@anchor{a8}
+@subsubsection Bugs
+
+
+Report bugs by using @indicateurl{https://bugs.anastasis.lu} or by sending
+electronic mail to <@email{contact@@anastasis.lu}>.
+
+@node anastasis-reducer 1,anastasis conf 5,anastasis-httpd 1,Man Pages
+@anchor{manpages/anastasis-reducer 1 doc}@anchor{a9}@anchor{manpages/anastasis-reducer 1 anastasis-reducer-1}@anchor{aa}
+@subsection anastasis-reducer(1)
+
+
+
+@menu
+* Synopsis: Synopsis<4>.
+* Description: Description<4>.
+* See Also: See Also<3>.
+* Bugs: Bugs<4>.
+
+@end menu
+
+@node Synopsis<4>,Description<4>,,anastasis-reducer 1
+@anchor{manpages/anastasis-reducer 1 synopsis}@anchor{ab}
+@subsubsection Synopsis
+
+
+@strong{anastasis-reducer}
+[@strong{-a**_*JSON*_|_}–arguments=@emph{JSON}]
+[@strong{-b**_|_}–backup]
+[@strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}]
+[@strong{-h} | @strong{––help}]
+[@strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL}]
+[@strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME}]
+[@strong{-r**_|_}–restore]
+[@strong{-v} | @strong{––version}] COMMAND
+
+@node Description<4>,See Also<3>,Synopsis<4>,anastasis-reducer 1
+@anchor{manpages/anastasis-reducer 1 description}@anchor{ac}
+@subsubsection Description
+
+
+@strong{anastasis-reducer} is a command-line tool to run Anastasis
+key recover and backup operations using a reducer-style interface.
+The reducer will read the current state from standard input and
+write the resulting state to standard output. A COMMAND must
+be given on the command line. The arguments (if any) are to
+be given in JSON format to the @strong{-a} option. A list of
+commands can be found in the @ref{58,,Reducer API}
+chapter.
+
+
+@table @asis
+
+@item @strong{-a} @emph{JSON} | @strong{––arguments=}@emph{JSON}
+
+Provide JSON inputs for the given command.
+
+@item @strong{-b} | @strong{–backup}
+
+Begin fresh reducer operation for a back up operation.
+
+@item @strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}
+
+Use the configuration from @emph{FILENAME}.
+
+@item @strong{-h} | @strong{––help}
+
+Print short help on options.
+
+@item @strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL}
+
+Specifies the log level to use. Accepted values are: @code{DEBUG}, @code{INFO},
+@code{WARNING}, @code{ERROR}.
+
+@item @strong{-l} @emph{FILENAME} | @strong{––logfile=}‌@emph{FILENAME}
+
+Send logging output to @emph{FILENAME}.
+
+@item @strong{-r} | @strong{–restore}
+
+Begin fresh reducer operation for a restore operation.
+
+@item @strong{-v} | @strong{––version}
+
+Print version information.
+@end table
+
+@node See Also<3>,Bugs<4>,Description<4>,anastasis-reducer 1
+@anchor{manpages/anastasis-reducer 1 see-also}@anchor{ad}
+@subsubsection See Also
+
+
+anastasis-gtk(1), anastasis-httpd(1), anastasis.conf(5).
+
+@node Bugs<4>,,See Also<3>,anastasis-reducer 1
+@anchor{manpages/anastasis-reducer 1 bugs}@anchor{ae}
+@subsubsection Bugs
+
+
+Report bugs by using @indicateurl{https://bugs.anastasis.lu/} or by sending electronic
+mail to <@email{contact@@anastasis.lu}>.
+
+@node anastasis conf 5,,anastasis-reducer 1,Man Pages
+@anchor{manpages/anastasis conf 5 doc}@anchor{af}@anchor{manpages/anastasis conf 5 anastasis-conf-5}@anchor{b0}
+@subsection anastasis.conf(5)
+
+
+
+@menu
+* Description: Description<5>.
+* SEE ALSO::
+* BUGS::
+
+@end menu
+
+@node Description<5>,SEE ALSO,,anastasis conf 5
+@anchor{manpages/anastasis conf 5 description}@anchor{b1}
+@subsubsection Description
+
+
+The configuration file is line-oriented.
+Blank lines and whitespace at the beginning and end of a line are ignored.
+Comments start with @code{#} or @code{%} in the first column
+(after any beginning-of-line whitespace) and go to the end of the line.
+
+The file is split into sections.
+Every section begins with “[SECTIONNAME]” and
+contains a number of options of the form “OPTION=VALUE”.
+There may be whitespace around the @code{=} (equal sign).
+Section names and options are @emph{case-insensitive}.
+
+The values, however, are @emph{case-sensitive}.
+In particular, boolean values are one of @code{YES} or @code{NO}.
+Values can include whitespace by surrounding
+the entire value with @code{"} (double quote).
+Note, however, that there are no escape characters in such strings;
+all characters between the double quotes (including other double quotes)
+are taken verbatim.
+
+Values that represent filenames can begin with a @code{/bin/sh}-like
+variable reference.
+This can be simple, such as @code{$TMPDIR/foo}, or complex,
+such as @code{$@{TMPDIR:-$@{TMP:-/tmp@}@}/foo}.
+See @code{[PATHS]} (below).
+
+Values that represent a time duration are represented as a series of one or
+more @code{NUMBER UNIT} pairs, e.g. @code{60 s}, @code{4 weeks 1 day}, @code{5 years 2 minutes}.
+
+Values that represent an amount are in the usual amount syntax:
+@code{CURRENCY:VALUE.FRACTION}, e.g. @code{EUR:1.50}.
+The @code{FRACTION} portion may extend up to 8 places.
+
+Files containing default values for many of the options described below
+are installed under @code{$ANASTASIS_PREFIX/share/taler/config.d/}.
+The configuration file given with @strong{-c} to Anastasis binaries
+overrides these defaults.
+
+A configuration file may include another, by using the @code{@@INLINE@@} directive,
+for example, in @code{main.conf}, you could write @code{@@INLINE@@ sub.conf} to
+include the entirety of @code{sub.conf} at that point in @code{main.conf}.
+.. TODO: Document ‘anastasis-config -V’ in light of ‘@@INLINE@@’ in taler-config(1).
+
+@menu
+* GLOBAL OPTIONS::
+* Authorization options::
+* Postgres database configuration::
+
+@end menu
+
+@node GLOBAL OPTIONS,Authorization options,,Description<5>
+@anchor{manpages/anastasis conf 5 global-options}@anchor{b2}
+@subsubsection GLOBAL OPTIONS
+
+
+The following options are from the @code{[anastasis]} section and used by
+the @strong{anastasis-httpd} service.
+
+
+@table @asis
+
+@item PAYMENT_BACKEND_URL
+
+Base-URL of the Taler merchant backend instance to use for payments.
+FIXME: How do we pass the access token?
+
+@item ANNUAL_FEE
+
+Annual fee to be paid for policy uploads, i.e. “EUR:1.5”.
+
+@item TRUTH_UPLOAD_FEE
+
+Annual fee to be paid for truth uploads, i.e. “EUR:1.5”.
+
+@item DB
+
+Database backend to use, only @code{postgres} is supported right now.
+
+@item UPLOAD_LIMIT_MB
+
+Maximum upload size for policy uploads in megabytes. Default is 1.
+
+@item ANNUAL_POLICY_UPLOAD_LIMIT
+
+Maximum number of policies uploaded per year of service. Default is 42.
+
+@item BUSINESS_NAME
+
+Name of the business.
+
+@item SERVER_SALT
+
+Must be set to a high-entropy random server salt that the provider must never
+change after the initial configuration.
+
+@item PORT
+
+TCP port on which the HTTP service should listen on.
+@end table
+
+@node Authorization options,Postgres database configuration,GLOBAL OPTIONS,Description<5>
+@anchor{manpages/anastasis conf 5 authorization-options}@anchor{b3}
+@subsubsection Authorization options
+
+
+For each active authorization plugin, options must be configured in
+a section called @code{[authorization-$PLUGIN]} where @code{$PLUGIN} is
+the name of the authorization plugin.
+
+
+@table @asis
+
+@item COST
+
+Fee the user has to pay to obtain a challenge from this
+authorization plugin during recovery.
+
+@item ENABLED
+
+@code{yes} to enable this plugin, @code{no} to disable.
+
+@item COMMAND
+
+Helper command to run (only relevant for some plugins).
+@end table
+
+@node Postgres database configuration,,Authorization options,Description<5>
+@anchor{manpages/anastasis conf 5 postgres-database-configuration}@anchor{b4}
+@subsubsection Postgres database configuration
+
+
+The following options must be in the section @code{[statis-postgres]} if
+@code{postgres} was used for the database under @code{DB} in the
+@code{[anastasis]} section.
+
+
+@table @asis
+
+@item CONFIG
+
+Path under which the Postgres database is that the service
+should use, i.e. @code{postgres://anastasis}.
+@end table
+
+@node SEE ALSO,BUGS,Description<5>,anastasis conf 5
+@anchor{manpages/anastasis conf 5 see-also}@anchor{b5}
+@subsubsection SEE ALSO
+
+
+anastasis-httpd(1), anastasis-config(1)
+
+@node BUGS,,SEE ALSO,anastasis conf 5
+@anchor{manpages/anastasis conf 5 bugs}@anchor{b6}
+@subsubsection BUGS
+
+
+Report bugs by using @indicateurl{https://bugs.anastasis.lu/} or by sending electronic
+mail to <@email{contact@@anastasis.lu}>.
+
+@node Complete Index,GNU Free Documentation License,Man Pages,Documentation Overview
+@anchor{genindex doc}@anchor{b7}@anchor{genindex complete-index}@anchor{b8}
+@section Complete Index
+
+
+@node GNU Free Documentation License,,Complete Index,Documentation Overview
+@anchor{fdl-1 3 doc}@anchor{b9}@anchor{fdl-1 3 gnu-fdl-1-3}@anchor{ba}@anchor{fdl-1 3 gnu-free-documentation-license}@anchor{bb}
+@section GNU Free Documentation License
+
+
+Version 1.3, 3 November 2008
+
+Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation,
+Inc. @indicateurl{https://fsf.org/}
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+@menu
+* 0. PREAMBLE: 0 PREAMBLE.
+* 1. APPLICABILITY AND DEFINITIONS: 1 APPLICABILITY AND DEFINITIONS.
+* 2. VERBATIM COPYING: 2 VERBATIM COPYING.
+* 3. COPYING IN QUANTITY: 3 COPYING IN QUANTITY.
+* 4. MODIFICATIONS: 4 MODIFICATIONS.
+* 5. COMBINING DOCUMENTS: 5 COMBINING DOCUMENTS.
+* 6. COLLECTIONS OF DOCUMENTS: 6 COLLECTIONS OF DOCUMENTS.
+* 7. AGGREGATION WITH INDEPENDENT WORKS: 7 AGGREGATION WITH INDEPENDENT WORKS.
+* 8. TRANSLATION: 8 TRANSLATION.
+* 9. TERMINATION: 9 TERMINATION.
+* 10. FUTURE REVISIONS OF THIS LICENSE: 10 FUTURE REVISIONS OF THIS LICENSE.
+* 11. RELICENSING: 11 RELICENSING.
+* ADDENDUM; How to use this License for your documents: ADDENDUM How to use this License for your documents.
+
+@end menu
+
+@node 0 PREAMBLE,1 APPLICABILITY AND DEFINITIONS,,GNU Free Documentation License
+@anchor{fdl-1 3 preamble}@anchor{bc}
+@subsection 0. PREAMBLE
+
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document “free” in the sense of freedom: to assure
+everyone the effective freedom to copy and redistribute it, with or
+without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible for
+modifications made by others.
+
+This License is a kind of “copyleft”, which means that derivative works
+of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft license
+designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free program
+should come with manuals providing the same freedoms that the software
+does. But this License is not limited to software manuals; it can be
+used for any textual work, regardless of subject matter or whether it is
+published as a printed book. We recommend this License principally for
+works whose purpose is instruction or reference.
+
+@node 1 APPLICABILITY AND DEFINITIONS,2 VERBATIM COPYING,0 PREAMBLE,GNU Free Documentation License
+@anchor{fdl-1 3 applicability-and-definitions}@anchor{bd}
+@subsection 1. APPLICABILITY AND DEFINITIONS
+
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The “Document”, below, refers
+to any such manual or work. Any member of the public is a licensee, and
+is addressed as “you”. You accept the license if you copy, modify or
+distribute the work in a way requiring permission under copyright law.
+
+A “Modified Version” of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A “Secondary Section” is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document’s overall subject
+(or to related matters) and contains nothing that could fall directly
+within that overall subject. (Thus, if the Document is in part a
+textbook of mathematics, a Secondary Section may not explain any
+mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding them.
+
+The “Invariant Sections” are certain Secondary Sections whose titles are
+designated, as being those of Invariant Sections, in the notice that
+says that the Document is released under this License. If a section does
+not fit the above definition of Secondary then it is not allowed to be
+designated as Invariant. The Document may contain zero Invariant
+Sections. If the Document does not identify any Invariant Sections then
+there are none.
+
+The “Cover Texts” are certain short passages of text that are listed, as
+Front-Cover Texts or Back-Cover Texts, in the notice that says that the
+Document is released under this License. A Front-Cover Text may be at
+most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A “Transparent” copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the general
+public, that is suitable for revising the document straightforwardly
+with generic text editors or (for images composed of pixels) generic
+paint programs or (for drawings) some widely available drawing editor,
+and that is suitable for input to text formatters or for automatic
+translation to a variety of formats suitable for input to text
+formatters. A copy made in an otherwise Transparent file format whose
+markup, or absence of markup, has been arranged to thwart or discourage
+subsequent modification by readers is not Transparent. An image format
+is not Transparent if used for any substantial amount of text. A copy
+that is not “Transparent” is called “Opaque”.
+
+Examples of suitable formats for Transparent copies include plain ASCII
+without markup, Texinfo input format, LaTeX input format, SGML or XML
+using a publicly available DTD, and standard-conforming simple HTML,
+PostScript or PDF designed for human modification. Examples of
+transparent image formats include PNG, XCF and JPG. Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the machine-generated
+HTML, PostScript or PDF produced by some word processors for output
+purposes only.
+
+The “Title Page” means, for a printed book, the title page itself, plus
+such following pages as are needed to hold, legibly, the material this
+License requires to appear in the title page. For works in formats which
+do not have any title page as such, “Title Page” means the text near the
+most prominent appearance of the work’s title, preceding the beginning
+of the body of the text.
+
+The “publisher” means any person or entity that distributes copies of
+the Document to the public.
+
+A section “Entitled XYZ” means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as “Acknowledgements”,
+“Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of
+such a section when you modify the Document means that it remains a
+section “Entitled XYZ” according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this License,
+but only as regards disclaiming warranties: any other implication that
+these Warranty Disclaimers may have is void and has no effect on the
+meaning of this License.
+
+@node 2 VERBATIM COPYING,3 COPYING IN QUANTITY,1 APPLICABILITY AND DEFINITIONS,GNU Free Documentation License
+@anchor{fdl-1 3 verbatim-copying}@anchor{be}
+@subsection 2. VERBATIM COPYING
+
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies to
+the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further copying
+of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+@node 3 COPYING IN QUANTITY,4 MODIFICATIONS,2 VERBATIM COPYING,GNU Free Documentation License
+@anchor{fdl-1 3 copying-in-quantity}@anchor{bf}
+@subsection 3. COPYING IN QUANTITY
+
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document’s license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover Texts:
+Front-Cover Texts on the front cover, and Back-Cover Texts on the back
+cover. Both covers must also clearly and legibly identify you as the
+publisher of these copies. The front cover must present the full title
+with all words of the title equally prominent and visible. You may add
+other material on the covers in addition. Copying with changes limited
+to the covers, as long as they preserve the title of the Document and
+satisfy these conditions, can be treated as verbatim copying in other
+respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy a
+computer-network location from which the general network-using public
+has access to download using public-standard network protocols a
+complete Transparent copy of the Document, free of added material. If
+you use the latter option, you must take reasonably prudent steps, when
+you begin distribution of Opaque copies in quantity, to ensure that this
+Transparent copy will remain thus accessible at the stated location
+until at least one year after the last time you distribute an Opaque
+copy (directly or through your agents or retailers) of that edition to
+the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to give
+them a chance to provide you with an updated version of the Document.
+
+@node 4 MODIFICATIONS,5 COMBINING DOCUMENTS,3 COPYING IN QUANTITY,GNU Free Documentation License
+@anchor{fdl-1 3 modifications}@anchor{c0}
+@subsection 4. MODIFICATIONS
+
+
+You may copy and distribute a Modified Version of the Document under the
+conditions of sections 2 and 3 above, provided that you release the
+Modified Version under precisely this License, with the Modified Version
+filling the role of the Document, thus licensing distribution and
+modification of the Modified Version to whoever possesses a copy of it.
+In addition, you must do these things in the Modified Version:
+
+
+@itemize -
+
+@item
+A. Use in the Title Page (and on the covers, if any) a title distinct
+from that of the Document, and from those of previous versions (which
+should, if there were any, be listed in the History section of the
+Document). You may use the same title as a previous version if the
+original publisher of that version gives permission.
+
+@item
+B. List on the Title Page, as authors, one or more persons or
+entities responsible for authorship of the modifications in the
+Modified Version, together with at least five of the principal
+authors of the Document (all of its principal authors, if it has
+fewer than five), unless they release you from this requirement.
+
+@item
+C. State on the Title page the name of the publisher of the Modified
+Version, as the publisher.
+
+@item
+
+@enumerate 4
+
+@item
+Preserve all the copyright notices of the Document.
+@end enumerate
+
+@item
+E. Add an appropriate copyright notice for your modifications
+adjacent to the other copyright notices.
+
+@item
+F. Include, immediately after the copyright notices, a license notice
+giving the public permission to use the Modified Version under the
+terms of this License, in the form shown in the Addendum below.
+
+@item
+G. Preserve in that license notice the full lists of Invariant
+Sections and required Cover Texts given in the Document’s license
+notice.
+
+@item
+
+@enumerate 8
+
+@item
+Include an unaltered copy of this License.
+@end enumerate
+
+@item
+I. Preserve the section Entitled “History”, Preserve its Title, and
+add to it an item stating at least the title, year, new authors, and
+publisher of the Modified Version as given on the Title Page. If
+there is no section Entitled “History” in the Document, create one
+stating the title, year, authors, and publisher of the Document as
+given on its Title Page, then add an item describing the Modified
+Version as stated in the previous sentence.
+
+@item
+J. Preserve the network location, if any, given in the Document for
+public access to a Transparent copy of the Document, and likewise the
+network locations given in the Document for previous versions it was
+based on. These may be placed in the “History” section. You may omit
+a network location for a work that was published at least four years
+before the Document itself, or if the original publisher of the
+version it refers to gives permission.
+
+@item
+K. For any section Entitled “Acknowledgements” or “Dedications”,
+Preserve the Title of the section, and preserve in the section all
+the substance and tone of each of the contributor acknowledgements
+and/or dedications given therein.
+
+@item
+L. Preserve all the Invariant Sections of the Document, unaltered in
+their text and in their titles. Section numbers or the equivalent are
+not considered part of the section titles.
+
+@item
+M. Delete any section Entitled “Endorsements”. Such a section may not
+be included in the Modified Version.
+
+@item
+N. Do not retitle any existing section to be Entitled “Endorsements”
+or to conflict in title with any Invariant Section.
+
+@item
+
+@enumerate 15
+
+@item
+Preserve any Warranty Disclaimers.
+@end enumerate
+@end itemize
+
+If the Modified Version includes new front-matter sections or appendices
+that qualify as Secondary Sections and contain no material copied from
+the Document, you may at your option designate some or all of these
+sections as invariant. To do this, add their titles to the list of
+Invariant Sections in the Modified Version’s license notice. These
+titles must be distinct from any other section titles.
+
+You may add a section Entitled “Endorsements”, provided it contains
+nothing but endorsements of your Modified Version by various
+parties—for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of Front-Cover
+Text and one of Back-Cover Text may be added by (or through arrangements
+made by) any one entity. If the Document already includes a cover text
+for the same cover, previously added by you or by arrangement made by
+the same entity you are acting on behalf of, you may not add another;
+but you may replace the old one, on explicit permission from the
+previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+@node 5 COMBINING DOCUMENTS,6 COLLECTIONS OF DOCUMENTS,4 MODIFICATIONS,GNU Free Documentation License
+@anchor{fdl-1 3 combining-documents}@anchor{c1}
+@subsection 5. COMBINING DOCUMENTS
+
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its license
+notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by adding
+at the end of it, in parentheses, the name of the original author or
+publisher of that section if known, or else a unique number. Make the
+same adjustment to the section titles in the list of Invariant Sections
+in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled “History” in
+the various original documents, forming one section Entitled “History”;
+likewise combine any sections Entitled “Acknowledgements”, and any
+sections Entitled “Dedications”. You must delete all sections Entitled
+“Endorsements”.
+
+@node 6 COLLECTIONS OF DOCUMENTS,7 AGGREGATION WITH INDEPENDENT WORKS,5 COMBINING DOCUMENTS,GNU Free Documentation License
+@anchor{fdl-1 3 collections-of-documents}@anchor{c2}
+@subsection 6. COLLECTIONS OF DOCUMENTS
+
+
+You may make a collection consisting of the Document and other documents
+released under this License, and replace the individual copies of this
+License in the various documents with a single copy that is included in
+the collection, provided that you follow the rules of this License for
+verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute
+it individually under this License, provided you insert a copy of this
+License into the extracted document, and follow this License in all
+other respects regarding verbatim copying of that document.
+
+@node 7 AGGREGATION WITH INDEPENDENT WORKS,8 TRANSLATION,6 COLLECTIONS OF DOCUMENTS,GNU Free Documentation License
+@anchor{fdl-1 3 aggregation-with-independent-works}@anchor{c3}
+@subsection 7. AGGREGATION WITH INDEPENDENT WORKS
+
+
+A compilation of the Document or its derivatives with other separate and
+independent documents or works, in or on a volume of a storage or
+distribution medium, is called an “aggregate” if the copyright resulting
+from the compilation is not used to limit the legal rights of the
+compilation’s users beyond what the individual works permit. When the
+Document is included in an aggregate, this License does not apply to the
+other works in the aggregate which are not themselves derivative works
+of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these copies
+of the Document, then if the Document is less than one half of the
+entire aggregate, the Document’s Cover Texts may be placed on covers
+that bracket the Document within the aggregate, or the electronic
+equivalent of covers if the Document is in electronic form. Otherwise
+they must appear on printed covers that bracket the whole aggregate.
+
+@node 8 TRANSLATION,9 TERMINATION,7 AGGREGATION WITH INDEPENDENT WORKS,GNU Free Documentation License
+@anchor{fdl-1 3 translation}@anchor{c4}
+@subsection 8. TRANSLATION
+
+
+Translation is considered a kind of modification, so you may distribute
+translations of the Document under the terms of section 4. Replacing
+Invariant Sections with translations requires special permission from
+their copyright holders, but you may include translations of some or all
+Invariant Sections in addition to the original versions of these
+Invariant Sections. You may include a translation of this License, and
+all the license notices in the Document, and any Warranty Disclaimers,
+provided that you also include the original English version of this
+License and the original versions of those notices and disclaimers. In
+case of a disagreement between the translation and the original version
+of this License or a notice or disclaimer, the original version will
+prevail.
+
+If a section in the Document is Entitled “Acknowledgements”,
+“Dedications”, or “History”, the requirement (section 4) to Preserve its
+Title (section 1) will typically require changing the actual title.
+
+@node 9 TERMINATION,10 FUTURE REVISIONS OF THIS LICENSE,8 TRANSLATION,GNU Free Documentation License
+@anchor{fdl-1 3 termination}@anchor{c5}
+@subsection 9. TERMINATION
+
+
+You may not copy, modify, sublicense, or distribute the Document except
+as expressly provided under this License. Any attempt otherwise to copy,
+modify, sublicense, or distribute it is void, and will automatically
+terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally terminates
+your license, and (b) permanently, if the copyright holder fails to
+notify you of the violation by some reasonable means prior to 60 days
+after the cessation.
+
+Moreover, your license from a particular copyright holder is reinstated
+permanently if the copyright holder notifies you of the violation by
+some reasonable means, this is the first time you have received notice
+of violation of this License (for any work) from that copyright holder,
+and you cure the violation prior to 30 days after your receipt of the
+notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+@node 10 FUTURE REVISIONS OF THIS LICENSE,11 RELICENSING,9 TERMINATION,GNU Free Documentation License
+@anchor{fdl-1 3 future-revisions-of-this-license}@anchor{c6}
+@subsection 10. FUTURE REVISIONS OF THIS LICENSE
+
+
+The Free Software Foundation may publish new, revised versions of the
+GNU Free Documentation License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns. See @indicateurl{https://www.gnu.org/licenses/}.
+
+Each version of the License is given a distinguishing version number. If
+the Document specifies that a particular numbered version of this
+License “or any later version” applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation. If the Document specifies
+that a proxy can decide which future versions of this License can be
+used, that proxy’s public statement of acceptance of a version
+permanently authorizes you to choose that version for the Document.
+
+@node 11 RELICENSING,ADDENDUM How to use this License for your documents,10 FUTURE REVISIONS OF THIS LICENSE,GNU Free Documentation License
+@anchor{fdl-1 3 relicensing}@anchor{c7}
+@subsection 11. RELICENSING
+
+
+“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World
+Wide Web server that publishes copyrightable works and also provides
+prominent facilities for anybody to edit those works. A public wiki that
+anybody can edit is an example of such a server. A “Massive Multiauthor
+Collaboration” (or “MMC”) contained in the site means any set of
+copyrightable works thus published on the MMC site.
+
+“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+“Incorporate” means to publish or republish a Document, in whole or in
+part, as part of another Document.
+
+An MMC is “eligible for relicensing” if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole or
+in part into the MMC, (1) had no cover texts or invariant sections, and
+(2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+@node ADDENDUM How to use this License for your documents,,11 RELICENSING,GNU Free Documentation License
+@anchor{fdl-1 3 addendum-how-to-use-this-license-for-your-documents}@anchor{c8}
+@subsection ADDENDUM: How to use this License for your documents
+
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+@example
+Copyright (C) YEAR YOUR NAME.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3
+or any later version published by the Free Software Foundation;
+with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+A copy of the license is included in the section entitled "GNU
+Free Documentation License".
+@end example
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the “with … Texts.” line with this:
+
+@example
+with the Invariant Sections being LIST THEIR TITLES, with the
+Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+@end example
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+@anchor{29}@w{ }
+@anchor{rest tsref-type-ErrorDetail}@w{ }
+
+@c %**end of body
+@bye