crypto implementation

This commit is contained in:
Gian Demarmels 2022-02-05 00:32:53 +01:00
parent ed136c1f2d
commit c42376cf40
No known key found for this signature in database
GPG Key ID: 030CEDDCCC92D778
3 changed files with 126 additions and 100 deletions

View File

@ -455,6 +455,25 @@ struct TALER_RsaPubHashP
struct GNUNET_HashCode hash; struct GNUNET_HashCode hash;
}; };
GNUNET_NETWORK_STRUCT_BEGIN
/**
* Master key material for the deriviation of
* private coins and blinding factors.
*/
struct TALER_PlanchetSecretsP
{
/**
* Key material.
*/
uint32_t key_data[8];
};
GNUNET_NETWORK_STRUCT_END
/** /**
* Hash @a rsa. * Hash @a rsa.
@ -990,11 +1009,14 @@ TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub);
/** /**
* Create private key for a Taler coin. * Create private key for a Taler coin.
* * @param ps planchet secret to derive coin priv key
* @param alg_values includes algorithm specific values
* @param[out] coin_priv private key to initialize * @param[out] coin_priv private key to initialize
*/ */
void void
TALER_planchet_setup_coin_priv ( TALER_planchet_setup_coin_priv (
const struct TALER_PlanchetSecretsP *ps,
const struct TALER_ExchangeWithdrawValues *alg_values,
struct TALER_CoinSpendPrivateKeyP *coin_priv); struct TALER_CoinSpendPrivateKeyP *coin_priv);
@ -1302,27 +1324,6 @@ void
TALER_payto_hash (const char *payto, TALER_payto_hash (const char *payto,
struct TALER_PaytoHash *h_payto); struct TALER_PaytoHash *h_payto);
GNUNET_NETWORK_STRUCT_BEGIN
/**
* Master key material for the deriviation of
* private coins and blinding factors.
*/
struct TALER_PlanchetSecretsP
{
/**
* Key material.
*/
uint32_t key_data[8];
};
GNUNET_NETWORK_STRUCT_END
/** /**
* Details about a planchet that the customer wants to obtain * Details about a planchet that the customer wants to obtain
* a withdrawal authorization. This is the information that * a withdrawal authorization. This is the information that
@ -1465,10 +1466,10 @@ GNUNET_NETWORK_STRUCT_END
* @param[out] ps value to initialize * @param[out] ps value to initialize
*/ */
void void
XXXTALER_planchet_setup_refresh (const struct TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
TALER_TransferSecretP *secret_seed,
uint32_t coin_num_salt, uint32_t coin_num_salt,
struct TALER_PlanchetSecretsP *ps); struct TALER_CoinSpendPrivateKeyP *coin_priv,
union TALER_DenominationBlindingKeyP *bks);
/** /**
@ -1485,21 +1486,25 @@ TALER_planchet_setup_random (
/** /**
* Create a blinding secret @a bs for @a cipher. * Create a blinding secret @a bs for @a cipher.
* *
* @param[out] ps planchet with blinding secret to initialize * @param ps secret to derive blindings from
* @param alg_values withdraw values containing cipher and additional CS values * @param alg_values withdraw values containing cipher and additional CS values
* @param bks blinding secrets
*/ */
void void
XXXTALER_planchet_blinding_secret_create (struct TALER_PlanchetSecretsP *ps, TALER_planchet_blinding_secret_create (const struct TALER_PlanchetSecretsP *ps,
const struct const struct
TALER_ExchangeWithdrawValues * TALER_ExchangeWithdrawValues *alg_values,
alg_values); union TALER_DenominationBlindingKeyP *bks);
/** /**
* Prepare a planchet for tipping. Creates and blinds a coin. * Prepare a planchet for tipping. Creates and blinds a coin.
* *
* @param dk denomination key for the coin to be created * @param dk denomination key for the coin to be created
* @param ps secret planchet internals (for #TALER_planchet_to_coin) * @param alg_values algorithm specific values
* @param bks blinding secrets
* @param coin_priv coin private key
* @param[out] c_hash set to the hash of the public key of the coin (needed later) * @param[out] c_hash set to the hash of the public key of the coin (needed later)
* @param[out] pd set to the planchet detail for TALER_MERCHANT_tip_pickup() and * @param[out] pd set to the planchet detail for TALER_MERCHANT_tip_pickup() and
* other withdraw operations, pd->blinded_planchet.cipher will be set * other withdraw operations, pd->blinded_planchet.cipher will be set
@ -1507,12 +1512,13 @@ XXXTALER_planchet_blinding_secret_create (struct TALER_PlanchetSecretsP *ps,
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
XXXTALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
const struct const struct TALER_ExchangeWithdrawValues *alg_values,
TALER_ExchangeWithdrawValues *alg_values, const union TALER_DenominationBlindingKeyP *bks,
struct TALER_PlanchetSecretsP *ps, const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinPubHash *c_hash, struct TALER_CoinPubHash *c_hash,
struct TALER_PlanchetDetail *pd); struct TALER_PlanchetDetail *pd
);
/** /**
@ -1531,19 +1537,20 @@ TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet);
* *
* @param dk denomination key, must match what was given to #TALER_planchet_prepare() * @param dk denomination key, must match what was given to #TALER_planchet_prepare()
* @param blind_sig blind signature from the exchange * @param blind_sig blind signature from the exchange
* @param ps secrets from #TALER_planchet_prepare() * @param bks blinding key secret
* @param coin_priv private key of the coin
* @param c_hash hash of the coin's public key for verification of the signature * @param c_hash hash of the coin's public key for verification of the signature
* @param[out] coin set to the details of the fresh coin * @param[out] coin set to the details of the fresh coin
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
*/ */
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
XXXTALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk, TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
const struct const struct
TALER_BlindedDenominationSignature *blind_sig, TALER_BlindedDenominationSignature *blind_sig,
const struct TALER_PlanchetSecretsP *ps, const union TALER_DenominationBlindingKeyP *bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
const struct TALER_CoinPubHash *c_hash, const struct TALER_CoinPubHash *c_hash,
const struct const struct TALER_ExchangeWithdrawValues *alg_values,
TALER_ExchangeWithdrawValues *alg_values,
struct TALER_FreshCoin *coin); struct TALER_FreshCoin *coin);

