gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-docs] branch master updated (d101a65 -> 4e9f6c1)


From: gnunet
Subject: [taler-docs] branch master updated (d101a65 -> 4e9f6c1)
Date: Wed, 11 Jan 2023 17:27:32 +0100

This is an automated email from the git hooks/post-receive script.

oec pushed a change to branch master
in repository docs.

    from d101a65  -better use keyrings dir
     new 0f619df  added withdraw with age restriction and reveal
     new 23200d9  fix # of disclosed coins -> [n][kappa-1] array
     new aac3221  fix some syntax issues
     new c7444f8  redo withdraw with age restriction
     new 36a6212  added ReserveAgeWithdrawTransaction to the history of a 
reserve
     new f099681  finalizing age-withdraw api
     new f219e43  -rename field in age-withdraw history
     new 1a65188  added description of optimization and DB-schema
     new d5c0aa3  added derivation of blinding from private key
     new 3270cce  clearity in age withdraw reveal optimization
     new 5eda8c8  -mention the private keys of the derived age commitments
     new f0d3af4  -rename id field in table
     new bccd5ef  added max_age_group to the withdraw-age request, made it 
signed by the reserve_priv, and put into the database schema
     new d968732  added description of how to derive cs-nonce from the 
coin_priv for withdraw-age
     new 4e9f6c1  Merge branch 'age-restriction'

The 15 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 core/api-common.rst                      |  16 ++
 core/api-exchange.rst                    | 363 +++++++++++++++++++++++++++----
 core/api-merchant.rst                    |  39 ++--
 design-documents/024-age-restriction.rst |  99 ++++++++-
 4 files changed, 445 insertions(+), 72 deletions(-)

diff --git a/core/api-common.rst b/core/api-common.rst
index b2913b4..ab158e7 100644
--- a/core/api-common.rst
+++ b/core/api-common.rst
@@ -633,6 +633,7 @@ uses 512-bit hash codes (64 bytes).
      struct GNUNET_ShortHashCode hash;
    };
 
+.. _BlindedCoinHash:
 .. sourcecode:: c
 
    struct TALER_BlindedCoinHash {
@@ -830,6 +831,21 @@ within the
     struct TALER_BlindedCoinHash h_coin_envelope;
   };
 
+.. _TALER_AgeWithdrawRequestPS:
+.. sourcecode:: c
+
+  struct TALER_AgeWithdrawRequestPS {
+    /**
+     * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW
+     */
+    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+    struct TALER_ReservePublicKeyP reserve_pub;
+    struct GNUNET_HashCode age_restricted_coins_commitment;
+    struct GNUNET_HashCode h_denoms_h;
+    uint8 max_age_group;
+  };
+
+
 .. _TALER_DepositRequestPS:
 .. sourcecode:: c
 
diff --git a/core/api-exchange.rst b/core/api-exchange.rst
index 34f6957..cc41a9f 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[];
@@ -1297,6 +1318,7 @@ exchange.
       | AccountSetupTransaction
       | ReserveHistoryTransaction
       | ReserveWithdrawTransaction
+      | ReserveAgeWithdrawTransaction
       | ReserveCreditTransaction
       | ReserveClosingTransaction
       | ReserveOpenRequestTransaction
@@ -1369,6 +1391,26 @@ exchange.
       withdraw_fee: Amount;
      }
 
+  .. ts:def:: ReserveAgeWithdrawTransaction
+
+    interface ReserveAgeWithdrawTransaction {
+      type: "AGEWITHDRAW";
+
+      // Total Amount withdrawn.
+      amount: Amount;
+
+      // Commitment of all ``n*kappa`` coins.
+      age_restricted_coins_commitment: HashCode;
+
+      // Signature over a `TALER_AgeWithdrawRequestPS`
+      // with purpose ``TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW``
+      // created with the reserve's private key.
+      reserve_sig: EddsaSignature;
+
+      // Fee that is charged for withdraw.
+      withdraw_fee: Amount;
+     }
+
 
   .. ts:def:: ReserveCreditTransaction
 
