gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] 01/02: [age restriction] progress 15/n - melt/refresh/r


From: gnunet
Subject: [taler-exchange] 01/02: [age restriction] progress 15/n - melt/refresh/reveal and recoup
Date: Fri, 18 Feb 2022 00:53:07 +0100

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

oec pushed a commit to branch master
in repository exchange.

commit a78b3345fbf017b1cddfd09afb4b2c29287b0bba
Author: Özgür Kesim <oec-taler@kesim.org>
AuthorDate: Thu Feb 17 12:23:06 2022 +0100

    [age restriction] progress 15/n - melt/refresh/reveal and recoup
    
    Added age restriction support for
      - melt/refresh/reveal
      - recoup
    
    However, tests are not yet implemented for those flows.
    
    Also: minor fixes and refactoring.
---
 src/auditor/taler-helper-auditor-coins.c           |  5 +-
 src/exchange/taler-exchange-httpd_deposit.c        |  4 +-
 src/exchange/taler-exchange-httpd_melt.c           |  6 +-
 src/exchange/taler-exchange-httpd_recoup-refresh.c |  7 +-
 src/exchange/taler-exchange-httpd_recoup.c         |  5 +-
 .../taler-exchange-httpd_refreshes_reveal.c        | 99 +++++++++++++++++++++-
 src/exchangedb/plugin_exchangedb_postgres.c        |  6 +-
 src/include/taler_crypto_lib.h                     | 22 +++--
 src/include/taler_exchange_service.h               | 13 +++
 src/lib/exchange_api_deposit.c                     |  4 +-
 src/lib/exchange_api_link.c                        | 45 +++++++---
 src/lib/exchange_api_management_get_keys.c         |  2 +-
 src/lib/exchange_api_refresh_common.c              | 42 ++++++++-
 src/lib/exchange_api_refresh_common.h              |  5 +-
 src/lib/exchange_api_refreshes_reveal.c            | 19 +++--
 src/testing/test_exchange_api_twisted.c            |  3 +
 src/testing/testing_api_cmd_insert_deposit.c       |  2 +-
 src/testing/testing_api_cmd_refresh.c              | 36 ++++----
 src/util/crypto.c                                  |  6 +-
 src/util/wallet_signatures.c                       |  5 --
 20 files changed, 259 insertions(+), 77 deletions(-)

