taler-docs

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

commit 449765705ba009bdd967132e346c9c4af2b34558
parent 039627fee4219e9a502fcc841d4995bb29c5af66
Author: Özgür Kesim <oec-taler@kesim.org>
Date:   Mon, 30 Dec 2024 10:05:23 +0100

[reveal] combine reveal for withdraw an refresh into one endpoint

Diffstat:
Mcore/api-exchange.rst | 207+++++++++++++++++++++++++++++++++----------------------------------------------
1 file changed, 86 insertions(+), 121 deletions(-)

diff --git a/core/api-exchange.rst b/core/api-exchange.rst @@ -1870,9 +1870,6 @@ Withdraw // Amount left in the reserve. balance: Amount; - // History of the reserve's activity, in the same format - // as returned by ``/reserve/$RID/history``. - history: TransactionHistoryItem[] } @@ -2090,76 +2087,109 @@ If so, the exchange will blindly sign ``n`` undisclosed coins from the request. Reveal ------ -These endpoins are called whenever a client made a commitment prior this this -call at another endpoint, such as a call to `Withdraw`_ with ``max_age`` set -or the melting request in`Refresh`_, and has to reveal now all but one secret -as part of a cut-and-choose protocol. - -After Withdraw -~~~~~~~~~~~~~~ - .. note:: This endpoint is available starting with API version v24. -This endpoint is called by the client after a call to `Withdraw`_, *only if* the original request -had ``max_age`` set and the response was of type ``AgeWithdrawResponse``. -Now the client has to disclose for each coin all but one of the κ secrets that went into -creating the blinded coin's planchets, including the commitent to age restriction, and prove -that the age restriction was set correctly. +This endpoint is called by the client -.. http:post:: /reveal/withdraw/$ACH +#. after a call to `melt`_. + Now the client has to disclose --for each coin-- + all but one of the κ secrets that went into creating the blinded coin's planchets, + the transfer public keys (linking the ownership of the old and new coin), + and the commitent to age restriction, + as proof that the age restriction was set correctly (if applicable). +#. after a call to `Withdraw`_, *if* the original request had ``max_age`` set + and the response was of type `AgeWithdrawResponse`. + Now the client has to disclose for each coin all but one of the κ secrets + that went into creating the blinded coin's planchets, + including the commitent to age restriction, + and prove that the age restriction was set correctly. - The client has previously committed to multiple coins with age restriction - in a call to ``/reserve/$RESERVE_PUB/withdraw`` and got a - `AgeWithdrawResponse` from the exchange. By calling this - endpoint, the client has to reveal each coin and their ``kappa - 1`` - age commitments, except for the age commitments with index - ``noreveal_index``. The hash of all commitments from the former withdraw - request is given as the ``$ACH`` value in the URL to this endpoint. - **Request:** The request body must be a `WithdrawRevealRequest` object. +.. http:post:: /reveal/$RCH - **Response:** + Reveal previously committed values to the exchange, except for the values + corresponding to the ``noreveal_index`` returned by the ``/withdraw`` or ``/melt/`` steps. + Depending on the prior call to either ``/melt`` or ``/withdraw``, + the $RCH is calculated as follows: + + .. warning:: TODO: be more specific about the calculation of $RCH here: + + #. In case of `melt`_: + $RCH is the hash over the refresh commitment from the ``/melt/`` step. + #. In case of `Withdraw`_: + $RCH is the running hash over all commitments from the former withdraw request. + + Note that the value for $RCH is calculated independently by both sides + and has never appeared *explicitly* in the protocol before. + + + The base URL for ``/reveal``-request may differ from the main base URL of + the exchange. Clients SHOULD respect the ``reveal_base_url`` returned for the + coin during melt operations. The exchange MUST return a + 307 or 308 redirection to the correct base URL if the client failed to + respect the ``reveal_base_url`` or if the allocation has changed. :http:statuscode:`200 OK`: - The request was successful, and the response is a `WithdrawRevealResponse`. - Note that repeating exactly the same request will again yield the same - response, so if the network goes down during the transaction or before the - client can commit the coin signature to disk, the coin is not lost. + The coin's' secret material matched the commitment and the original request was well-formed. + The response body is a `RevealResponse`. :http:statuscode:`404 Not found`: - The provided commitment $ACH is unknown. + The provided commitment $RCH is unknown. :http:statuscode:`409 Conflict`: - The reveal operation failed and the response is an `WithdrawError` object. - The error codes indicate one of two cases: + There is a problem between the original commitment and the revealed secret data. + The returned information is proof of the mismatch, + and therefore rather verbose, as it includes most of the original /melt or /withdraw request, + but of course expected to be primarily used for diagnostics. + + The response body is a `RevealConflictResponse`. + + In case of reveal after a ``/withdraw`` request, i.e. for withdrawal with age restriction, + the following specific error codes can be returned: + + - An age commitment for at least one of the coins did not fulfill the + required maximum age requirement of the corresponding reserve. + Error code: + ``TALER_EC_EXCHANGE_GENERIC_COIN_AGE_REQUIREMENT_FAILURE``. + - The computation of the hash of the commitment with provided input does + result in the value $ACH. + Error code: + ``TALER_EC_EXCHANGE_AGE_WITHDRAW_REVEAL_INVALID_HASH`` - 1. An age commitment for at least one of the coins did not fulfill the - required maximum age requirement of the corresponding reserve. - Error code: - ``TALER_EC_EXCHANGE_GENERIC_COIN_AGE_REQUIREMENT_FAILURE``. - 2. The computation of the hash of the commitment with provided input does - result in the value $ACH. - Error code: - ``TALER_EC_EXCHANGE_AGE_WITHDRAW_REVEAL_INVALID_HASH`` + **Details:** + Request body contains a JSON object with the following fields: - .. ts:def:: WithdrawRevealRequest + .. ts:def:: RevealRequest - interface WithdrawRevealRequest { + interface RevealRequest { // Array of ``n`` of ``(kappa - 1)`` disclosed coin master secrets, from - // which the coins' private key, blinding, nonce (for Clause-Schnorr) and - // age-restriction is calculated. - // - // Given each coin's private key and age commitment, the exchange will - // calculate each coin's blinded hash value und use all those (disclosed) - // blinded hashes together with the non-disclosed envelopes ``coin_evs`` - // during the verification of the original age-withdraw-commitment. - disclosed_coin_secrets: AgeRestrictedCoinSecret[][]; + // which the coins' private key, blinding, nonce (for Clause-Schnorr), + // transfer private keys (in case of prior ``/melt``) and + // age-restriction is calculated (in case of prior ``/withdraw``). + disclosed_coin_secrets: DisclosedCoinSecret[][]; + } + .. ts:def:: DisclosedCoinSecret + + type DisclosedCoinSecret = MasterCoinSecret + | AgeRestrictedCoinSecret + + + .. ts:def:: MasterCoinSecret + + // The master key material from which the coins' private key ``coin_priv``, + // blinding ``beta``, nonce ``nonce`` (for Clause-Schnorr) and + // the transfer private key (to link the new coin to the previous) + // are derived. + // TODO: specification of how exactly this derivation works. + type MasterCoinSecret = string + + .. ts:def:: AgeRestrictedCoinSecret - // The Master key material from which the coins' private key ``coin_priv``, + // The master key material from which the coins' private key ``coin_priv``, // blinding ``beta`` and nonce ``nonce`` (for Clause-Schnorr) itself are // derived as usually in wallet-core. Given a coin's master key material, // the age commitment for the coin MUST be derived from this private key as @@ -2174,7 +2204,7 @@ that the age restriction was set correctly. // and calculate the corresponding Edx25519PublicKey as // q[$AG] = Edx25519_public_from_private(p[$AG]) // - // For age groups $AG ∈ {m,...,M}, set + // For age groups $AG ∈ {m+1,...,M}, set // f[$AG] = HDKF(coin_secret, "age-factor", $AG) // and calculate the corresponding Edx25519PublicKey as // q[$AG] = Edx25519_derive_public(`PublishedAgeRestrictionBaseKey`, f[$AG]) @@ -2191,71 +2221,6 @@ that the age restriction was set correctly. const PublishedAgeRestrictionBaseKey = new Edx25519PublicKey("CH0VKFDZ2GWRWHQBBGEK9MWV5YDQVJ0RXEE0KYT3NMB69F0R96TG"); - .. ts:def:: WithdrawRevealResponse - - interface WithdrawRevealResponse { - // List of the exchange's blinded RSA signatures on the new coins. - ev_sigs : BlindedDenominationSignature[]; - } - - -After Melt -~~~~~~~~~~ - -.. note:: - This endpoint is available starting with API version v24. - -This endpoint is called by the client after a call to `melt`_. -Now the client has to disclose for each coin all but one of the κ secrets that went into -creating the blinded coin's planchets, the transfer public keys -(linking the ownership of the old and new coin), -and the commitent to age restriction, prove that the age restriction was set correctly -(if applicable). - -.. http:post:: /reveal/refresh/$RCH - - Reveal previously committed values to the exchange, except for the values - corresponding to the ``noreveal_index`` returned by the ``/melt/`` step. - - The $RCH is the hash over the refresh commitment from the ``/melt/``-melt step - (note that the value is calculated independently by both sides and has never - appeared *explicitly* in the protocol before). - - The base URL for ``/reveal/refresh``-requests may differ from the main base URL of - the exchange. Clients SHOULD respect the ``refresh_base_url`` returned for the - coin during melt operations. The exchange MUST return a - 307 or 308 redirection to the correct base URL if the client failed to - respect the ``refresh_base_url`` or if the allocation has changed. - - :http:statuscode:`200 OK`: - The transfer private keys matched the commitment and the original request was well-formed. - The response body is a `RevealResponse`. - :http:statuscode:`409 Conflict`: - There is a problem between the original commitment and the revealed private - keys. The returned information is proof of the mismatch, and therefore - rather verbose, as it includes most of the original /melt request, - but of course expected to be primarily used for diagnostics. - The response body is a `RevealConflictResponse`. - :http:statuscode:`410 Gone`: - The requested denomination key (for the fresh coins) is not yet or no longer valid. - It either before the validity start, past the expiration or was revoked. The response is a - `DenominationExpiredMessage`. Clients must evaluate - the error code provided to understand which of the - cases this is and handle it accordingly. - - **Details:** - - Request body contains a JSON object with the following fields: - - .. ts:def:: RevealRequest - - interface RevealRequest { - - // ``kappa - 1`` transfer private keys (ephemeral ECDHE keys). - transfer_privs: EddsaPrivateKey[]; - - } - .. ts:def:: RevealResponse @@ -3581,15 +3546,15 @@ the API during normal operation. // the base URL is the same as the one used for this request. // Can be used if the base URL for ``/reveal/`` differs from that // for ``/melt/``, i.e. for load balancing. Clients SHOULD - // respect the refresh_base_url if provided. Any HTTP server + // respect the reveal_base_url if provided. Any HTTP server // belonging to an exchange MUST generate a 307 or 308 redirection // to the correct base URL should a client uses the wrong base // URL, or if the base URL has changed since the melt. // // When melting the same coin twice (technically allowed // as the response might have been lost on the network), - // the exchange may return different values for the ``refresh_base_url``. - refresh_base_url?: string; + // the exchange may return different values for the ``reveal_base_url``. + reveal_base_url?: string; }