@@ -1569,6 +1611,68 @@ exchange.
     }
 
 
+.. _delete-reserve:
+
+.. http:DELETE:: /reserves/$RESERVE_PUB
+
+  Forcefully closes a reserve.
+  The request header must contain an *Account-Request-Signature*.
+  Note: this endpoint is not currently implemented!
+
+  **Request:**
+
+  *Account-Request-Signature*: The client must provide Base-32 encoded EdDSA 
signature made with ``$ACCOUNT_PRIV``, affirming its authorization to delete 
the account.  The purpose used MUST be ``TALER_SIGNATURE_RESERVE_CLOSE``.
+
+  :query force=BOOLEAN: *Optional.*  If set to 'true' specified, the exchange
+    will delete the account even if there is a balance remaining.
+
+  **Response:**
+
+  :http:statuscode:`200 OK`:
+    The operation succeeded, the exchange provides details
+    about the account deletion.
+    The response will include a `ReserveClosedResponse` object.
+  :http:statuscode:`403 Forbidden`:
+    The *Account-Request-Signature* is invalid.
+    This response comes with a standard `ErrorDetail` response.
+  :http:statuscode:`404 Not found`:
+    The account is unknown to the exchange.
+  :http:statuscode:`409 Conflict`:
+    The account is still has digital cash in it, the associated
+    wire method is ``void`` and the *force* option was not provided.
+    This response comes with a standard `ErrorDetail` response.
+
+  **Details:**
+
+  .. ts:def:: ReserveClosedResponse
+
+     interface ReserveClosedResponse {
+
+      // Final balance of the account.
+      closing_amount: Amount;
+
+      // Current time of the exchange, used as part of
+      // what the exchange signs over.
+      close_time: Timestamp;
+
+      // Hash of the wire account into which the remaining
+      // balance will be transferred. Note: may be the
+      // hash over ``payto://void/`, in which case the
+      // balance is forfeit to the profit of the exchange.
+      h_wire: HashCode;
+
+      // This is a signature over a
+      // struct ``TALER_AccountDeleteConfirmationPS`` with purpose
+      // ``TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED``.
+      exchange_sig: EddsaSignature;
+
+    }
+
+
+
+Withdraw
+~~~~~~~~
+
 .. http:post:: /csr-withdraw
 
   Obtain exchange-side input values in preparation for a
@@ -1638,6 +1742,7 @@ exchange.
       r_pub_1: CsRPublic;
     }
 
+
 .. http:post:: /reserves/$RESERVE_PUB/withdraw
 
   Withdraw a coin of the specified denomination.  Note that the client should
@@ -1822,6 +1927,10 @@ exchange.
 
 
 
+Batch Withdraw
+~~~~~~~~~~~~~~
+
+
 .. http:post:: /reserves/$RESERVE_PUB/batch-withdraw
 
   Withdraw multiple coins from the same reserve.  Note that the client should
@@ -1836,10 +1945,9 @@ exchange.
 
   :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.
   :http:statuscode:`403 Forbidden`:
     A signature is invalid.
     This response comes with a standard `ErrorDetail` response.
@@ -1854,14 +1962,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
@@ -1892,6 +2000,7 @@ exchange.
 
     }
 
+
   .. ts:def:: BatchWithdrawResponse
 
     interface BatchWithdrawResponse {
@@ -1901,64 +2010,211 @@ exchange.
 
     }
 
+Withdraw with Age Restriction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. _delete-reserve:
-
-.. http:DELETE:: /reserves/$RESERVE_PUB
+If the reserve was marked with a maximum age group, the client has to perform a
+cut&choose protocol with the exchange.  It first calls
+``/reserves/$RESERVE_PUB/age-withdraw`` and commits to ``n*kappa`` coins.  On
+success, the exchange answers this request with an noreveal-index.  The client
+then has to call ``/age-withdraw/$ACH/reveal`` to reveal all ``n*(kappa - 1)``
+coins along with their age commitments to proof that they were appropriate.
+If so, the exchange will blindly sign ``n`` undisclosed coins from the request.
 
