diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index b726972ce..06247689f 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -587,6 +587,29 @@ struct TALER_DenominationPublicKey }; +/** + * Client-side secrets for blinding. + */ +struct TALER_BlindingSecret +{ + + /** + * Type of the blinding secret. + */ + enum TALER_DenominationCipher cipher; + + union + { + + /** + * Blinding key secret for RSA. + */ + struct GNUNET_CRYPTO_RsaBlindingKeySecret rsa_bks; + + } details; +}; + + /** * @brief Type of private signing keys for blind signing of coins. */ @@ -677,6 +700,27 @@ void TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub); +/** + * Create a blinding secret @a bs for @a cipher. + * + * @param[out] blinding secret to initialize + * @param cipher cipher to create blinding secret for + */ +enum GNUNET_GenericReturnValue +TALER_blinding_secret_create (struct TALER_BlindingSecret *bs, + enum TALER_DenominationCipher cipher, + ...); + + +/** + * Release memory inside of a blinding secret @a bs. + * + * @param[in] blinding secret to free + */ +void +TALER_blinding_secret_free (struct TALER_BlindingSecret *bs); + + /** * Initialize denomination public-private key pair. * @@ -731,6 +775,23 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig, size_t blinded_msg_size); +/** + * Unblind blinded signature. + * + * @param[out] denom_sig where to write the unblinded signature + * @param bdenom_sig the blinded signature + * @param bks blinding secret to use + * @param denom_pub public key used for signing + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +TALER_denom_sig_unblind (struct TALER_DenominationSignature *denom_sig, + const struct + TALER_BlindedDenominationSignature *bdenom_sig, + const struct TALER_BlindingSecret *bks, + const struct TALER_DenominationPublicKey *denom_pub); + + /** * Free internals of @a denom_sig, but not @a denom_sig itself. * diff --git a/src/util/denom.c b/src/util/denom.c index f251d9052..725e294d6 100644 --- a/src/util/denom.c +++ b/src/util/denom.c @@ -109,6 +109,94 @@ TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig, } +enum GNUNET_GenericReturnValue +TALER_denom_sig_unblind (struct TALER_DenominationSignature *denom_sig, + const struct + TALER_BlindedDenominationSignature *bdenom_sig, + const struct TALER_BlindingSecret *bks, + const struct TALER_DenominationPublicKey *denom_pub) +{ + if (bks->cipher != denom_pub->cipher) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (bdenom_sig->cipher != denom_pub->cipher) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + switch (denom_pub->cipher) + { + case TALER_DENOMINATION_INVALID: + GNUNET_break (0); + return GNUNET_SYSERR; + case TALER_DENOMINATION_RSA: + denom_sig->details.rsa_signature + = TALER_rsa_unblind ( + bdenom_sig->details.blinded_rsa_signature, + &bks->details.rsa_bks, + denom_pub->details.rsa_public_key); + if (NULL == denom_sig->details.rsa_signature) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + denom_sig->cipher = TALER_DENOMINATION_RSA; + return GNUNET_OK; + // TODO: add case for Clause-Schnorr + default: + GNUNET_break (0); + } + return GNUNET_SYSERR; +} + + +enum GNUNET_GenericReturnValue +TALER_blinding_secret_create (struct TALER_BlindingSecret *bs, + enum TALER_DenominationCipher cipher, + ...) +{ + memset (bs, + 0, + sizeof (*bs)); + switch (bs->cipher) + { + case TALER_DENOMINATION_INVALID: + return GNUNET_OK; + case TALER_DENOMINATION_RSA: + bs->cipher = TALER_DENOMINATION_RSA; + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + &bs->details.rsa_bks, + sizeof (bs->details.rsa_bks)); + return GNUNET_OK; + // TODO: add case for Clause-Schnorr + default: + GNUNET_break (0); + } + return GNUNET_SYSERR; +} + + +void +TALER_blinding_secret_free (struct TALER_BlindingSecret *bs) +{ + switch (bs->cipher) + { + case TALER_DENOMINATION_INVALID: + return; + case TALER_DENOMINATION_RSA: + memset (bs, + 0, + sizeof (*bs)); + return; + // TODO: add case for Clause-Schnorr + default: + GNUNET_break (0); + } +} + + void TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub, struct TALER_DenominationHash *denom_hash) diff --git a/src/util/test_helper_rsa.c b/src/util/test_helper_rsa.c index 24d7a4cca..bf79e1e43 100644 --- a/src/util/test_helper_rsa.c +++ b/src/util/test_helper_rsa.c @@ -133,9 +133,7 @@ key_cb (void *cls, { keys[i].valid = false; keys[i].revoked = false; - GNUNET_CRYPTO_rsa_public_key_free ( - keys[i].denom_pub.details.rsa_public_key); - keys[i].denom_pub.details.rsa_public_key = NULL; + TALER_denom_pub_free (&keys[i].denom_pub); GNUNET_assert (num_keys > 0); num_keys--; found = true; @@ -157,8 +155,8 @@ key_cb (void *cls, keys[i].start_time = start_time; keys[i].validity_duration = validity_duration; keys[i].denom_pub = *denom_pub; - keys[i].denom_pub.details.rsa_public_key - = GNUNET_CRYPTO_rsa_public_key_dup (denom_pub->details.rsa_public_key); + TALER_denom_pub_deep_copy (&keys[i].denom_pub, + denom_pub); num_keys++; return; } @@ -241,11 +239,11 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh) enum TALER_ErrorCode ec; bool success = false; struct TALER_CoinPubHash m_hash; - struct GNUNET_CRYPTO_RsaBlindingKeySecret bks; + struct TALER_BlindingSecret bks; - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - &bks, - sizeof (bks)); + GNUNET_assert (GNUNET_OK == + TALER_blinding_secret_create (&bks, + TALER_DENOMINATION_RSA)); GNUNET_CRYPTO_hash ("Hello", strlen ("Hello"), &m_hash.hash); @@ -259,7 +257,7 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh) GNUNET_assert (GNUNET_YES == TALER_rsa_blind (&m_hash, - &bks, + &bks.details.rsa_bks, keys[i].denom_pub.details.rsa_public_key, &buf, &buf_size)); @@ -294,12 +292,11 @@ test_signing (struct TALER_CRYPTO_DenominationHelper *dh) { struct TALER_DenominationSignature rs; - rs.cipher = TALER_DENOMINATION_RSA; - rs.details.rsa_signature - = TALER_rsa_unblind (ds.details.blinded_rsa_signature, - &bks, - keys[i].denom_pub.details.rsa_public_key); - if (NULL == rs.details.rsa_signature) + if (GNUNET_OK != + TALER_denom_sig_unblind (&rs, + &ds, + &bks, + &keys[i].denom_pub)) { GNUNET_break (0); return 6;