exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 97af2363b285165fdbdb6fdaa80fec28791b143b
parent 3f891d944f141b4317b0c2c25f82e9e4053ce8ab
Author: Özgür Kesim <oec@codeblau.de>
Date:   Wed, 30 Apr 2025 23:37:28 +0200

[exchange] fix calculation of planchets_h in age-proof-required case

Diffstat:
Msrc/exchange/taler-exchange-httpd_reveal-withdraw.c | 93++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/lib/exchange_api_reveal_withdraw.c | 11++++++-----
Msrc/lib/exchange_api_withdraw.c | 17+++++++++++++++--
3 files changed, 75 insertions(+), 46 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_reveal-withdraw.c b/src/exchange/taler-exchange-httpd_reveal-withdraw.c @@ -405,29 +405,42 @@ verify_commitment_and_max_age ( for (uint8_t gamma = 0; gamma<TALER_CNC_KAPPA; gamma++) { - cs_idx = 0; - - /* Expand the secrets for a disclosed batch */ - if (gamma != wd->noreveal_index) + if (gamma == wd->noreveal_index) + { + /** + * For the disclosed index, all we have to do is to accumulate the hash + * of the selected coins + */ + GNUNET_CRYPTO_hash_context_read ( + hash_context, + &wd->selected_h, + sizeof(wd->selected_h)); + } + else { + /** + * For the non-disclosed index, we have to generate the planchets in + * this batch and calculate their hash + */ + struct GNUNET_HashContext *batch_ctx; + struct TALER_BlindedCoinHashP batch_h; + cs_idx = 0; + + batch_ctx = GNUNET_CRYPTO_hash_context_start (); + GNUNET_assert (NULL != batch_ctx); + + /* Expand the secrets for a disclosed batch */ GNUNET_assert (secrets_idx < (TALER_CNC_KAPPA - 1)); TALER_withdraw_expand_secrets ( wd->num_coins, &disclosed_batch_seeds->tuple[secrets_idx], secrets[secrets_idx]); - } - for (size_t coin_idx = 0; coin_idx < wd->num_coins; coin_idx++) - { - /* Now find or create the actual hash of the blinded planchet */ - if (gamma == wd->noreveal_index) - { - GNUNET_CRYPTO_hash_context_read ( - hash_context, - &wd->selected_h, - sizeof(wd->selected_h)); - } - else /* disclosed case: we need to create the blinded hash ourselves */ + /** + * Now individually create each coin in this batch and calculate + * its hash, and accumulate the hash of the batch with it + */ + for (size_t coin_idx = 0; coin_idx < wd->num_coins; coin_idx++) { struct TALER_BlindedCoinHashP bch; struct GNUNET_CRYPTO_CSPublicRPairP *rp; @@ -445,41 +458,43 @@ verify_commitment_and_max_age ( np = NULL; rp = NULL; } - - ret = calculate_blinded_hash ( - con, - denom_keys[coin_idx], - &secrets[secrets_idx][coin_idx], - rp, - np, - wd->max_age, - &bch, - result); - - + ret = calculate_blinded_hash (con, + denom_keys[coin_idx], + &secrets[secrets_idx][coin_idx], + rp, + np, + wd->max_age, + &bch, + result); if (GNUNET_OK != ret) { GNUNET_CRYPTO_hash_context_abort (hash_context); return GNUNET_SYSERR; } - - /* Continue the running hash of all coin hashes with the calculated - * hash-value of the current, disclosed coin */ - GNUNET_CRYPTO_hash_context_read (hash_context, + /** + * Continue the running hash of all coin hashes in the batch + * with the calculated hash-value of the current, disclosed coin + */ + GNUNET_CRYPTO_hash_context_read (batch_ctx, &bch, sizeof(bch)); } - } /* for-loop over num_coins */ + /** + * Finalize the hash of this batch and add it to + * the total hash + */ + GNUNET_CRYPTO_hash_context_finish ( + batch_ctx, + &batch_h.hash); + GNUNET_CRYPTO_hash_context_read ( + hash_context, + &batch_h, + sizeof(batch_h)); - /** - * Only for the disclosed indices do we increment the index - * into secrets. - */ - if (gamma != wd->noreveal_index) secrets_idx++; + } } } -#pragma message "complete rewrite calculate_blinded_hash" /* Finally, compare the calculated hash with the original wd */ { diff --git a/src/lib/exchange_api_reveal_withdraw.c b/src/lib/exchange_api_reveal_withdraw.c @@ -43,7 +43,7 @@ struct TALER_EXCHANGE_RevealWithdrawHandle /** * The commitment from the previous call withdraw */ - const struct TALER_HashBlindedPlanchetsP *h_planchets; + const struct TALER_HashBlindedPlanchetsP *planchets_h; /** * Number of coins for which to reveal tuples of seeds @@ -278,8 +278,8 @@ perform_protocol ( json_t *j_request_body; j_request_body = GNUNET_JSON_PACK ( - GNUNET_JSON_pack_data_auto ("h_planchets", - wrh->h_planchets), + GNUNET_JSON_pack_data_auto ("planchets_h", + wrh->planchets_h), GNUNET_JSON_pack_array_steal ("disclosed_batch_seeds", j_array_of_secrets)); GNUNET_assert (NULL != j_request_body); @@ -290,6 +290,7 @@ perform_protocol ( TALER_curl_easy_post (&wrh->post_ctx, curlh, j_request_body)); + json_decref (j_request_body); } @@ -316,14 +317,14 @@ TALER_EXCHANGE_reveal_withdraw ( struct GNUNET_CURL_Context *curl_ctx, const char *exchange_url, size_t num_coins, - const struct TALER_HashBlindedPlanchetsP *h_planchets, + const struct TALER_HashBlindedPlanchetsP *planchets_h, const struct TALER_RevealWithdrawMasterSeedsP *seeds, TALER_EXCHANGE_RevealWithdrawCallback reveal_cb, void *reveal_cb_cls) { struct TALER_EXCHANGE_RevealWithdrawHandle *wrh = GNUNET_new (struct TALER_EXCHANGE_RevealWithdrawHandle); - wrh->h_planchets = h_planchets; + wrh->planchets_h = planchets_h; wrh->num_coins = num_coins; wrh->seeds = *seeds; wrh->callback = reveal_cb; diff --git a/src/lib/exchange_api_withdraw.c b/src/lib/exchange_api_withdraw.c @@ -818,6 +818,12 @@ perform_withdraw_protocol ( */ for (size_t k = 0; k < TALER_CNC_KAPPA; k++) { + struct GNUNET_HashContext *batch_ctx; + struct TALER_BlindedCoinHashP batch_h; + + batch_ctx = GNUNET_CRYPTO_hash_context_start (); + FAIL_IF (NULL == batch_ctx); + for (size_t i = 0; i< wbh->num_input; i++) { const struct TALER_PlanchetDetail *planchet = @@ -838,11 +844,18 @@ perform_withdraw_protocol ( &bch); GNUNET_CRYPTO_hash_context_read ( - coins_hctx, + batch_ctx, &bch, sizeof(bch)); - } + + GNUNET_CRYPTO_hash_context_finish ( + batch_ctx, + &batch_h.hash); + GNUNET_CRYPTO_hash_context_read ( + coins_hctx, + &batch_h, + sizeof(batch_h)); } }