diff options
author | Özgür Kesim <oec-taler@kesim.org> | 2023-01-06 19:24:12 +0100 |
---|---|---|
committer | Özgür Kesim <oec-taler@kesim.org> | 2023-01-06 19:24:12 +0100 |
commit | 0f619df8ee16bea6d8e5a333139630ed257a45d2 (patch) | |
tree | 8f31f37e85dae08ecdfb7cb5e8873c09869e305f /core | |
parent | 2caa9ec930895ab79b8182a21b70ed15dac4b8b7 (diff) | |
download | docs-0f619df8ee16bea6d8e5a333139630ed257a45d2.tar.gz docs-0f619df8ee16bea6d8e5a333139630ed257a45d2.tar.bz2 docs-0f619df8ee16bea6d8e5a333139630ed257a45d2.zip |
added withdraw with age restriction and reveal
Diffstat (limited to 'core')
-rw-r--r-- | core/api-common.rst | 27 | ||||
-rw-r--r-- | core/api-exchange.rst | 214 | ||||
-rw-r--r-- | core/api-merchant.rst | 2 |
3 files changed, 229 insertions, 14 deletions
diff --git a/core/api-common.rst b/core/api-common.rst index b2913b47..4faaf88d 100644 --- a/core/api-common.rst +++ b/core/api-common.rst @@ -830,6 +830,33 @@ within the struct TALER_BlindedCoinHash h_coin_envelope; }; +.. _TALER_WithdrawAgeRestrictedRequestPS: +.. sourcecode:: c + + struct TALER_WithdrawAgeRestrictedRequestPS { + /** + * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW_AGE_RESTRICTED + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_HashCode h_age_restricted_coin_commitments; + }; + + +.. _TALER_WithdrawAgeRestrictedRevealRequestPS: +.. sourcecode:: c + + struct TALER_WithdrawAgeRestrictedRevealRequestPS { + /** + * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW_AGE_RESTRICTED_REVEAL + */ + struct GNUNET_CRYPTO_EccSignaturePurpose purpose; + struct GNUNET_HashCode denoms_h; + struct GNUNET_HashCode coin_evs; + struct GNUNET_HashCode disclosed_coins; + }; + + .. _TALER_DepositRequestPS: .. sourcecode:: c diff --git a/core/api-exchange.rst b/core/api-exchange.rst index 68528fb7..871778c6 100644 --- a/core/api-exchange.rst +++ b/core/api-exchange.rst @@ -132,6 +132,15 @@ possibly by using HTTPS. // The exchange's signing keys. signkeys: SignKey[]; + // Optional field with a dictionary of (name, object) pairs defining the + // supported and enabled extensions, such as ``age_restriction``. + extensions?: { name: ExtensionManifest }; + + // Signature by the exchange master key of the SHA-256 hash of the + // normalized JSON-object of field extensions, if it was set. + // The signature has purpose TALER_SIGNATURE_MASTER_EXTENSIONS. + extensions_sig?: EddsaSignature; + // Compact EdDSA `signature` (binary-only) over the SHA-512 hash of the // concatenation of all SHA-512 hashes of the RSA denomination public keys // in ``denoms`` in the same order as they were in ``denoms``. Note that for @@ -1239,6 +1248,14 @@ exchange. interface ReserveSummary { // Balance left in the reserve. balance: Amount; + + // If set, age restriction is required to be set for each coin to this + // value during the withdrawal from this reserve. The client then MUST + // use a denomination with support for age restriction enabled for the + // withdrawal. + // The value represents a valid age group from the list of permissible + // age groups as defined by the exchange's output to /keys. + maximum_age_group: number; } @@ -1283,6 +1300,10 @@ exchange. // Balance left in the reserve. balance: Amount; + // If set, gives the maximum age group that the client is required to set + // during withdrawal. + maximum_age_group: number; + // Transaction history for this reserve. // May be partial (!). history: TransactionHistoryItem[]; @@ -1872,16 +1893,24 @@ exchange. recover the information if necessary in case of transient failures, like power outage, network outage, etc. - **Request:** The request body must be a `BatchWithdrawRequest` object. + **Request:** The request body must be a `BatchWithdrawRequest` object. TODO: + describe differences. **Response:** :http:statuscode:`200 OK`: The request was successful, and the response is a `BatchWithdrawResponse`. - 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. + 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. + + If the reserve did not require age restriction to be set, the + `BatchWithdrawResponse` will consist of the signatures of the blinded coins. + However, if the reserve requires age restriction to be set for the coins, + the request must have been a `WithdrawAgeRestrictedRequests`, containing + all commitments to all coins with age restriction, and the response will + contain the index that the client has not to reveal in a subsequent call to + ``/reserves/$RESERVE_PUB/reveal/$RCH``. :http:statuscode:`403 Forbidden`: A signature is invalid. This response comes with a standard `ErrorDetail` response. @@ -1896,14 +1925,14 @@ exchange. In this case, the wallet should repeat the exact same request later again using exactly the same blinded coin. :http:statuscode:`409 Conflict`: - The balance of the reserve is not sufficient to withdraw the coins of the indicated denominations. - The response is `WithdrawError` object. + The balance of the reserve is not sufficient to withdraw the coins of the + indicated denominations. The response is `WithdrawError` object. :http:statuscode:`410 Gone`: A requested denomination key 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. + 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. :http:statuscode:`451 Unavailable for Legal Reasons`: This reserve has received funds from a purse or the amount withdrawn exceeds another legal threshold and thus the reserve must @@ -1928,21 +1957,163 @@ exchange. .. ts:def:: BatchWithdrawRequest - interface BatchWithdrawRequest { + type BatchWithdawRequest = + | WithdrawRequests + | WithdrawAgeRestrictedRequest + + + .. ts:def:: WithdrawRequests + + interface WithdrawRequests { // Array of requests for the individual coins to withdraw. planchets: WithdrawRequest[]; } + + .. ts:def:: WithdrawAgeRestrictedRequest + + interface WithdrawAgeRestrictedRequests { + // Array of commitments for coins with age restriction. + // The SHA512 hash value $RCH of this field has to be used in the + // subsequent call to /reserve/$RESERVE_PUB/reveal/$RCH. + age_restricted_coin_commitments: HashCode[]; + + // Signature of `TALER_WithdrawAgeRestrictedRequestPS` created with + // the `reserves's private key <reserve-priv>` + // using purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW_AGE_RESTRICTED``. + // The field ``.h_age_restricted_coin_commitments`` in that struct MUST + // be the SHA512 hash value of ``age_restricted_coin_commitments`` + // (which is also the value for $RSH in the subsequent request to + // /reserve/$RESERVE_PUB/reveal/$RSH.) + reserve_sig: EddsaSignature; + } + .. ts:def:: BatchWithdrawResponse - interface BatchWithdrawResponse { + type BatchWithdrawResponse = + | BlindedSignaturesResponse + | WithdrawRevealRequiredResponse; + + .. ts:def:: BlindedSignaturesResponse + + interface BlindedSignaturesResponse { // Array of blinded signatures, in the same order as was // given in the request. ev_sigs: WithdrawResponse[]; } + .. ts:def:: WithdrawRevealRequiredResponse + + interface WithdrawRevealRequiredResponse { + // index of the commitments that the client doesn't + // have to disclose + noreveal_index: Integer; + + // Signature of `TALER_WithdrawAgeRestrictedConfirmationPS` whereby + // the exchange confirms the ``noreveal_index``. + exchange_sig: EddsaSignature; + + // `Public EdDSA key <sign-key-pub>` of the exchange that was used to + // generate the signature. Should match one of the exchange's signing + // keys from ``/keys``. Again given explicitly as the client might + // otherwise be confused by clock skew as to which signing key was used. + exchange_pub: EddsaPublicKey; + } + + +.. http:POST:: /reserves/$RESERVE_PUB/reveal/$RCH + + The client has previously committed to multiple coins with age restriction + in a call to ``/reserve/$RESERVE_PUB/batch-withdraw`` and got a + `WithdrawRevealRequiredResponse` from the exchange. By calling this + endpoint, the client has to reveal each coin and their :math:`\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 ``$RCH`` value in the URL to this endpoint. + + + **Request:** The request body must be a `WithdrawRevealRequest` object. + + **Response:** + + :http:statuscode:`200 OK`: + The request was successful, and the response is a `BlindedSignaturesResponse`. + 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. + :http:statuscode:`404 Not found`: + A denomination key is not known to the exchange. If the denomination key + is unknown, this suggests a bug in the wallet as the wallet should have + used current denomination keys from ``/keys``. The response will be a + `DenominationUnknownMessage`. + :http:statuscode:`409 Conflict`: + There are multiple reasons for this: + + #. The balance of the reserve is not sufficient to withdraw the coins of + the indicated denominations. + #. A denomination referred to in the request doesn't support age + restriction. + #. An age commitment for one of the coins did not fulfill the required + maximum age requirement of the corresponding reserve. + + The response is an `WithdrawError` object. + :http:statuscode:`410 Gone`: + A requested denomination key 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. + + + .. ts:def:: WithdrawRevealRequest + + interface WithdrawRevealRequest { + // Array of ``n`` hash codes of denomination public keys to order. + // These denominations MUST support age restriction as defined in the + // output to ``/keys``. + denoms_h: HashCode[]; + + // Array of ``n`` entries with blinded coins, matching the respective + // entries in ``denoms_h``. These are the non-desclosed coins from the + // previous commitments. + coin_evs: CoinEnvelope[]; + + // Array of ``n`` disclosed coin public keys together with their age + // commitments. + disclosed_coins: DisclosedAgeRestrictedCoin[]; + + // Signature of `TALER_WithdrawAgeRestrictedRevealRequestPS` created with + // the `reserves's private key <reserve-priv>` + // using purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW_AGE_RESTRICTED_REVEAL``. + reserve_sig: EddsaSignature; + } + + .. ts:def:: DisclosedAgeRestrictedCoin + + interface DisclosedAgeRestrictedCoin { + // Hash of the coin's public key. + coin_pub_h: HashCode; + + // Age commitment for this coin, up to the maximum age group allowed + // by the associated reserve. The length of the array therefore MUST be + // equal to <maximum age group allowed according to reserve> (including 0). + max_age_commitment: Edx25519PublicKey[]; + + // For all age groups _larger_ than the maximum age, the client MUST provide + // the scalar factors with which it had multiplied the published public + // key `BasePublicKey`. Formaly, they are encoded as `Edx25519PrivateKey`. + // The length of this array MUST be + // ( <maximum age group defined in exchange> + // - <maximum age group allowed according to reserve> ). + larger_age_factors: Edx25519PrivateKey[]; + } + + .. ts:def:: BasePublicKey + + type BasePublicKey = Edx25519PublicKey(...); // TODO: definition! + .. _delete-reserve: @@ -2094,6 +2265,12 @@ proof to the seller for the escrow of sufficient fund. // Hash of denomination RSA key with which the coin is signed. denom_pub_hash: HashCode; + // IFF the corresponding denomination has support for + // age restriction enabled, this field MUST contain the SHA256 + // value of the age commitment that MUST have been provided during the + // purchase. + age_commitment_hash?: AgeCommitmentHash; + // Exchange's unblinded RSA signature of the coin. ub_sig: DenominationSignature; @@ -2956,6 +3133,10 @@ the API during normal operation. // denominations is of type Clause-Schnorr. rms?: RefreshMasterSeed; + // IFF the denomination has age restriction support, the client MUST + // provide the SHA256 hash of the age commitment of the coin. + // MUST be omitted otherwise. + age_commitment_hash?: AgeCommitmentHash; } For details about the HKDF used to derive the new coin private keys and @@ -3078,6 +3259,13 @@ the API during normal operation. // Signs over a `TALER_CoinLinkSignaturePS`. link_sigs: EddsaSignature[]; + // IFF the corresponding denomination has support for age restriction, + // the client MUST provide the original age commitment, i. e. the + // vector of public keys. + // The size of the vector MUST be the number of age groups as defined by the + // Exchange in the field ``.age_groups`` of the extension ``age_restriction``. + old_age_commitment?: Edx25519PublicKey[]; + } diff --git a/core/api-merchant.rst b/core/api-merchant.rst index ff03795a..db0563e6 100644 --- a/core/api-merchant.rst +++ b/core/api-merchant.rst @@ -1575,7 +1575,7 @@ Inspecting inventory next_restock?: Timestamp; // Minimum age buyer must have (in years). - minimum_age: Integer; + minimum_age?: Integer; } |