-  Forcefully closes a reserve.
-  The request header must contain an *Account-Request-Signature*.
-  Note: this endpoint is not currently implemented!
 
-  **Request:**
+.. http:POST:: /reserves/$RESERVE_PUB/age-withdraw
 
-  *Account-Request-Signature*: The client must provide Base-32 encoded EdDSA 
signature made with ``$ACCOUNT_PRIV``, affirming its authorization to delete 
the account.  The purpose used MUST be ``TALER_SIGNATURE_RESERVE_CLOSE``.
+  Withdraw multiple coins *with age restriction* from the same reserve.
+  Note that the client should commit all of the request details, including the
+  private key of the coins and the blinding factors, to disk *before* issuing
+  this request, so that it can recover the information if necessary in case of
+  transient failures, like power outage, network outage, etc.
 
-  :query force=BOOLEAN: *Optional.*  If set to 'true' specified, the exchange
-    will delete the account even if there is a balance remaining.
+  **Request:** The request body must be a `AgeWithdrawRequest` object.
 
   **Response:**
 
   :http:statuscode:`200 OK`:
-    The operation succeeded, the exchange provides details
-    about the account deletion.
-    The response will include a `ReserveClosedResponse` object.
+    The request was successful, and the response is a `AgeWithdrawResponse`.
+    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:`403 Forbidden`:
-    The *Account-Request-Signature* is invalid.
+    A signature is invalid.
     This response comes with a standard `ErrorDetail` response.
