summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
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
commit0f619df8ee16bea6d8e5a333139630ed257a45d2 (patch)
tree8f31f37e85dae08ecdfb7cb5e8873c09869e305f /core
parent2caa9ec930895ab79b8182a21b70ed15dac4b8b7 (diff)
downloaddocs-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.rst27
-rw-r--r--core/api-exchange.rst214
-rw-r--r--core/api-merchant.rst2
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;
}