View File

@ -242,9 +242,15 @@ TALER_EXCHANGE_withdraw (
TALER_denom_pub_deep_copy (&wh->pk.key, TALER_denom_pub_deep_copy (&wh->pk.key,
&pk->key); &pk->key);
switch (pk->key.cipher) switch (pk->key.cipher)
{ {
case TALER_DENOMINATION_RSA: case TALER_DENOMINATION_RSA:
struct TALER_CoinSpendPrivateKeyP priv;
alg_values.cipher = TALER_DENOMINATION_RSA;
TALER_planchet_setup_coin_priv (ps, &wh->alg_values, &priv);
if (GNUNET_OK != if (GNUNET_OK !=
TALER_planchet_prepare (&pk->key, TALER_planchet_prepare (&pk->key,
&wh->alg_values, &wh->alg_values,

View File

@ -149,13 +149,19 @@ TALER_link_recover_transfer_secret (
void void
TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed, TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
uint32_t coin_num_salt, uint32_t coin_num_salt,
struct TALER_PlanchetSecretsP *ps) struct TALER_CoinSpendPrivateKeyP *coin_priv,
union TALER_DenominationBlindingKeyP *bks)
{ {
uint32_t be_salt = htonl (coin_num_salt); uint32_t be_salt = htonl (coin_num_salt);
struct
{
struct TALER_CoinSpendPrivateKeyP coin_priv;
union TALER_DenominationBlindingKeyP bks;
} out;
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
GNUNET_CRYPTO_kdf (ps, GNUNET_CRYPTO_kdf (&out,
sizeof (*ps), sizeof (out),
&be_salt, &be_salt,
sizeof (be_salt), sizeof (be_salt),
secret_seed, secret_seed,
@ -163,12 +169,14 @@ TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
"taler-coin-derivation", "taler-coin-derivation",
strlen ("taler-coin-derivation"), strlen ("taler-coin-derivation"),
NULL, 0)); NULL, 0));
*coin_priv = out.coin_priv;
*bks = out.bks;
} }
void void
cs_blinding_seed_derive (const struct cs_blinding_seed_derive (const struct
TALER_CoinSpendPrivateKeyP *coin_priv, TALER_PlanchetSecretsP *ps,
const struct GNUNET_CRYPTO_CsRPublic r_pub[2], const struct GNUNET_CRYPTO_CsRPublic r_pub[2],
struct GNUNET_CRYPTO_CsNonce *blind_seed) struct GNUNET_CRYPTO_CsNonce *blind_seed)
{ {
@ -179,8 +187,8 @@ cs_blinding_seed_derive (const struct
GCRY_MD_SHA256, GCRY_MD_SHA256,
"bseed", "bseed",
strlen ("bseed"), strlen ("bseed"),
coin_priv, ps,
sizeof(*coin_priv), sizeof(*ps),
r_pub, r_pub,
sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2, sizeof(struct GNUNET_CRYPTO_CsRPublic) * 2,
NULL, NULL,
@ -217,9 +225,11 @@ TALER_cs_withdraw_nonce_generate (struct TALER_CsNonce *nonce)
void void
TALER_planchet_blinding_secret_create (struct TALER_PlanchetSecretsP *ps, TALER_planchet_blinding_secret_create (const struct TALER_PlanchetSecretsP *ps,
const struct const struct
TALER_ExchangeWithdrawValues *alg_values) TALER_ExchangeWithdrawValues *alg_values,
union TALER_DenominationBlindingKeyP *bks)
{ {
switch (alg_values->cipher) switch (alg_values->cipher)
{ {
@ -227,16 +237,26 @@ TALER_planchet_blinding_secret_create (struct TALER_PlanchetSecretsP *ps,
GNUNET_break (0); GNUNET_break (0);
return; return;
case TALER_DENOMINATION_RSA: case TALER_DENOMINATION_RSA:
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, GNUNET_assert (GNUNET_YES ==
&ps->blinding_key.rsa_bks, GNUNET_CRYPTO_hkdf (&bks->rsa_bks,
sizeof (struct sizeof (struct
GNUNET_CRYPTO_RsaBlindingKeySecret)); GNUNET_CRYPTO_RsaBlindingKeySecret),
GCRY_MD_SHA512,
GCRY_MD_SHA256,
"bks",
strlen ("bks"),
ps,
sizeof(*ps),
&alg_values->details, /* Could be null on RSA case*/
sizeof(alg_values->details),
NULL,
0));
return; return;
case TALER_DENOMINATION_CS: case TALER_DENOMINATION_CS:
{ {
cs_blinding_seed_derive (&ps->coin_priv, cs_blinding_seed_derive (ps,
alg_values->details.cs_values.r_pub.r_pub, alg_values->details.cs_values.r_pub.r_pub,
&ps->blinding_key.nonce); &bks->nonce);
return; return;
} }
default: default:
@ -247,51 +267,43 @@ TALER_planchet_blinding_secret_create (struct TALER_PlanchetSecretsP *ps,
void void
TALER_planchet_setup_coin_priv ( TALER_planchet_setup_coin_priv (
const struct TALER_PlanchetSecretsP *ps,
const struct TALER_ExchangeWithdrawValues *alg_values,
struct TALER_CoinSpendPrivateKeyP *coin_priv) struct TALER_CoinSpendPrivateKeyP *coin_priv)
{ {
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, GNUNET_assert (GNUNET_YES ==
coin_priv, GNUNET_CRYPTO_hkdf (coin_priv,
sizeof (*coin_priv)); sizeof (*coin_priv),
// FIXME-jeff/dold: Clamping? GCRY_MD_SHA512,
} GCRY_MD_SHA256,
"coin",
strlen ("coin"),
void ps,
TALER_planchet_setup_random ( sizeof(*ps),
struct TALER_PlanchetSecretsP *ps, &alg_values->details, /* Could be null on RSA case*/
const struct TALER_ExchangeWithdrawValues *alg_values) sizeof(alg_values->details),
{ NULL,
TALER_planchet_setup_coin_priv (&ps->coin_priv); 0));
switch (alg_values->cipher) coin_priv->eddsa_priv.d[0] &= 248;
{ coin_priv->eddsa_priv.d[31] &= 127;
case TALER_DENOMINATION_INVALID: coin_priv->eddsa_priv.d[31] |= 64;
GNUNET_break (0);
return;
case TALER_DENOMINATION_RSA:
TALER_planchet_blinding_secret_create (ps,
alg_values);
return;
case TALER_DENOMINATION_CS:
// Will be set in a later stage for Clause Blind Schnorr Scheme
return;
default:
GNUNET_break (0);
}
} }
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk, TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_ExchangeWithdrawValues *alg_values,
struct TALER_PlanchetSecretsP *ps, const union TALER_DenominationBlindingKeyP *bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
struct TALER_CoinPubHash *c_hash, struct TALER_CoinPubHash *c_hash,
struct TALER_PlanchetDetail *pd) struct TALER_PlanchetDetail *pd
)
{ {
struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_CoinSpendPublicKeyP coin_pub;
GNUNET_assert (alg_values->cipher == dk->cipher); GNUNET_assert (alg_values->cipher == dk->cipher);
GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv, GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
&coin_pub.eddsa_pub); &coin_pub.eddsa_pub);
switch (dk->cipher) switch (dk->cipher)
@ -299,7 +311,7 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
case TALER_DENOMINATION_RSA: case TALER_DENOMINATION_RSA:
if (GNUNET_OK != if (GNUNET_OK !=
TALER_denom_blind (dk, TALER_denom_blind (dk,
&ps->blinding_key, bks,
NULL, /* FIXME-Oec */ NULL, /* FIXME-Oec */
&coin_pub, &coin_pub,
alg_values, alg_values,
@ -313,7 +325,7 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
case TALER_DENOMINATION_CS: case TALER_DENOMINATION_CS:
if (GNUNET_OK != if (GNUNET_OK !=
TALER_denom_blind (dk, TALER_denom_blind (dk,
&ps->blinding_key, bks,
NULL, /* FIXME-Oec */ NULL, /* FIXME-Oec */
&coin_pub, &coin_pub,
alg_values, alg_values,
@ -357,7 +369,8 @@ enum GNUNET_GenericReturnValue
TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk, TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
const struct const struct
TALER_BlindedDenominationSignature *blind_sig, TALER_BlindedDenominationSignature *blind_sig,
const struct TALER_PlanchetSecretsP *ps, const union TALER_DenominationBlindingKeyP *bks,
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
const struct TALER_CoinPubHash *c_hash, const struct TALER_CoinPubHash *c_hash,
const struct TALER_ExchangeWithdrawValues *alg_values, const struct TALER_ExchangeWithdrawValues *alg_values,
struct TALER_FreshCoin *coin) struct TALER_FreshCoin *coin)
@ -377,7 +390,7 @@ TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
if (GNUNET_OK != if (GNUNET_OK !=
TALER_denom_sig_unblind (&sig, TALER_denom_sig_unblind (&sig,
blind_sig, blind_sig,
&ps->blinding_key, bks,
dk)) dk))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -390,7 +403,7 @@ TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
struct GNUNET_CRYPTO_CsBlindingSecret bs[2]; struct GNUNET_CRYPTO_CsBlindingSecret bs[2];
struct TALER_DenominationCsPublicR r_pub_blind; struct TALER_DenominationCsPublicR r_pub_blind;
GNUNET_CRYPTO_cs_blinding_secrets_derive (&ps->blinding_key.nonce, bs); GNUNET_CRYPTO_cs_blinding_secrets_derive (&bks->nonce, bs);
GNUNET_CRYPTO_cs_calc_blinded_c (bs, GNUNET_CRYPTO_cs_calc_blinded_c (bs,
alg_values->details.cs_values.r_pub.r_pub, alg_values->details.cs_values.r_pub.r_pub,
@ -406,7 +419,7 @@ TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
if (GNUNET_OK != if (GNUNET_OK !=
TALER_denom_sig_unblind (&sig, TALER_denom_sig_unblind (&sig,
blind_sig, blind_sig,
&ps->blinding_key, bks,
dk)) dk))
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
@ -430,7 +443,7 @@ TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
} }
coin->sig = sig; coin->sig = sig;
coin->coin_priv = ps->coin_priv; coin->coin_priv = *coin_priv;
return GNUNET_OK; return GNUNET_OK;
} }