taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit e4687d3857c036c6c88e1cf0ad3372eefed4bd2c
parent ce2633b6496f46f394caec08aefba205bd99de4f
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed,  5 Aug 2026 18:32:21 +0200

clarify paivana_id computation

Diffstat:
Mdesign-documents/076-paywall-proxy.rst | 28++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/design-documents/076-paywall-proxy.rst b/design-documents/076-paywall-proxy.rst @@ -91,10 +91,26 @@ Steps: since the Epoch and the current URL (``{website}``) plus some freshly generated entropy (``{nonce}``): - ``paivana_id := cur_time || '-' || b64url(SHA256(nonce || website || cur_time))``. - - Here ``b64url`` is the RFC 7515 base64 URL encoder, used to keep - the result short (same reason for the use of SHA-256). + ``paivana_id := cur_time || '-' || b64url(SHA256(nonce || website || '\0' || cur_time))``. + + The exact byte string that is hashed is the concatenation of: + + * the 16-byte (128-bit) binary ``nonce``; + * the UTF-8 encoding of ``website``, including its terminating + zero byte (which separates it unambiguously from the timestamp); + * ``cur_time`` as an 8-byte **big-endian (network byte order) + number of microseconds** since the Epoch, that is, the value of + the seconds-based ``cur_time`` multiplied by 1000000. + + Note that ``cur_time`` thus appears twice in two different + encodings: the ``paivana_id`` *prefix* is the timestamp in + **seconds** (as decimal ASCII, to keep the identifier short), + while the hashed value is the same instant in **microseconds** + in network byte order. + + Here ``b64url`` is the RFC 7515 base64 URL encoder without + padding, used to keep the result short (same reason for the use of + SHA-256). The same computation could also easily be done by a non-JS client that processes the ``Paivana`` HTTP header (or a GNU Taler wallet running as a Web extension). @@ -122,6 +138,10 @@ Steps: processing the ``Paivana`` HTTP header) then POSTs the order ID, ``nonce``, ``cur_time`` and ``website`` to ``{domain}/.well-known/pavivana``. + In this JSON request, the ``nonce`` is ``crock32``-encoded and + ``cur_time`` is a normal GNU Taler timestamp object (``{"t_s": ...}``, + in seconds); the server re-derives the binary inputs given above + from these values. * paivana-httpd computes the paivana ID and checks if the given order ID was indeed paid recently for the computed paivana ID. If so, it generates an HTTP response which the Paivana cookie