+  :http:statuscode:`409 Conflict`:
+    The balance of the reserve is not sufficient to withdraw the coins of the
+    given amount.  The response is a `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.
+  :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
+    be upgraded to an account (with KYC) before the withdraw can
+    complete.  Note that this response does NOT affirm that the
+    withdraw will ultimately complete with the requested amount.
+    The user should be redirected to the provided location to perform
+    the required KYC checks to open the account before withdrawing.
+    Afterwards, the request should be repeated.
+    The response will be an `KycNeededRedirect` object.
+
+  .. ts:def:: AgeWithdrawRequest
+
+    interface AgeWithdrawRequest {
+      // Commitment to the coins with age restriction.  This is the SHA512
+      // hash value $ACH over all n*kappa `BlindedCoinHash` values of all
+      // coins and their age commitments.  It is alter used as part of the URL
+      // in the subsequent call to /age-withdraw/$ACH/reveal.
+      age_restricted_coins_commitment: HashCode;
+
+      // The total amount that the client wants to withdraw from the reserve
+      // and must be at most the balance of the reserve.  The balance of the
+      // reserve will be immediatley reduced by that amount.
+      // In the subsequent call to /age-withdraw/$ACH/reveal, the client has to
+      // provide the list of denominations (with support for age restriction)
+      // that the coins shall be signed with.  The sum of the values of those
+      // denominations MUST equal this amount.
+      amount: Amount;
+
+      // The maximum age group to commit to.  MUST be the same as the maximum
+      // age group in the reserve.
+      max_age_group: number;
+
+      // Signature of `TALER_AgeWithdrawRequestPS` created with
+      // the `reserves's private key <reserve-priv>`
+      // using purpose ``TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW``.
+      reserve_sig: EddsaSignature;
+    }
+
+  .. ts:def:: AgeWithdrawResponse
+
+    interface AgeWithdrawResponse {
+      // index of the commitments that the client doesn't
+      // have to disclose
+      noreveal_index: Integer;
+
+      // Signature of `TALER_AgeWithdrawRequestPS` 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:: /age-withdraw/$ACH/reveal
+
+  The client has previously committed to multiple coins with age restriction
+  in a call to ``/reserve/$RESERVE_PUB/age-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 `AgeWithdrawRevealRequest` 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`:
-    The account is unknown to the exchange.
+    The provided commitment $ACH is unknown.
   :http:statuscode:`409 Conflict`:
-    The account is still has digital cash in it, the associated
-    wire method is ``void`` and the *force* option was not provided.
-    This response comes with a standard `ErrorDetail` response.
+    The reveal operation failed and the response is an `WithdrawError` object.
+    The error codes indicate one of two cases:
 
-  **Details:**
+    1. An age commitment for 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 sum of all denominations in the request is not equal to the amount
+       that was given in the previous commitment via the call to
+       /reserves/$RESERVE_PUB/age-withdraw.  Error code:
+       ``TALER_EC_EXCHANGE_GENERIC_MISMATCH_OF_AMOUNT_AND_DENOMINATIONS``.
 
-  .. ts:def:: ReserveClosedResponse
 
-     interface ReserveClosedResponse {
+  .. ts:def:: AgeWithdrawRevealRequest
 
-      // Final balance of the account.
-      closing_amount: Amount;
+    interface AgeWithdrawRevealRequest {
+      // The public key of the reserve that was used for the initial commitment
+      // request.  Needed for optimized database lookup.
+      reserve_pub: EddsaPublicKey;
 
-      // Current time of the exchange, used as part of
-      // what the exchange signs over.
-      close_time: Timestamp;
+      // Array of ``n`` hash codes of denomination public keys to order.
+      // These denominations MUST support age restriction as defined in the
+      // output to /keys.
+      // The sum of all denomination's values MUST equal the original amount
+      // of the previous commitment.
+      denoms_h: HashCode[];
 
-      // Hash of the wire account into which the remaining
-      // balance will be transferred. Note: may be the
-      // hash over ``payto://void/`, in which case the
-      // balance is forfeit to the profit of the exchange.
-      h_wire: HashCode;
+      // Array of ``n`` entries with blinded coins, which are the non-desclosed
+      // coins in the previous commitment. They match the respective entries
+      // in ``denoms_h``.
+      coin_evs:  CoinEnvelope[];
 
-      // This is a signature over a
-      // struct ``TALER_AccountDeleteConfirmationPS`` with purpose
-      // ``TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED``.
-      exchange_sig: EddsaSignature;
+      // Array of ``n`` arrays of ``kappa - 1`` disclosed coin private keys,
+      // from which the associated age commitments are also derived.
+      disclosed_coins: DisclosedAgeRestrictedCoin[][];
+
+    }
+
+  .. ts:def:: DisclosedAgeRestrictedCoin
+
+    interface DisclosedAgeRestrictedCoin {
+      // A coin's private key.  The associated blinding and age commitment for
+      // this coin MUST be derived from this private key as follows:
+      //
+      // Calculate the blinding beta as
+      //    beta := HKDF(coin_priv, "blinding")
+      //
+      // If the denominations are for Clause-Schnorr-Signatures, calculate the
+      // nonce as
+      //    nonce := HKDF(coin_priv, "cs-nonce")
+      //
+      // Let m ∈  {1,...,M} be the maximum age group as defined in the reserve
+      // that the wallet can commit to.
+      //
+      // For age group $AG ∈  {1,...m}, set
+      //     seed = HDKF(coin_priv, "age-commitment", $AG)
+      //   p[$AG] = Edx25519_generate_private(seed)
+      // and calculate the corresponding Edx25519PublicKey as
+      //   q[$AG] = Edx25519_public_from_private(p[$AG])
+      //
+      // For age groups $AG ∈  {m,...,M}, set
+      //   f[$AG] = HDKF(coin_priv, "age-factor", $AG)
+      // and calculate the corresponding Edx25519PublicKey as
+      //   q[$AG] = Edx25519_derive_public(`PublishedAgeRestrictionBaseKey`, 
f[$AG])
+      //
+      // Finally, with coin_priv and age commitment (q[]), the exchange
+      // will calculate the coin's public key coin_pub and use the
+      //    TALER_CoinPubHashP(coin_pub, age_commitment_hash(q))
+      // during the verification of the original age-withdraw-commitment.
+      coin_priv: EddsaPrivateKey;
 
     }
 