diff --git a/src/auditor/taler-helper-auditor-coins.c 
b/src/auditor/taler-helper-auditor-coins.c
index 2ed8e5a1..531f5bb4 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -1614,7 +1614,6 @@ deposit_cb (void *cls,
     struct TALER_MerchantWireHash h_wire;
     struct TALER_DenominationHash h_denom_pub;
     struct TALER_Amount deposit_fee;
-    struct TALER_AgeCommitmentHash *h_age_commitment = NULL; /* FIXME-oec */
 
     TALER_denom_pub_hash (denom_pub,
                           &h_denom_pub);
@@ -1631,8 +1630,8 @@ deposit_cb (void *cls,
                                      &deposit_fee,
                                      &h_wire,
                                      &deposit->h_contract_terms,
-                                     h_age_commitment, /* FIXME-oec */
-                                     NULL /* h_extensions! */,
+                                     &deposit->coin.h_age_commitment,
+                                     NULL /* FIXME: h_extensions! */,
                                      &h_denom_pub,
                                      deposit->timestamp,
                                      &deposit->merchant_pub,
diff --git a/src/exchange/taler-exchange-httpd_deposit.c 
b/src/exchange/taler-exchange-httpd_deposit.c
index d750ec70..11a53cea 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -242,7 +242,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
                                  &deposit.h_contract_terms),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
-                                   &deposit.coin.age_commitment_hash)),
+                                   &deposit.coin.h_age_commitment)),
     GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                  &deposit.csig),
     GNUNET_JSON_spec_timestamp ("timestamp",
@@ -400,7 +400,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
                                    &deposit.deposit_fee,
                                    &h_wire,
                                    &deposit.h_contract_terms,
-                                   &deposit.coin.age_commitment_hash,
+                                   &deposit.coin.h_age_commitment,
                                    NULL /* h_extensions! */,
                                    &deposit.coin.denom_pub_hash,
                                    deposit.timestamp,
diff --git a/src/exchange/taler-exchange-httpd_melt.c 
b/src/exchange/taler-exchange-httpd_melt.c
index 8bfdf8ce..769b13e4 100644
--- a/src/exchange/taler-exchange-httpd_melt.c
+++ b/src/exchange/taler-exchange-httpd_melt.c
@@ -336,7 +336,7 @@ check_melt_valid (struct MHD_Connection *connection,
                                 &rmc->coin_refresh_fee,
                                 &rmc->refresh_session.rc,
                                 &rmc->refresh_session.coin.denom_pub_hash,
-                                &rmc->refresh_session.coin.age_commitment_hash,
+                                &rmc->refresh_session.coin.h_age_commitment,
                                 &rmc->refresh_session.coin.coin_pub,
                                 &rmc->refresh_session.coin_sig))
   {
@@ -413,8 +413,8 @@ TEH_handler_melt (struct MHD_Connection *connection,
     GNUNET_JSON_spec_fixed_auto ("denom_pub_hash",
                                  &rmc.refresh_session.coin.denom_pub_hash),
     GNUNET_JSON_spec_mark_optional (
-      GNUNET_JSON_spec_fixed_auto ("age_commitment_hash",
-                                   
&rmc.refresh_session.coin.age_commitment_hash)),
+      GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+                                   
&rmc.refresh_session.coin.h_age_commitment)),
     GNUNET_JSON_spec_fixed_auto ("confirm_sig",
                                  &rmc.refresh_session.coin_sig),
     TALER_JSON_spec_amount ("value_with_fee",
diff --git a/src/exchange/taler-exchange-httpd_recoup-refresh.c 
b/src/exchange/taler-exchange-httpd_recoup-refresh.c
index bbf6defe..4326dfe4 100644
--- a/src/exchange/taler-exchange-httpd_recoup-refresh.c
+++ b/src/exchange/taler-exchange-httpd_recoup-refresh.c
@@ -251,7 +251,7 @@ verify_and_execute_recoup_refresh (
     if (GNUNET_OK !=
         TALER_denom_blind (&dk->denom_pub,
                            coin_bks,
-                           NULL, /* FIXME-Oec: TALER_AgeCommitmentHash * */
+                           &coin->h_age_commitment,
                            &coin->coin_pub,
                            exchange_vals,
                            &c_hash,
@@ -360,7 +360,7 @@ TEH_handler_recoup_refresh (struct MHD_Connection 
*connection,
                             const json_t *root)
 {
   enum GNUNET_GenericReturnValue ret;
-  struct TALER_CoinPublicInfo coin;
+  struct TALER_CoinPublicInfo coin = {0};
   union TALER_DenominationBlindingKeyP coin_bks;
   struct TALER_CoinSpendSignatureP coin_sig;
   struct TALER_ExchangeWithdrawValues exchange_vals;
@@ -376,6 +376,9 @@ TEH_handler_recoup_refresh (struct MHD_Connection 
*connection,
                                  &coin_bks),
     GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                  &coin_sig),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+                                   &coin.h_age_commitment)),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_fixed_auto ("cs_nonce",
                                    &nonce)),
diff --git a/src/exchange/taler-exchange-httpd_recoup.c 
b/src/exchange/taler-exchange-httpd_recoup.c
index 4ac997e9..00753251 100644
--- a/src/exchange/taler-exchange-httpd_recoup.c
+++ b/src/exchange/taler-exchange-httpd_recoup.c
@@ -256,7 +256,7 @@ verify_and_execute_recoup (
     if (GNUNET_OK !=
         TALER_denom_blind (&dk->denom_pub,
                            coin_bks,
-                           NULL, /* FIXME-Oec: TALER_AgeCommitmentHash * */
+                           &coin->h_age_commitment,
                            &coin->coin_pub,
                            exchange_vals,
                            &c_hash,
@@ -389,6 +389,9 @@ TEH_handler_recoup (struct MHD_Connection *connection,
                                  &coin_bks),
     GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                  &coin_sig),
+    GNUNET_JSON_spec_mark_optional (
+      GNUNET_JSON_spec_fixed_auto ("h_age_commitment",
+                                   &coin.h_age_commitment)),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_fixed_auto ("cs_nonce",
                                    &nonce)),
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c 
b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index 1f0782aa..32195f8d 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -102,6 +102,12 @@ struct RevealContext
    */
   const struct TEH_DenominationKey **dks;
 
+  /**
+   * Age commitment that was used for the original coin.  If not NULL, its hash
+   * should be the same as melt.session.h_age_commitment.
+   */
+  struct TALER_AgeCommitment *old_age_commitment;
+
   /**
    * Array of information about fresh coins being revealed.
    */
@@ -263,6 +269,7 @@ check_commitment (struct RevealContext *rctx,
           const struct TALER_ExchangeWithdrawValues *alg_value
             = &rctx->rrcs[j].exchange_vals;
           struct TALER_PlanchetDetail pd;
+          struct TALER_AgeCommitmentHash *hac = NULL;
           struct TALER_CoinPubHash c_hash;
           struct TALER_PlanchetMasterSecretP ps;
 
@@ -276,12 +283,30 @@ check_commitment (struct RevealContext *rctx,
           TALER_planchet_blinding_secret_create (&ps,
                                                  alg_value,
                                                  &bks);
+          /* Calculate, if applicable, the age commitment and its hash, from
+           * the transfer_secret and the old age commitment. */
+          if (NULL != rctx->old_age_commitment)
+          {
+            struct TALER_AgeCommitment ac = {0};
+            struct TALER_AgeCommitmentHash h = {0};
+
+            GNUNET_assert (GNUNET_OK ==
+                           TALER_age_commitment_derive (
+                             rctx->old_age_commitment,
+                             ts.key.bits[0],
+                             &ac));
+
+            TALER_age_commitment_hash (&ac, &h);
+
+            hac = &h;
+          }
+
           GNUNET_assert (GNUNET_OK ==
                          TALER_planchet_prepare (rcd->dk,
                                                  alg_value,
                                                  &bks,
                                                  &coin_priv,
-                                                 NULL, /* FIXME-Oec, struct 
TALER_AgeCommitmentHash * */
+                                                 hac,
                                                  &c_hash,
                                                  &pd));
           if (TALER_DENOMINATION_CS == dk->cipher)
@@ -542,6 +567,77 @@ resolve_refreshes_reveal_denominations (struct 
MHD_Connection *connection,
     }
   }
 
+  if (TEH_age_restriction_enabled &&
+      ((NULL == old_age_commitment_json) !=
+       TALER_AgeCommitmentHash_isNullOrZero (
+         &rctx->melt.session.h_age_commitment)))
+  {
+    GNUNET_break (0);
+    return MHD_NO;
+  }
+
+  /* Reconstruct the old age commitment and verify its hash matches the one
+   * from the melt request */
+  if (TEH_age_restriction_enabled &&
+      (NULL != old_age_commitment_json))
+  {
+    enum GNUNET_GenericReturnValue res;
+    struct TALER_AgeCommitment *oac = rctx->old_age_commitment;
+    size_t ng = json_array_size (old_age_commitment_json);
+    bool failed = true;
+
+    /* Has been checked in handle_refreshes_reveal_json() */
+    GNUNET_assert (ng ==
+                   TALER_extensions_age_restriction_num_groups ());
+
+    oac = GNUNET_new (struct TALER_AgeCommitment);
+    oac->mask  =  TEH_age_mask;
+    oac->num_pub = ng;
+    oac->num_priv = 0; /* no private keys are needed for the reveal phase */
+    oac->pub = GNUNET_new_array (ng, struct TALER_AgeCommitmentPublicKeyP);
+
+    /* Extract old age commitment */
+    for (unsigned int i = 0; i< ng; i++)
+    {
+      struct GNUNET_JSON_Specification ac_spec[] = {
+        GNUNET_JSON_spec_fixed_auto (NULL,
+                                     &oac->pub[i]),
+        GNUNET_JSON_spec_end ()
+      };
+
+      res = TALER_MHD_parse_json_array (connection,
+                                        old_age_commitment_json,
+                                        ac_spec,
+                                        i,
+                                        -1);
+      GNUNET_break (GNUNET_OK != res);
+      if (GNUNET_OK != res)
+        goto clean_age;
+    }
+
+    /* Sanity check: Compare hash from melting with hash of this age 
commitment */
+    {
+      struct TALER_AgeCommitmentHash hac = {0};
+      TALER_age_commitment_hash (oac, &hac);
+      if (0 != memcmp (&hac,
+                       &rctx->melt.session.h_age_commitment,
+                       sizeof(struct TALER_AgeCommitmentHash)))
+      {
+        GNUNET_break (0);
+        goto clean_age;
+      }
+    }
+
+    failed = false;
+
+clean_age:
+    if (failed)
+    {
+      TALER_age_commitment_free (oac);
+      return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
+    }
+  }
+
   /* Parse link signatures array */
   for (unsigned int i = 0; i<num_fresh_coins; i++)
   {
@@ -567,7 +663,6 @@ resolve_refreshes_reveal_denominations (struct 
MHD_Connection *connection,
           &rctx->gamma_tp,
           &rrcs[i].coin_envelope_hash,
           &rctx->melt.session.coin.coin_pub,
-          NULL, // TODO-oec: calculate the correct h_age_commitment
           &rrcs[i].orig_coin_link_sig))
     {
       GNUNET_break_op (0);
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 878c36f9..8f7a0940 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -5664,7 +5664,7 @@ postgres_get_known_coin (void *cls,
     GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
                                           &coin_info->denom_pub_hash),
     GNUNET_PQ_result_spec_auto_from_type ("age_hash",
-                                          &coin_info->age_commitment_hash),
+                                          &coin_info->h_age_commitment),
     TALER_PQ_result_spec_denom_sig ("denom_sig",
                                     &coin_info->denom_sig),
     GNUNET_PQ_result_spec_end
@@ -5780,7 +5780,7 @@ postgres_ensure_coin_known (void *cls,
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
     GNUNET_PQ_query_param_auto_from_type (&coin->denom_pub_hash),
-    GNUNET_PQ_query_param_auto_from_type (&coin->age_commitment_hash),
+    GNUNET_PQ_query_param_auto_from_type (&coin->h_age_commitment),
     TALER_PQ_query_param_denom_sig (&coin->denom_sig),
     GNUNET_PQ_query_param_end
   };
@@ -5830,7 +5830,7 @@ postgres_ensure_coin_known (void *cls,
 
   if ( (! is_age_hash_null) &&
        (0 != GNUNET_memcmp (age_hash,
-                            &coin->age_commitment_hash)) )
+                            &coin->h_age_commitment)) )
   {
     GNUNET_break (GNUNET_is_zero (age_hash));
     GNUNET_break_op (0);
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 9bbf29de..6aabf983 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -979,7 +979,7 @@ struct TALER_CoinPublicInfo
    * Hash of the age commitment.  If no age commitment was provided, it must be
    * set to all zeroes.
    */
-  struct TALER_AgeCommitmentHash age_commitment_hash;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * (Unblinded) signature over @e coin_pub with @e denom_pub,
@@ -2351,11 +2351,12 @@ TALER_wallet_melt_verify (
  * @param[out] coin_sig resulting signature
  */
 void
-TALER_wallet_link_sign (const struct TALER_DenominationHash *h_denom_pub,
-                        const struct TALER_TransferPublicKeyP *transfer_pub,
-                        const struct TALER_BlindedCoinHash *bch,
-                        const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
-                        struct TALER_CoinSpendSignatureP *coin_sig);
+TALER_wallet_link_sign (
+  const struct TALER_DenominationHash *h_denom_pub,
+  const struct TALER_TransferPublicKeyP *transfer_pub,
+  const struct TALER_BlindedCoinHash *bch,
+  const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
+  struct TALER_CoinSpendSignatureP *coin_sig);
 
 
 /**
@@ -2365,7 +2366,6 @@ TALER_wallet_link_sign (const struct 
TALER_DenominationHash *h_denom_pub,
  * @param transfer_pub transfer public key
  * @param h_coin_ev hash of the coin envelope
  * @param old_coin_pub old coin key that the link signature is for
- * @param h_age_commitment hash of age commitment. Maybe NULL, if not 
applicable.
  * @param coin_sig resulting signature
  * @return #GNUNET_OK if the signature is valid
  */
@@ -2375,7 +2375,6 @@ TALER_wallet_link_verify (
   const struct TALER_TransferPublicKeyP *transfer_pub,
   const struct TALER_BlindedCoinHash *h_coin_ev,
   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
-  const struct TALER_AgeCommitmentHash *h_age_commitment,
   const struct TALER_CoinSpendSignatureP *coin_sig);
 
 
@@ -3283,12 +3282,11 @@ TALER_age_commitment_derive (
   struct TALER_AgeCommitment *derived);
 
 /*
- * @brief helper function to free memory inside a struct TALER_AgeCommitment
- * @param cmt the commitment from which internal memory should be freed.  Note
- * that cmt itself is NOT freed!
+ * @brief helper function to free memory of a struct TALER_AgeCommitment
+ * @param cmt the commitment from which all memory should be freed.
  */
 void
-TALER_age_restriction_commitment_free_inside (
+TALER_age_commitment_free (
   struct TALER_AgeCommitment *cmt);
 
 #endif
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index fef09f72..a8a29008 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1599,6 +1599,11 @@ struct TALER_EXCHANGE_RefreshData
    */
   struct TALER_CoinSpendPrivateKeyP melt_priv;
 
+  /*
+   * age commitment that went into the original coin, might be NULL
+   */
+  struct TALER_AgeCommitment *age_commitment;
+
   /**
    * amount specifying how much the coin will contribute to the melt
    * (including fee)
@@ -1766,6 +1771,12 @@ struct TALER_EXCHANGE_RevealedCoinInfo
    */
   struct TALER_PlanchetMasterSecretP ps;
 
+  /**
+   * Age commitment and its hash of the coin, might be NULL.
+   */
+  struct TALER_AgeCommitment *age_commitment;
+  struct TALER_AgeCommitmentHash *h_age_commitment;
+
   /**
    * Blinding keys used to blind the fresh coin.
    */
@@ -1982,6 +1993,7 @@ typedef void
  *
  * @param exchange the exchange handle; the exchange must be ready to operate
  * @param coin_priv private key to request link data for
+ * @param age_commitment age commitment to the corresponding coin, might be 
NULL
  * @param link_cb the callback to call with the useful result of the
  *        refresh operation the @a coin_priv was involved in (if any)
  * @param link_cb_cls closure for @a link_cb
@@ -1990,6 +2002,7 @@ typedef void
 struct TALER_EXCHANGE_LinkHandle *
 TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
                      const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+                     const struct TALER_AgeCommitment *age_commitment,
                      TALER_EXCHANGE_LinkCallback link_cb,
                      void *link_cb_cls);
 
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
index 2bfaaf6c..2cd40556 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_deposit.c
@@ -518,11 +518,11 @@ verify_signatures (const struct 
TALER_EXCHANGE_DenomPublicKey *dki,
       .coin_pub = *coin_pub,
       .denom_pub_hash = *denom_pub_hash,
       .denom_sig = *denom_sig,
-      .age_commitment_hash = {{{0}}}
+      .h_age_commitment = {{{0}}}
     };
     if (NULL != h_age_commitment)
     {
-      coin_info.age_commitment_hash = *h_age_commitment;
+      coin_info.h_age_commitment = *h_age_commitment;
     }
 
     if (GNUNET_YES !=
diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c
index 10ddd471..0702ba4e 100644
--- a/src/lib/exchange_api_link.c
+++ b/src/lib/exchange_api_link.c
@@ -66,6 +66,11 @@ struct TALER_EXCHANGE_LinkHandle
    */
   struct TALER_CoinSpendPrivateKeyP coin_priv;
 
+  /**
+   * Age commitment of the coin, might be NULL, required to re-generate age 
commitments
+   */
+  const struct TALER_AgeCommitment *age_commitment;
+
 };
 
 
@@ -113,7 +118,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
   struct TALER_TransferSecretP secret;
   struct TALER_PlanchetDetail pd;
   struct TALER_CoinPubHash c_hash;
-  struct TALER_AgeCommitmentHash h_age_commitment = {0}; // TODO, see below.
+  struct TALER_AgeCommitmentHash *hac = NULL;
 
   /* parse reply */
   memset (&nonce,
@@ -139,12 +144,37 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle 
*lh,
   TALER_planchet_blinding_secret_create (&lci->ps,
                                          &alg_values,
                                          &bks);
+
+  /* Derive the age commitment and calculate the hash */
+  if (NULL != lh->age_commitment)
+  {
+    struct TALER_AgeCommitment nac = {0};
+    struct TALER_AgeCommitmentHash h = {0};
+    uint32_t seed  = secret.key.bits[0];
+
+    if (GNUNET_OK !=
+        TALER_age_commitment_derive (
+          lh->age_commitment,
+          seed,
+          &nac))
+    {
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
+
+    TALER_age_commitment_hash (
+      &nac,
+      &h);
+
+    hac = &h;
+  }
+
   if (GNUNET_OK !=
       TALER_planchet_prepare (&rpub,
                               &alg_values,
                               &bks,
                               &lci->coin_priv,
-                              NULL, /* FIXME-oec. struct 
TALER_AgeCommitmentHash */
+                              hac,
                               &c_hash,
                               &pd))
   {
@@ -181,14 +211,6 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle 
*lh,
 
     GNUNET_CRYPTO_eddsa_key_get_public (&lh->coin_priv.eddsa_priv,
                                         &old_coin_pub.eddsa_pub);
-    /*
-     * TODO-oec: Derive the age commitment vector and hash it into
-     * h_age_commitment.
-     * Questions:
-     *   - Where do we get the information about the support for age
-     *     restriction of the denomination?
-     *   - Where do we get the information bout the previous coin's age groups?
-     */
 
     TALER_coin_ev_hash (&pd.blinded_planchet,
                         &pd.denom_pub_hash,
@@ -198,7 +220,6 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
                                   trans_pub,
                                   &coin_envelope_hash,
                                   &old_coin_pub,
-                                  &h_age_commitment,
                                   &link_sig))
     {
       GNUNET_break_op (0);
@@ -455,6 +476,7 @@ handle_link_finished (void *cls,
 struct TALER_EXCHANGE_LinkHandle *
 TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
                      const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+                     const struct TALER_AgeCommitment *age_commitment,
                      TALER_EXCHANGE_LinkCallback link_cb,
                      void *link_cb_cls)
 {
@@ -493,6 +515,7 @@ TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
   lh->link_cb = link_cb;
   lh->link_cb_cls = link_cb_cls;
   lh->coin_priv = *coin_priv;
+  lh->age_commitment = age_commitment;
   lh->url = TEAH_path_to_url (exchange,
                               arg_str);
   if (NULL == lh->url)
diff --git a/src/lib/exchange_api_management_get_keys.c 
b/src/lib/exchange_api_management_get_keys.c
index ac419388..4d686633 100644
--- a/src/lib/exchange_api_management_get_keys.c
+++ b/src/lib/exchange_api_management_get_keys.c
@@ -32,7 +32,7 @@
 /**
  * Set to 1 for extra debug logging.
  */
-#define DEBUG 1  /* FIXME-oec */
+#define DEBUG 0
 
 
 /**
diff --git a/src/lib/exchange_api_refresh_common.c 
b/src/lib/exchange_api_refresh_common.c
index 89ee1e17..30711d78 100644
--- a/src/lib/exchange_api_refresh_common.c
+++ b/src/lib/exchange_api_refresh_common.c
@@ -77,6 +77,8 @@ TALER_EXCHANGE_get_melt_data_ (
   md->melted_coin.fee_melt = rd->melt_pk.fee_refresh;
   md->melted_coin.original_value = rd->melt_pk.value;
   md->melted_coin.expire_deposit = rd->melt_pk.expire_deposit;
+  md->melted_coin.age_commitment = rd->age_commitment;
+
   GNUNET_assert (GNUNET_OK ==
                  TALER_amount_set_zero (rd->melt_amount.currency,
                                         &total));
@@ -141,14 +143,18 @@ TALER_EXCHANGE_get_melt_data_ (
       rms,
       i,
       &md->transfer_priv[i]);
+
     GNUNET_CRYPTO_ecdhe_key_get_public (
       &md->transfer_priv[i].ecdhe_priv,
       &md->transfer_pub[i].ecdhe_pub);
+
     TALER_link_derive_transfer_secret (&rd->melt_priv,
                                        &md->transfer_priv[i],
                                        &trans_sec);
+
     md->rcd[i] = GNUNET_new_array (rd->fresh_pks_len,
                                    struct TALER_RefreshCoinData);
+
     for (unsigned int j = 0; j<rd->fresh_pks_len; j++)
     {
       struct FreshCoinData *fcd = &md->fcds[j];
@@ -158,24 +164,57 @@ TALER_EXCHANGE_get_melt_data_ (
       union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i];
       struct TALER_PlanchetDetail pd;
       struct TALER_CoinPubHash c_hash;
+      struct TALER_AgeCommitmentHash *ach = NULL;
 
       TALER_transfer_secret_to_planchet_secret (&trans_sec,
                                                 j,
                                                 ps);
+
       TALER_planchet_setup_coin_priv (ps,
                                       &alg_values[j],
                                       coin_priv);
+
       TALER_planchet_blinding_secret_create (ps,
                                              &alg_values[j],
                                              bks);
+
+      /* Handle age commitment, if present */
+      if (NULL != md->melted_coin.age_commitment)
+      {
+        struct TALER_AgeCommitment new_ac;
+        struct TALER_AgeCommitmentHash hac;
+
+        /* We use the first 4 bytes of the trans_sec to generate a new age
+         * commitment */
+        uint32_t age_seed = trans_sec.key.bits[0];
+
+        if (GNUNET_OK !=
+            TALER_age_commitment_derive (
+              md->melted_coin.age_commitment,
+              age_seed + j,
+              &new_ac))
+        {
+          GNUNET_break_op (0);
+          TALER_EXCHANGE_free_melt_data_ (md);
+          return GNUNET_SYSERR;
+        }
+
+        TALER_age_commitment_hash (
+          &new_ac,
+          &hac);
+
+        ach = &hac;
+      }
+
       if (TALER_DENOMINATION_CS == alg_values[j].cipher)
         pd.blinded_planchet.details.cs_blinded_planchet.nonce = nonces[j];
+
       if (GNUNET_OK !=
           TALER_planchet_prepare (&fcd->fresh_pk,
                                   &alg_values[j],
                                   bks,
                                   coin_priv,
-                                  NULL, /* FIXME-oec: This needs to be setup 
!*/
+                                  ach,
                                   &c_hash,
                                   &pd))
       {
@@ -183,6 +222,7 @@ TALER_EXCHANGE_get_melt_data_ (
         TALER_EXCHANGE_free_melt_data_ (md);
         return GNUNET_SYSERR;
       }
+
       rcd->blinded_planchet = pd.blinded_planchet;
       rcd->dk = &fcd->fresh_pk;
     }
diff --git a/src/lib/exchange_api_refresh_common.h 
b/src/lib/exchange_api_refresh_common.h
index b6926b51..a3c3e2c0 100644
--- a/src/lib/exchange_api_refresh_common.h
+++ b/src/lib/exchange_api_refresh_common.h
@@ -53,10 +53,11 @@ struct MeltedCoin
   struct TALER_Amount original_value;
 
   /**
-   * The original age commitment hash.  MUST be all zeroes, if no age
+   * The original age commitment and its hash.  MUST be NULL if no age
    * commitment was set.
    */
-  struct TALER_AgeCommitmentHash h_age_commitment;
+  struct TALER_AgeCommitment *age_commitment;
+  struct TALER_AgeCommitmentHash *h_age_commitment;
 
   /**
    * Timestamp indicating when coins of this denomination become invalid.
diff --git a/src/lib/exchange_api_refreshes_reveal.c 
b/src/lib/exchange_api_refreshes_reveal.c
index 8d04c279..d5f2265c 100644
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ b/src/lib/exchange_api_refreshes_reveal.c
@@ -142,7 +142,6 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
       &rcis[i];
     const struct FreshCoinData *fcd = &rrh->md.fcds[i];
     const struct TALER_DenominationPublicKey *pk;
-    struct TALER_AgeCommitmentHash *ach = NULL;
     json_t *jsonai;
     struct TALER_BlindedDenominationSignature blind_sig;
     struct TALER_CoinSpendPublicKeyP coin_pub;
@@ -157,14 +156,22 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
 
     rci->ps = fcd->ps[rrh->noreveal_index];
     rci->bks = fcd->bks[rrh->noreveal_index];
+    rci->age_commitment = fcd->age_commitment[rrh->noreveal_index];
+    rci->h_age_commitment = NULL;
     pk = &fcd->fresh_pk;
     jsonai = json_array_get (jsona, i);
+
     GNUNET_assert (NULL != jsonai);
+    GNUNET_assert (
+      (NULL != rrh->md.melted_coin.age_commitment) ==
+      (NULL != rci->age_commitment));
 
-    if (! TALER_AgeCommitmentHash_isNullOrZero (
-          &rrh->md.melted_coin.h_age_commitment))
+    if (NULL != rci->age_commitment)
     {
-      /* FIXME-oec:  need to pull fresh_ach from somewhere */
+      rci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash);
+      TALER_age_commitment_hash (
+        rci->age_commitment,
+        rci->h_age_commitment);
     }
 
     if (GNUNET_OK !=
@@ -188,14 +195,14 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
     GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv,
                                         &coin_pub.eddsa_pub);
     TALER_coin_pub_hash (&coin_pub,
-                         ach,
+                         rci->h_age_commitment,
                          &coin_hash);
     if (GNUNET_OK !=
         TALER_planchet_to_coin (pk,
                                 &blind_sig,
                                 &bks,
                                 &rci->coin_priv,
-                                ach,
+                                rci->h_age_commitment,
                                 &coin_hash,
                                 &rrh->alg_values[i],
                                 &coin))
diff --git a/src/testing/test_exchange_api_twisted.c 
b/src/testing/test_exchange_api_twisted.c
index 33631764..f8cfa64b 100644
--- a/src/testing/test_exchange_api_twisted.c
+++ b/src/testing/test_exchange_api_twisted.c
@@ -124,6 +124,7 @@ run (void *cls,
     TALER_TESTING_cmd_withdraw_amount ("refresh-withdraw-coin",
                                        "refresh-create-reserve",
                                        "EUR:5",
+                                       0, /* age restriction off */
                                        MHD_HTTP_OK),
     TALER_TESTING_cmd_deposit ("refresh-deposit-partial",
                                "refresh-withdraw-coin",
@@ -164,6 +165,7 @@ run (void *cls,
     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-r1",
                                        "create-reserve-r1",
                                        "EUR:5",
+                                       0, /* age restriction off */
                                        MHD_HTTP_OK),
     TALER_TESTING_cmd_deposit ("deposit-refund-1",
                                "withdraw-coin-r1",
@@ -233,6 +235,7 @@ run (void *cls,
     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-r2",
                                        "create-reserve-r2",
                                        "EUR:5",
+                                       0, /* age restriction off */
                                        MHD_HTTP_OK),
     TALER_TESTING_cmd_end ()
   };
diff --git a/src/testing/testing_api_cmd_insert_deposit.c 
b/src/testing/testing_api_cmd_insert_deposit.c
index dcda7cf3..f0204067 100644
--- a/src/testing/testing_api_cmd_insert_deposit.c
+++ b/src/testing/testing_api_cmd_insert_deposit.c
@@ -212,7 +212,7 @@ insert_deposit_run (void *cls,
     GNUNET_assert (GNUNET_OK ==
                    TALER_denom_blind (&dpk,
                                       &bks,
-                                      NULL, /* FIXME-Oec */
+                                      NULL, /* no age restriction active */
                                       &deposit.coin.coin_pub,
                                       &alg_values,
                                       &c_hash,
diff --git a/src/testing/testing_api_cmd_refresh.c 
b/src/testing/testing_api_cmd_refresh.c
index 11c88c19..8ae4ab93 100644
--- a/src/testing/testing_api_cmd_refresh.c
+++ b/src/testing/testing_api_cmd_refresh.c
@@ -836,6 +836,7 @@ refresh_link_run (void *cls,
   /* finally, use private key from withdraw sign command */
   rls->rlh = TALER_EXCHANGE_link (is->exchange,
                                   coin_priv,
+                                  rms->age_commitment,
                                   &link_cb,
                                   rls);
 
@@ -1149,28 +1150,29 @@ melt_run (void *cls,
     rms->refresh_data.melt_pk = *melt_denom_pub;
     rms->refresh_data.fresh_pks = rms->fresh_pks;
     rms->refresh_data.fresh_pks_len = num_fresh_coins;
-/* FIXME-oec:  is this needed _here_?
+    rms->refresh_data.age_commitment = NULL;
+
+    GNUNET_assert (age_restricted ==
+                   (NULL != rms->age_commitment));
+
+    if (NULL != rms->age_commitment)
     {
-      struct TALER_AgeCommitment *ac = NULL;
+      struct TALER_AgeCommitment *ac;
+      uint32_t seed;
 
-      GNUNET_assert (age_restricted == (NULL != rms->age_commitment));
+      ac = GNUNET_new (struct TALER_AgeCommitment);
+      seed  = GNUNET_CRYPTO_random_u32 (
+        GNUNET_CRYPTO_QUALITY_WEAK,
+        UINT32_MAX);
 
-      if (NULL != rms->age_commitment)
-      {
-        uint32_t seed = GNUNET_CRYPTO_random_u32 (
-          GNUNET_CRYPTO_QUALITY_WEAK,
-          UINT32_MAX);
-
-        GNUNET_assert (GNUNET_OK ==
-                       TALER_age_commitment_derive (
-                         rms->age_commitment,
-                         seed,
-                         ac));
-      }
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_age_commitment_derive (
+                       rms->age_commitment,
+                       seed,
+                       ac));
 
-      rms->refresh_data.age_commitment = ac
+      rms->refresh_data.age_commitment = ac;
     }
-*/
 
     rms->rmh = TALER_EXCHANGE_melt (is->exchange,
                                     &rms->rms,
diff --git a/src/util/crypto.c b/src/util/crypto.c
index 6bea984f..39a9c7f1 100644
--- a/src/util/crypto.c
+++ b/src/util/crypto.c
@@ -90,7 +90,7 @@ TALER_test_coin_valid (const struct TALER_CoinPublicInfo 
*coin_public_info,
 #endif
 
   TALER_coin_pub_hash (&coin_public_info->coin_pub,
-                       &coin_public_info->age_commitment_hash,
+                       &coin_public_info->h_age_commitment,
                        &c_hash);
 
   if (GNUNET_OK !=
@@ -681,7 +681,7 @@ FAIL:
 
 
 void
-TALER_age_restriction_commmitment_free_inside (
+TALER_age_commitment_free (
   struct TALER_AgeCommitment *commitment)
 {
   if (NULL == commitment)
@@ -703,7 +703,7 @@ TALER_age_restriction_commmitment_free_inside (
     commitment->priv = NULL;
   }
 
-  /* Caller is responsible for commitment itself */
+  GNUNET_free (commitment);
 }
 
 
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 88cd8de0..6c664bbd 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -143,7 +143,6 @@ TALER_wallet_link_verify (
   const struct TALER_TransferPublicKeyP *transfer_pub,
   const struct TALER_BlindedCoinHash *h_coin_ev,
   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
-  const struct TALER_AgeCommitmentHash *h_age_commitment,
   const struct TALER_CoinSpendSignatureP *coin_sig)
 {
   struct TALER_LinkDataPS ldp = {
@@ -152,12 +151,8 @@ TALER_wallet_link_verify (
     .h_denom_pub = *h_denom_pub,
     .transfer_pub = *transfer_pub,
     .coin_envelope_hash = *h_coin_ev,
-    .h_age_commitment = {{{0}}}
   };
 
-  if (NULL != h_age_commitment)
-    ldp.h_age_commitment = *h_age_commitment;
-
   return
     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
                                 &ldp,

-- 
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]