From e9eb00e285c80f63cfc08fdd9ea6707d55162e60 Mon Sep 17 00:00:00 2001 From: Özgür Kesim Date: Tue, 1 Mar 2022 17:02:37 +0100 Subject: Refactoring TALER_AgeCommitment Instead of a single struct TALER_AgeCommitment, we now use 1. TALER_AgeCommitment for the age mask and list public keys for age restriciton. 2. TALER_AgeProof for list of private keys for age restriction 3. TALER_AgeCommitmentProof for the aggregation of the former two. Also, we introduce TALER_AgeAttestation as the EDDSA signature to attest a particular age group, along with the function prototypes TALER_age_commitment_attest and TALER_age_commitment_verify. --- src/benchmark/taler-aggregator-benchmark.c | 6 +- .../taler-exchange-httpd_refreshes_reveal.c | 18 ++-- src/include/taler_crypto_lib.h | 85 ++++++++++++++-- src/include/taler_exchange_service.h | 13 +-- src/include/taler_testing_lib.h | 1 + src/lib/exchange_api_link.c | 23 +++-- src/lib/exchange_api_refresh_common.c | 13 +-- src/lib/exchange_api_refresh_common.h | 14 +-- src/lib/exchange_api_refreshes_reveal.c | 19 ++-- src/testing/testing_api_cmd_deposit.c | 25 ++--- src/testing/testing_api_cmd_refresh.c | 29 +++--- src/testing/testing_api_cmd_withdraw.c | 24 ++--- src/util/crypto.c | 113 +++++++++++++-------- src/util/wallet_signatures.c | 4 +- 14 files changed, 248 insertions(+), 139 deletions(-) (limited to 'src') diff --git a/src/benchmark/taler-aggregator-benchmark.c b/src/benchmark/taler-aggregator-benchmark.c index 6d5df1e64..6db083426 100644 --- a/src/benchmark/taler-aggregator-benchmark.c +++ b/src/benchmark/taler-aggregator-benchmark.c @@ -532,7 +532,7 @@ run (void *cls, struct TALER_AgeMask mask = { .mask = 1 || 1 << 8 || 1 << 12 || 1 << 16 || 1 << 18 }; - struct TALER_AgeCommitment ac = {0}; + struct TALER_AgeCommitmentProof acp = {0}; seed = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); @@ -542,9 +542,9 @@ run (void *cls, &mask, 13, seed, - &ac)); + &acp)); - TALER_age_commitment_hash (&ac, &hac); + TALER_age_commitment_hash (&acp.commitment, &hac); } GNUNET_assert (GNUNET_OK == diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c b/src/exchange/taler-exchange-httpd_refreshes_reveal.c index 23620f87a..caba557c5 100644 --- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c +++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c @@ -296,18 +296,23 @@ check_commitment (struct RevealContext *rctx, * the transfer_secret and the old age commitment. */ if (NULL != rctx->old_age_commitment) { - struct TALER_AgeCommitment ac = {0}; - struct TALER_AgeCommitmentHash h = {0}; uint64_t seed = (uint64_t) ts.key.bits[0] | (uint64_t) ts.key.bits[1] << 32; + struct TALER_AgeCommitmentProof acp = { + /* we only need the commitment, not the proof, for the call to + * TALER_age_commitment_derive. */ + .commitment = *(rctx->old_age_commitment) + }; + struct TALER_AgeCommitmentProof nacp = {0}; + struct TALER_AgeCommitmentHash h = {0}; GNUNET_assert (GNUNET_OK == TALER_age_commitment_derive ( - rctx->old_age_commitment, + &acp, seed, - &ac)); + &nacp)); - TALER_age_commitment_hash (&ac, &h); + TALER_age_commitment_hash (&nacp.commitment, &h); hac = &h; } @@ -614,8 +619,7 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection, rctx->old_age_commitment = GNUNET_new (struct TALER_AgeCommitment); oac = rctx->old_age_commitment; oac->mask = TEH_age_mask; - oac->num_pub = ng; - oac->num_priv = 0; /* no private keys are needed for the reveal phase */ + oac->num = ng; oac->pub = GNUNET_new_array (ng, struct TALER_AgeCommitmentPublicKeyP); /* Extract old age commitment */ diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index ed447e905..38f91a8e0 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -864,6 +864,14 @@ struct TALER_AgeCommitmentHash struct GNUNET_ShortHashCode shash; }; +/** + * @brief Signature of an age with the private key for the corresponding age group of an age commitment. + */ +struct TALER_AgeAttestation +{ + struct GNUNET_CRYPTO_EddsaSignature attest; +}; + extern const struct TALER_AgeCommitmentHash TALER_ZeroAgeCommitmentHash; #define TALER_AgeCommitmentHash_isNullOrZero(ph) ((NULL == ph) || \ (0 == memcmp (ph, \ @@ -3307,7 +3315,7 @@ struct TALER_AgeCommitment /* The number of public keys, which must be the same as the number of * groups in the mask. */ - size_t num_pub; + size_t num; /* The list of #num_pub public keys. In must have same size as the number of * age groups defined in the mask. @@ -3319,12 +3327,17 @@ struct TALER_AgeCommitment * The list has been allocated via GNUNET_malloc. */ struct TALER_AgeCommitmentPublicKeyP *pub; +}; +struct TALER_AgeProof +{ /* The number of private keys, which must be at most num_pub_keys. One minus * this number corresponds to the largest age group that is supported with * this age commitment. + * **Note**, that this and the next field are only relevant on the wallet + * side for attestation and derive operations. */ - size_t num_priv; + size_t num; /* List of #num_priv private keys. * @@ -3337,6 +3350,12 @@ struct TALER_AgeCommitment struct TALER_AgeCommitmentPrivateKeyP *priv; }; +struct TALER_AgeCommitmentProof +{ + struct TALER_AgeCommitment commitment; + struct TALER_AgeProof proof; +}; + /* * @brief Generates a hash of the public keys in the age commitment. * @@ -3354,7 +3373,7 @@ TALER_age_commitment_hash ( * @param mask The age mask the defines the age groups * @param age The actual age for which an age commitment is generated * @param salt The salt that goes into the key generation. MUST be choosen uniformly random. - * @param commitment[out] The generated age commitment, ->priv and ->pub allocated via GNUNET_malloc on success + * @param comm_proof[out] The generated age commitment, ->priv and ->pub allocated via GNUNET_malloc on success * @return GNUNET_OK on success, GNUNET_SYSERR otherwise */ enum GNUNET_GenericReturnValue @@ -3362,28 +3381,76 @@ TALER_age_restriction_commit ( const struct TALER_AgeMask *mask, const uint8_t age, const uint64_t salt, - struct TALER_AgeCommitment *commitment); + struct TALER_AgeCommitmentProof *comm_proof); /* * @brief Derives another, equivalent age commitment for a given one. * * @param orig Original age commitment * @param salt Salt to randomly move the points on the elliptic curve in order to generate another, equivalent commitment. - * @param derived[out] The resulting age commitment, ->priv and ->pub allocated via GNUNET_malloc on success. + * @param[out] derived The resulting age commitment, ->priv and ->pub allocated via GNUNET_malloc on success. * @return GNUNET_OK on success, GNUNET_SYSERR otherwise */ enum GNUNET_GenericReturnValue TALER_age_commitment_derive ( - const struct TALER_AgeCommitment *orig, + const struct TALER_AgeCommitmentProof *orig, const uint64_t salt, - struct TALER_AgeCommitment *derived); + struct TALER_AgeCommitmentProof *derived); + + +/* + * @brief Provide attestation for a given age, from a given age commitment, if possible. + * + * @param comm_proof The age commitment to be used for attestation. For successful attestation, it must contain the private key for the corresponding age group. + * @param age Age (not age group) for which the an attestation should be done + * @param[out] attest Signature of the age with the appropriate key from the age commitment for the corresponding age group, if applicaple. + * @return GNUNET_OK on success, GNUNET_NO when no attestation can be made for that age with the given commitment, GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +TALER_age_commitment_attest ( + const struct TALER_AgeCommitmentProof *comm_proof, + uint8_t age, + struct TALER_AgeAttestation *attest); + +/* + * @brief Verify the attestation for an given age and age commitment + * + * @param commitent The age commitment that went into the attestation. Only the public keys are needed. + * @param age Age (not age group) for which the an attestation should be done + * @param attest Signature of the age with the appropriate key from the age commitment for the corresponding age group, if applicaple. + * @return GNUNET_OK when the attestation was successfull, GNUNET_NO no attestation couldn't be verified, GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +TALER_age_commitment_verify ( + const struct TALER_AgeCommitment *commitment, + uint8_t age, + const struct TALER_AgeAttestation *attest); /* * @brief helper function to free memory of a struct TALER_AgeCommitment - * @param cmt the commitment from which all memory should be freed. + * + * @param p the commitment from which all memory should be freed. */ void TALER_age_commitment_free ( - struct TALER_AgeCommitment *cmt); + struct TALER_AgeCommitment *p); + +/* + * @brief helper function to free memory of a struct TALER_AgeProof + * + * @param p the proof of commitment from which all memory should be freed. + */ +void +TALER_age_proof_free ( + struct TALER_AgeProof *p); + +/* + * @brief helper function to free memory of a struct TALER_AgeCommitmentProof + * + * @param p the commitment and its proof from which all memory should be freed. + */ +void +TALER_age_commitment_proof_free ( + struct TALER_AgeCommitmentProof *p); #endif diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index d1800c01d..2a20bda73 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1682,10 +1682,10 @@ struct TALER_EXCHANGE_RefreshData struct TALER_CoinSpendPrivateKeyP melt_priv; /* - * age commitment and its hash that went into the original coin, might be - * NULL + * age commitment and proof and its hash that went into the original coin, + * might be NULL. */ - const struct TALER_AgeCommitment *melt_age_commitment; + const struct TALER_AgeCommitmentProof *melt_age_commitment_proof; const struct TALER_AgeCommitmentHash *melt_h_age_commitment; /** @@ -1858,7 +1858,7 @@ struct TALER_EXCHANGE_RevealedCoinInfo /** * Age commitment and its hash of the coin, might be NULL. */ - struct TALER_AgeCommitment *age_commitment; + struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentHash *h_age_commitment; /** @@ -2002,7 +2002,7 @@ struct TALER_EXCHANGE_LinkedCoinInfo /** * Age commitment and its hash, if applicable. Might be NULL. */ - struct TALER_AgeCommitment *age_commitment; + struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentHash *h_age_commitment; /** @@ -2092,7 +2092,8 @@ 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, + const struct + TALER_AgeCommitmentProof *age_commitment_proof, TALER_EXCHANGE_LinkCallback link_cb, void *link_cb_cls); diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h index 531d9d261..081a93478 100644 --- a/src/include/taler_testing_lib.h +++ b/src/include/taler_testing_lib.h @@ -2484,6 +2484,7 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits, op (denom_pub, const struct TALER_EXCHANGE_DenomPublicKey) \ op (denom_sig, const struct TALER_DenominationSignature) \ op (age_commitment, const struct TALER_AgeCommitment) \ + op (age_commitment_proof, const struct TALER_AgeCommitmentProof) \ op (h_age_commitment, const struct TALER_AgeCommitmentHash) \ op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues) \ diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c index fdb34f075..5840cac63 100644 --- a/src/lib/exchange_api_link.c +++ b/src/lib/exchange_api_link.c @@ -67,10 +67,10 @@ struct TALER_EXCHANGE_LinkHandle struct TALER_CoinSpendPrivateKeyP coin_priv; /** - * Age commitment of the original coin, might be NULL. - * Required to derive the new age commitment + * Age commitment and proof of the original coin, might be NULL. + * Required to derive the new age commitment and proof. */ - const struct TALER_AgeCommitment *age_commitment; + const struct TALER_AgeCommitmentProof *age_commitment_proof; }; @@ -143,25 +143,25 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh, &alg_values, &bks); - lci->age_commitment = NULL; + lci->age_commitment_proof = NULL; lci->h_age_commitment = NULL; /* Derive the age commitment and calculate the hash */ - if (NULL != lh->age_commitment) + if (NULL != lh->age_commitment_proof) { uint64_t seed = (uint64_t) secret.key.bits[0] | (uint64_t) secret.key.bits[1] << 32; - lci->age_commitment = GNUNET_new (struct TALER_AgeCommitment); + lci->age_commitment_proof = GNUNET_new (struct TALER_AgeCommitmentProof); lci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash); GNUNET_assert (GNUNET_OK == TALER_age_commitment_derive ( - lh->age_commitment, + lh->age_commitment_proof, seed, - lci->age_commitment)); + lci->age_commitment_proof)); TALER_age_commitment_hash ( - lci->age_commitment, + &(lci->age_commitment_proof->commitment), lci->h_age_commitment); } @@ -471,7 +471,8 @@ 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, + const struct + TALER_AgeCommitmentProof *age_commitment_proof, TALER_EXCHANGE_LinkCallback link_cb, void *link_cb_cls) { @@ -510,7 +511,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->age_commitment_proof = age_commitment_proof; lh->url = TEAH_path_to_url (exchange, arg_str); if (NULL == lh->url) diff --git a/src/lib/exchange_api_refresh_common.c b/src/lib/exchange_api_refresh_common.c index 997d1fec8..94d0dc8cb 100644 --- a/src/lib/exchange_api_refresh_common.c +++ b/src/lib/exchange_api_refresh_common.c @@ -78,7 +78,7 @@ TALER_EXCHANGE_get_melt_data_ ( md->melted_coin.fee_melt = rd->melt_pk.fees.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->melt_age_commitment; + md->melted_coin.age_commitment_proof = rd->melt_age_commitment_proof; md->melted_coin.h_age_commitment = rd->melt_h_age_commitment; GNUNET_assert (GNUNET_OK == @@ -183,24 +183,25 @@ TALER_EXCHANGE_get_melt_data_ ( bks); /* Handle age commitment, if present */ - if (NULL != md->melted_coin.age_commitment) + if (NULL != md->melted_coin.age_commitment_proof) { /* We use the first 8 bytes of the trans_sec to generate a new age * commitment */ uint64_t age_seed = (uint64_t) trans_sec.key.bits[0] | (uint64_t) trans_sec.key.bits[1] << 32; - fcd->age_commitment[i] = GNUNET_new (struct TALER_AgeCommitment); + fcd->age_commitment_proof[i] = GNUNET_new (struct + TALER_AgeCommitmentProof); ach = GNUNET_new (struct TALER_AgeCommitmentHash); GNUNET_assert (GNUNET_OK == TALER_age_commitment_derive ( - md->melted_coin.age_commitment, + md->melted_coin.age_commitment_proof, age_seed, - fcd->age_commitment[i])); + fcd->age_commitment_proof[i])); TALER_age_commitment_hash ( - fcd->age_commitment[i], + &fcd->age_commitment_proof[i]->commitment, ach); } diff --git a/src/lib/exchange_api_refresh_common.h b/src/lib/exchange_api_refresh_common.h index 8d7eb282e..c06824fec 100644 --- a/src/lib/exchange_api_refresh_common.h +++ b/src/lib/exchange_api_refresh_common.h @@ -53,10 +53,10 @@ struct MeltedCoin struct TALER_Amount original_value; /** - * The original age commitment and its hash. MUST be NULL if no age - * commitment was set. + * The original age commitment, its proof and its hash. MUST be NULL if no + * age commitment was set. */ - const struct TALER_AgeCommitment *age_commitment; + const struct TALER_AgeCommitmentProof *age_commitment_proof; const struct TALER_AgeCommitmentHash *h_age_commitment; /** @@ -100,11 +100,11 @@ struct FreshCoinData struct TALER_CoinSpendPrivateKeyP coin_priv; /** - * Arrays age commitments to be created, one for each cut-and-choose - * dimension. The entries in each list might be NULL and indicate no age - * commitment/restriction on the particular coin. + * Arrays of age commitments and proofs to be created, one for each + * cut-and-choose dimension. The entries in each list might be NULL and + * indicate no age commitment/restriction on the particular coin. */ - struct TALER_AgeCommitment *age_commitment[TALER_CNC_KAPPA]; + struct TALER_AgeCommitmentProof *age_commitment_proof[TALER_CNC_KAPPA]; /** * Blinding key secrets for the coins, depending on the diff --git a/src/lib/exchange_api_refreshes_reveal.c b/src/lib/exchange_api_refreshes_reveal.c index 881c7e731..6427c637b 100644 --- a/src/lib/exchange_api_refreshes_reveal.c +++ b/src/lib/exchange_api_refreshes_reveal.c @@ -156,21 +156,21 @@ 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->age_commitment_proof = fcd->age_commitment_proof[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)); + (NULL != rrh->md.melted_coin.age_commitment_proof) == + (NULL != rci->age_commitment_proof)); - if (NULL != rci->age_commitment) + if (NULL != rci->age_commitment_proof) { rci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash); TALER_age_commitment_hash ( - rci->age_commitment, + &rci->age_commitment_proof->commitment, rci->h_age_commitment); } @@ -429,18 +429,19 @@ TALER_EXCHANGE_refreshes_reveal ( } /* build array of old age commitment, if applicable */ - GNUNET_assert ((NULL == rd->melt_age_commitment) == + GNUNET_assert ((NULL == rd->melt_age_commitment_proof) == (NULL == rd->melt_h_age_commitment)); - if (NULL != rd->melt_age_commitment) + if (NULL != rd->melt_age_commitment_proof) { GNUNET_assert (NULL != (old_age_commitment = json_array ())); - for (size_t i = 0; i < rd->melt_age_commitment->num_pub; i++) + for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++) { GNUNET_assert (0 == json_array_append_new (old_age_commitment, GNUNET_JSON_from_data_auto ( - &rd->melt_age_commitment->pub[i]))); + &rd->melt_age_commitment_proof-> + commitment.pub[i]))); } } diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c index 33c1db447..2b9486ca5 100644 --- a/src/testing/testing_api_cmd_deposit.c +++ b/src/testing/testing_api_cmd_deposit.c @@ -287,7 +287,7 @@ deposit_run (void *cls, const struct TALER_TESTING_Command *coin_cmd; const struct TALER_CoinSpendPrivateKeyP *coin_priv; struct TALER_CoinSpendPublicKeyP coin_pub; - const struct TALER_AgeCommitment *age_commitment = NULL; + const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL; struct TALER_AgeCommitmentHash h_age_commitment = {0}; const struct TALER_EXCHANGE_DenomPublicKey *denom_pub; const struct TALER_DenominationSignature *denom_pub_sig; @@ -385,9 +385,9 @@ deposit_run (void *cls, ds->coin_index, &coin_priv)) || (GNUNET_OK != - TALER_TESTING_get_trait_age_commitment (coin_cmd, - ds->coin_index, - &age_commitment)) || + TALER_TESTING_get_trait_age_commitment_proof (coin_cmd, + ds->coin_index, + &age_commitment_proof)) || (GNUNET_OK != TALER_TESTING_get_trait_denom_pub (coin_cmd, ds->coin_index, @@ -405,9 +405,10 @@ deposit_run (void *cls, return; } - if (NULL != age_commitment) + if (NULL != age_commitment_proof) { - TALER_age_commitment_hash (age_commitment, &h_age_commitment); + TALER_age_commitment_hash (&age_commitment_proof->commitment, + &h_age_commitment); } ds->deposit_fee = denom_pub->fees.deposit; GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, @@ -533,7 +534,7 @@ deposit_traits (void *cls, const struct TALER_TESTING_Command *coin_cmd; /* Will point to coin cmd internals. */ const struct TALER_CoinSpendPrivateKeyP *coin_spent_priv; - const struct TALER_AgeCommitment *age_commitment; + const struct TALER_AgeCommitmentProof *age_commitment_proof; if (GNUNET_YES != ds->command_initialized) { @@ -556,9 +557,9 @@ deposit_traits (void *cls, ds->coin_index, &coin_spent_priv) || (GNUNET_OK != - TALER_TESTING_get_trait_age_commitment (coin_cmd, - ds->coin_index, - &age_commitment))) + TALER_TESTING_get_trait_age_commitment_proof (coin_cmd, + ds->coin_index, + &age_commitment_proof))) { GNUNET_break (0); TALER_TESTING_interpreter_fail (ds->is); @@ -573,8 +574,8 @@ deposit_traits (void *cls, /* These traits are always available */ TALER_TESTING_make_trait_coin_priv (index, coin_spent_priv), - TALER_TESTING_make_trait_age_commitment (index, - age_commitment), + TALER_TESTING_make_trait_age_commitment_proof (index, + age_commitment_proof), TALER_TESTING_make_trait_wire_details (ds->wire_details), TALER_TESTING_make_trait_contract_terms (ds->contract_terms), TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv), diff --git a/src/testing/testing_api_cmd_refresh.c b/src/testing/testing_api_cmd_refresh.c index 9a81a603d..e2ed8b216 100644 --- a/src/testing/testing_api_cmd_refresh.c +++ b/src/testing/testing_api_cmd_refresh.c @@ -71,9 +71,10 @@ struct TALER_TESTING_FreshCoinData struct TALER_CoinSpendPrivateKeyP coin_priv; /* - * Fresh age commitment for the coin and its hash, NULL if not applicable. + * Fresh age commitment for the coin with proof and its hash, NULL if not + * applicable. */ - struct TALER_AgeCommitment *age_commitment; + struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentHash *h_age_commitment; /** @@ -441,7 +442,7 @@ reveal_cb (void *cls, return; } fc->coin_priv = coin->coin_priv; - fc->age_commitment = coin->age_commitment; + fc->age_commitment_proof = coin->age_commitment_proof; fc->h_age_commitment = coin->h_age_commitment; TALER_denom_sig_deep_copy (&fc->sig, @@ -834,7 +835,7 @@ refresh_link_run (void *cls, /* finally, use private key from withdraw sign command */ rls->rlh = TALER_EXCHANGE_link (is->exchange, coin_priv, - rms->refresh_data.melt_age_commitment, + rms->refresh_data.melt_age_commitment_proof, &link_cb, rls); @@ -1044,7 +1045,7 @@ melt_run (void *cls, { struct TALER_Amount melt_amount; struct TALER_Amount fresh_amount; - const struct TALER_AgeCommitment *age_commitment; + const struct TALER_AgeCommitmentProof *age_commitment_proof; const struct TALER_AgeCommitmentHash *h_age_commitment; const struct TALER_DenominationSignature *melt_sig; const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub; @@ -1072,9 +1073,9 @@ melt_run (void *cls, } if (GNUNET_OK != - TALER_TESTING_get_trait_age_commitment (coin_command, - 0, - &age_commitment)) + TALER_TESTING_get_trait_age_commitment_proof (coin_command, + 0, + &age_commitment_proof)) { GNUNET_break (0); TALER_TESTING_interpreter_fail (rms->is); @@ -1159,13 +1160,13 @@ melt_run (void *cls, rms->refresh_data.melt_amount = melt_amount; rms->refresh_data.melt_sig = *melt_sig; rms->refresh_data.melt_pk = *melt_denom_pub; - rms->refresh_data.melt_age_commitment = age_commitment; + rms->refresh_data.melt_age_commitment_proof = age_commitment_proof; rms->refresh_data.melt_h_age_commitment = h_age_commitment; rms->refresh_data.fresh_pks = rms->fresh_pks; rms->refresh_data.fresh_pks_len = num_fresh_coins; GNUNET_assert (age_restricted == - (NULL != age_commitment)); + (NULL != age_commitment_proof)); rms->rmh = TALER_EXCHANGE_melt (is->exchange, &rms->rms, @@ -1251,9 +1252,9 @@ melt_traits (void *cls, &rms->fresh_pks[index]), TALER_TESTING_make_trait_coin_priv (index, rms->melt_priv), - TALER_TESTING_make_trait_age_commitment ( + TALER_TESTING_make_trait_age_commitment_proof ( index, - rms->refresh_data.melt_age_commitment), + rms->refresh_data.melt_age_commitment_proof), TALER_TESTING_make_trait_h_age_commitment ( index, rms->refresh_data.melt_h_age_commitment), @@ -1421,9 +1422,9 @@ refresh_reveal_traits (void *cls, TALER_TESTING_make_trait_coin_priv ( index, &rrs->fresh_coins[index].coin_priv), - TALER_TESTING_make_trait_age_commitment ( + TALER_TESTING_make_trait_age_commitment_proof ( index, - rrs->fresh_coins[index].age_commitment), + rrs->fresh_coins[index].age_commitment_proof), TALER_TESTING_make_trait_h_age_commitment ( index, rrs->fresh_coins[index].h_age_commitment), diff --git a/src/testing/testing_api_cmd_withdraw.c b/src/testing/testing_api_cmd_withdraw.c index 3974a1057..1c24d5a6c 100644 --- a/src/testing/testing_api_cmd_withdraw.c +++ b/src/testing/testing_api_cmd_withdraw.c @@ -138,10 +138,10 @@ struct WithdrawState uint8_t age; /** - * If age > 0, put here the corresponding age commitment and its hash, - * respectivelly, NULL otherwise. + * If age > 0, put here the corresponding age commitment with its proof and + * its hash, respectivelly, NULL otherwise. */ - struct TALER_AgeCommitment *age_commitment; + struct TALER_AgeCommitmentProof *age_commitment_proof; struct TALER_AgeCommitmentHash *h_age_commitment; /** @@ -524,10 +524,10 @@ withdraw_cleanup (void *cls, TALER_EXCHANGE_destroy_denomination_key (ws->pk); ws->pk = NULL; } - if (NULL != ws->age_commitment) + if (NULL != ws->age_commitment_proof) { - TALER_age_commitment_free (ws->age_commitment); - ws->age_commitment = NULL; + TALER_age_commitment_proof_free (ws->age_commitment_proof); + ws->age_commitment_proof = NULL; } if (NULL != ws->h_age_commitment) { @@ -579,7 +579,7 @@ withdraw_traits (void *cls, (const char **) &ws->reserve_payto_uri), TALER_TESTING_make_trait_exchange_url ( (const char **) &ws->exchange_url), - TALER_TESTING_make_trait_age_commitment (0, ws->age_commitment), + TALER_TESTING_make_trait_age_commitment_proof (0, ws->age_commitment_proof), TALER_TESTING_make_trait_h_age_commitment (0, ws->h_age_commitment), TALER_TESTING_trait_end () }; @@ -619,12 +619,12 @@ TALER_TESTING_cmd_withdraw_amount (const char *label, ws->age = age; if (0 < age) { - struct TALER_AgeCommitment *ac; + struct TALER_AgeCommitmentProof *acp; struct TALER_AgeCommitmentHash *hac; uint32_t seed; struct TALER_AgeMask mask; - ac = GNUNET_new (struct TALER_AgeCommitment); + acp = GNUNET_new (struct TALER_AgeCommitmentProof); hac = GNUNET_new (struct TALER_AgeCommitmentHash); seed = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); mask = TALER_extensions_age_restriction_ageMask (); @@ -634,7 +634,7 @@ TALER_TESTING_cmd_withdraw_amount (const char *label, &mask, age, seed, - ac)) + acp)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to generate age commitment for age %d at %s\n", @@ -643,8 +643,8 @@ TALER_TESTING_cmd_withdraw_amount (const char *label, GNUNET_assert (0); } - TALER_age_commitment_hash (ac,hac); - ws->age_commitment = ac; + TALER_age_commitment_hash (&acp->commitment,hac); + ws->age_commitment_proof = acp; ws->h_age_commitment = hac; } diff --git a/src/util/crypto.c b/src/util/crypto.c index bf91b6971..8e6c89aa9 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -459,11 +459,11 @@ TALER_age_commitment_hash ( } GNUNET_assert (__builtin_popcount (commitment->mask.mask) - 1 == - commitment->num_pub); + commitment->num); hash_context = GNUNET_CRYPTO_hash_context_start (); - for (size_t i = 0; i < commitment->num_pub; i++) + for (size_t i = 0; i < commitment->num; i++) { GNUNET_CRYPTO_hash_context_read (hash_context, &commitment->pub[i], @@ -507,7 +507,7 @@ TALER_age_restriction_commit ( const struct TALER_AgeMask *mask, const uint8_t age, const uint64_t salt, - struct TALER_AgeCommitment *new) + struct TALER_AgeCommitmentProof *new) { uint8_t num_pub = __builtin_popcount (mask->mask) - 1; uint8_t num_priv = get_age_group (mask, age) - 1; @@ -519,14 +519,14 @@ TALER_age_restriction_commit ( GNUNET_assert (31 > num_priv); GNUNET_assert (num_priv <= num_pub); - new->mask.mask = mask->mask; - new->num_pub = num_pub; - new->num_priv = num_priv; + new->commitment.mask.mask = mask->mask; + new->commitment.num = num_pub; + new->proof.num = num_priv; - new->pub = GNUNET_new_array ( + new->commitment.pub = GNUNET_new_array ( num_pub, struct TALER_AgeCommitmentPublicKeyP); - new->priv = GNUNET_new_array ( + new->proof.priv = GNUNET_new_array ( num_priv, struct TALER_AgeCommitmentPrivateKeyP); @@ -542,7 +542,7 @@ TALER_age_restriction_commit ( /* Only save the private keys for age groups less than num_priv */ if (i < num_priv) - priv = &new->priv[i]; + priv = &new->proof.priv[i]; if (GNUNET_OK != GNUNET_CRYPTO_kdf (priv, @@ -556,23 +556,23 @@ TALER_age_restriction_commit ( goto FAIL; GNUNET_CRYPTO_eddsa_key_get_public (&priv->eddsa_priv, - &new->pub[i].eddsa_pub); + &new->commitment.pub[i].eddsa_pub); } return GNUNET_OK; FAIL: - GNUNET_free (new->pub); - GNUNET_free (new->priv); + GNUNET_free (new->commitment.pub); + GNUNET_free (new->proof.priv); return GNUNET_SYSERR; } enum GNUNET_GenericReturnValue TALER_age_commitment_derive ( - const struct TALER_AgeCommitment *orig, + const struct TALER_AgeCommitmentProof *orig, const uint64_t salt, - struct TALER_AgeCommitment *new) + struct TALER_AgeCommitmentProof *new) { struct GNUNET_CRYPTO_EccScalar scalar; uint64_t saltBT = htonl (salt); @@ -618,27 +618,30 @@ TALER_age_commitment_derive ( * */ GNUNET_assert (NULL != new); - GNUNET_assert (orig->num_pub == __builtin_popcount (orig->mask.mask) - 1); - GNUNET_assert (orig->num_priv <= orig->num_pub); - - new->mask = orig->mask; - new->num_pub = orig->num_pub; - new->num_priv = orig->num_priv; - new->pub = GNUNET_new_array ( - new->num_pub, + GNUNET_assert (orig->commitment.num== __builtin_popcount ( + orig->commitment.mask.mask) - 1); + GNUNET_assert (orig->proof.num <= orig->commitment.num); + + new->commitment.mask = orig->commitment.mask; + new->commitment.num = orig->commitment.num; + new->proof.num = orig->proof.num; + new->commitment.pub = GNUNET_new_array ( + new->commitment.num, struct TALER_AgeCommitmentPublicKeyP); - new->priv = GNUNET_new_array ( - new->num_priv, + new->proof.priv = GNUNET_new_array ( + new->proof.num, struct TALER_AgeCommitmentPrivateKeyP); /* scalar multiply the public keys on the curve */ - for (size_t i = 0; i < orig->num_pub; i++) + for (size_t i = 0; i < orig->commitment.num; i++) { /* We shift all keys by the same scalar */ struct GNUNET_CRYPTO_EccPoint *p = (struct - GNUNET_CRYPTO_EccPoint *) &orig->pub[i]; + GNUNET_CRYPTO_EccPoint *) &orig-> + commitment.pub[i]; struct GNUNET_CRYPTO_EccPoint *np = (struct - GNUNET_CRYPTO_EccPoint *) &new->pub[i]; + GNUNET_CRYPTO_EccPoint *) &new-> + commitment.pub[i]; if (GNUNET_OK != GNUNET_CRYPTO_ecc_pmul_mpi ( p, @@ -651,7 +654,7 @@ TALER_age_commitment_derive ( /* multiply the private keys */ /* we borough ideas from GNUNET_CRYPTO_ecdsa_private_key_derive */ { - for (size_t i = 0; i < orig->num_priv; i++) + for (size_t i = 0; i < orig->proof.num; i++) { uint8_t dc[32]; gcry_mpi_t f, x, d, n; @@ -664,7 +667,7 @@ TALER_age_commitment_derive ( sizeof(factor)); for (size_t j = 0; j < 32; j++) - dc[i] = orig->priv[i].eddsa_priv.d[31 - j]; + dc[i] = orig->proof.priv[i].eddsa_priv.d[31 - j]; GNUNET_CRYPTO_mpi_scan_unsigned (&x, dc, sizeof(dc)); d = gcry_mpi_new (256); @@ -672,7 +675,7 @@ TALER_age_commitment_derive ( GNUNET_CRYPTO_mpi_print_unsigned (dc, sizeof(dc), d); for (size_t j = 0; j <32; j++) - new->priv[i].eddsa_priv.d[j] = dc[31 - 1]; + new->proof.priv[i].eddsa_priv.d[j] = dc[31 - 1]; sodium_memzero (dc, sizeof(dc)); gcry_mpi_release (d); @@ -690,8 +693,8 @@ TALER_age_commitment_derive ( return GNUNET_OK; FAIL: - GNUNET_free (new->pub); - GNUNET_free (new->priv); + GNUNET_free (new->commitment.pub); + GNUNET_free (new->proof.priv); return GNUNET_SYSERR; } @@ -703,23 +706,51 @@ TALER_age_commitment_free ( if (NULL == commitment) return; - if (NULL != commitment->priv) + if (NULL != commitment->pub) + { + GNUNET_free (commitment->pub); + commitment->pub = NULL; + } + GNUNET_free (commitment); +} + + +void +TALER_age_proof_free ( + struct TALER_AgeProof *proof) +{ + if (NULL != proof->priv) { GNUNET_CRYPTO_zero_keys ( - commitment->priv, - sizeof(*commitment->priv) * commitment->num_priv); + proof->priv, + sizeof(*proof->priv) * proof->num); - GNUNET_free (commitment->priv); - commitment->priv = NULL; + GNUNET_free (proof->priv); + proof->priv = NULL; } + GNUNET_free (proof); +} - if (NULL != commitment->pub) + +void +TALER_age_commitment_proof_free ( + struct TALER_AgeCommitmentProof *cp) +{ + if (NULL != cp->proof.priv) { - GNUNET_free (commitment->pub); - commitment->priv = NULL; + GNUNET_CRYPTO_zero_keys ( + cp->proof.priv, + sizeof(*cp->proof.priv) * cp->proof.num); + + GNUNET_free (cp->proof.priv); + cp->proof.priv = NULL; } - GNUNET_free (commitment); + if (NULL != cp->commitment.pub) + { + GNUNET_free (cp->commitment.pub); + cp->commitment.pub = NULL; + } } diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c index 7d07c9e77..84c0f06bd 100644 --- a/src/util/wallet_signatures.c +++ b/src/util/wallet_signatures.c @@ -32,9 +32,9 @@ TALER_wallet_deposit_sign ( const struct TALER_AgeCommitmentHash *h_age_commitment, const struct TALER_ExtensionContractHashP *h_extensions, const struct TALER_DenominationHashP *h_denom_pub, - struct GNUNET_TIME_Timestamp wallet_timestamp, + const struct GNUNET_TIME_Timestamp wallet_timestamp, const struct TALER_MerchantPublicKeyP *merchant_pub, - struct GNUNET_TIME_Timestamp refund_deadline, + const struct GNUNET_TIME_Timestamp refund_deadline, const struct TALER_CoinSpendPrivateKeyP *coin_priv, struct TALER_CoinSpendSignatureP *coin_sig) { -- cgit v1.2.3