+  .. ts:def:: PublishedAgeRestrictionBaseKey
+
+    // The value for ``PublishedAgeRestrictionBaseKey`` is a randomly chosen
+    // `Edx25519PublicKey` for which the private key is not known to the 
clients.  It is
+    // used during the age-withdraw protocol so that clients can proof that 
they
+    // derived all public keys to age groups higher than their allowed maximum
+    // from this particular value.
+    const PublishedAgeRestrictionBaseKey =
+        new 
Edx25519PublicKey("DZJRF6HXN520505XDAWM8NMH36QV9J3VH77265WQ09EBQ76QSKCG");
+
 
 
 .. _deposit-par:
@@ -2052,6 +2308,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;
 
@@ -2914,6 +3176,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
@@ -3036,6 +3302,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 ff03795..f686b30 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;
 
     }
 
@@ -3097,34 +3097,27 @@ Inspecting template
   :http:statuscode:`404 Not found`:
      The backend has does not know about the instance.
 
-
   .. ts:def:: TemplateSummaryResponse
 
     interface TemplateSummaryResponse {
 
-     // List of templates that are present in our backend.
-     templates_list: TemplateEntry[];
-  }
-
-
+      // List of templates that are present in our backend.
+      templates_list: TemplateEntry[];
+    }
 
   The `TemplatesEntry` object describes a template. It has the following 
structure:
 
-
-
   .. ts:def:: TemplateEntry
 
     interface TemplateEntry {
 
-     // Template identifier, as found in the template.
-     template_id: string;
-
-     // Human-readable description for the template.
-     template_description: string;
-
-  }
+      // Template identifier, as found in the template.
+      template_id: string;
 
+      // Human-readable description for the template.
+      template_description: string;
 
+    }
 
 .. http:get:: [/instances/$INSTANCE]/private/templates/$TEMPLATE_ID
 
@@ -3206,21 +3199,15 @@ Using template
 
       // The amount entered by the customer.
       amount?: Amount;
-  }
-
+    }
 
   .. ts:def:: UsingTemplateResponse
 
     interface UsingTemplateResponse {
 
-       // After enter the request. The user will be pay with a taler URL.
-       taler_url: string;
-   }
-
-
-
-
-
+      // After enter the request. The user will be pay with a taler URL.
+      taler_url: string;
+    }
 
 
 --------
diff --git a/design-documents/024-age-restriction.rst 
b/design-documents/024-age-restriction.rst
index e216168..5b6e091 100644
--- a/design-documents/024-age-restriction.rst
+++ b/design-documents/024-age-restriction.rst
@@ -53,7 +53,7 @@ protocol, that gives the minor/ward a 1/Îș chance to raise the 
minimum age for
 the new coin).
 
 The proposed solution maintains the guarantees of GNU Taler with respect to
-anonymity and unlinkability.  We have published a paper 
+anonymity and unlinkability.  We have published a paper
 `Zero Knowledge Age Restriction for GNU Taler 
<https://link.springer.com/chapter/10.1007/978-3-031-17140-6_6>`_
 with the details.
 
@@ -291,6 +291,7 @@ NULL, but only iff the corresponding denomination 
(indirectly referenced via
 table ``known_coins``) has ``.age_restricted`` set to true.  This constraint
 can not be expressed reliably with SQL.
 
+
 Protocol changes
 ----------------
 
@@ -371,6 +372,102 @@ accomodate for handling multiple coins at once -- thus 
multiplying the amount
 of data by the amount of coins in question--, but all with the same value of
 :math:`\gamma`.
 
+The *actual* implementation of the protocol above will have a major 
optimization
+to keep the bandwidth usage to a minimum.  Instead of generating and sending
+the age commitment (array of public keys) and blindings for each coin, the
+wallet *MUST* derive the corresponding blindings and the age commitments from
+the coin's private key itself as follows:
+
+Let
+
+- :math:`c_s` be the private key of the coin,
+- :math:`m \in \{1,\ldots,M\}` be the maximum age (according to the reserve)
+  that a wallet can commit to during the withdrawal.
+- :math:`P` be a published constant Edx25519-public-key to which the private
+  key is not known to any client.
+
+
+Then calculate the blinding :math:`\beta` for the coin as
+
+.. math::
+     \beta &:= \text{HKDF}(c_s, \text{"blinding"})
+
+If the denomination is using Clause-Schnorr signatures, calculate the nonce
+:math:`n` for the coin as
+
+.. math::
+     n &:= \text{HKDF}(c_s, \text{"cs-nonce"})
+
+
+
+For the age commitment, calculate:
+
+1. For age group :math:`a \in \{1,\ldots,m\}`, set
+
+.. math::
+           s_a &:= \text{HDKF}(c_s, \text{"age-commitment"}, a) \\
+           p_a &:= \text{Edx25519\_generate\_private}(s_a) \\
+           q_a &:= \text{Edx25519\_public\_from\_private}(p_a)
+
+2. For age group :math:`a \in \{m,\ldots,M\}`, set
+
+.. math::
+           f_a &:= \text{HDKF}(c_s, \text{"age-factor"}, a) \\
+           q_a &:= \text{Edx25519\_derive\_public}(P, f_a).
+
+Then the vector :math:`\vec{q} = \{q_1,\ldots,q_M\}` is then the age commitment
+associated to the coin's private key :math:`c_s`.  For the non-disclosed coins,
+the wallet can use the vector :math:`(p_1,\ldots,p_m,\bot,\ldots,\bot)` of
+private keys for the attestation.
+
+Provided with the private key :math:`c_s`, the exchange can therefore calculate
+the blinding :math:`\beta`, the nonce :math:`n` (if needed) and the age
+commitment :math:`\vec{q}` itself, along with the coin's public key :math:`C_p`
+and use the value of
+
+.. math::
+
+  \text{TALER\_CoinPubHashP}(C_p, \text{age\_commitment\_hash}(\vec{q}))
+
+during the verification of the original age-withdraw-commitment.
+
+
+For the withdrawal with age restriction, a sketch of the corresponding database
+schema in the exchange is given here:
+
+.. graphviz::
+
+       digraph deposit_policies {
+               rankdir = LR;
+               splines = true;
+               fontname="monospace"
+               node [
+                       fontname="monospace"
+                       shape=record
+               ]
+
+               subgraph cluster_commitments {
+                       label=<<B>withdraw_age_commitments</B>>
+                       margin=20
+                       commitments [
+                         
label="<id>withdraw_age_commitments_id\l|h_commitment\l|amount_with_fee_val\l|amount_with_fee_frac\l|noreveal_index\l|max_age_group\l|<res>reserve_pub\l|reserve_sig\l|timestamp\l"
+                       ]
+               }
+
+               subgraph cluster_reveals {
+                       label=<<B>withdraw_age_reveals</B>>
+                       margin=20
+                       reveals [
+                         
label="freshcoin_index\l|<comm>withdraw_age_commitments_id\l|<denom>denominations_serial\l|h_coin_ev\l"
+                       ]
+               }
+
+               commitments:res->reserves:id [ label="n:1"; 
fontname="monospace"];
+               reveals:comm -> commitments:id [ label="n:1"; 
fontname="monospace" ];
+               reveals:denom -> denominations:id [ label="n:1"; 
fontname="monospace"] ;
+
+       }
+
 
 Refresh - melting phase
 ~~~~~~~~~~~~~~~~~~~~~~~

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]