[age restriction] progress 18/n - attestation tested
- Unit-tests for commit, derive, attest and verify added, with multiple combinations of minimum age and commited age. - Fixed crypto implementation (eddsa -> ecdsa) - Using now standard functionality from GNUNET: GNUNET_CRYPTO_ecdsa_{private,public}_key_derive All tests pass (unit tests in util/ and 'make check' in testing).
This commit is contained in:
parent
476ae53808
commit
4c53d42e44
1
.gitignore
vendored
1
.gitignore
vendored
@ -88,6 +88,7 @@ src/wire-plugins/test_wire_plugin
|
|||||||
src/wire-plugins/test_wire_plugin_transactions_taler_bank
|
src/wire-plugins/test_wire_plugin_transactions_taler_bank
|
||||||
src/pq/test_pq
|
src/pq/test_pq
|
||||||
src/sq/test_sq
|
src/sq/test_sq
|
||||||
|
src/util/test_age_restriction
|
||||||
src/util/test_amount
|
src/util/test_amount
|
||||||
src/util/test_crypto
|
src/util/test_crypto
|
||||||
src/util/test_json
|
src/util/test_json
|
||||||
|
@ -620,14 +620,14 @@ resolve_refreshes_reveal_denominations (struct MHD_Connection *connection,
|
|||||||
oac = rctx->old_age_commitment;
|
oac = rctx->old_age_commitment;
|
||||||
oac->mask = TEH_age_mask;
|
oac->mask = TEH_age_mask;
|
||||||
oac->num = ng;
|
oac->num = ng;
|
||||||
oac->pub = GNUNET_new_array (ng, struct TALER_AgeCommitmentPublicKeyP);
|
oac->keys = GNUNET_new_array (ng, struct TALER_AgeCommitmentPublicKeyP);
|
||||||
|
|
||||||
/* Extract old age commitment */
|
/* Extract old age commitment */
|
||||||
for (unsigned int i = 0; i< ng; i++)
|
for (unsigned int i = 0; i< ng; i++)
|
||||||
{
|
{
|
||||||
struct GNUNET_JSON_Specification ac_spec[] = {
|
struct GNUNET_JSON_Specification ac_spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto (NULL,
|
GNUNET_JSON_spec_fixed_auto (NULL,
|
||||||
&oac->pub[i]),
|
&oac->keys[i]),
|
||||||
GNUNET_JSON_spec_end ()
|
GNUNET_JSON_spec_end ()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -339,9 +339,9 @@ struct TALER_CoinSpendPrivateKeyP
|
|||||||
struct TALER_AgeCommitmentPrivateKeyP
|
struct TALER_AgeCommitmentPrivateKeyP
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Taler uses EdDSA for coins when signing age verification attestation.
|
* Taler uses EcDSA for coins when signing age verification attestation.
|
||||||
*/
|
*/
|
||||||
struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
|
struct GNUNET_CRYPTO_EcdsaPrivateKey priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -351,9 +351,9 @@ struct TALER_AgeCommitmentPrivateKeyP
|
|||||||
struct TALER_AgeCommitmentPublicKeyP
|
struct TALER_AgeCommitmentPublicKeyP
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Taler uses EdDSA for coins when signing age verification attestation.
|
* Taler uses EcDSA for coins when signing age verification attestation.
|
||||||
*/
|
*/
|
||||||
struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub;
|
struct GNUNET_CRYPTO_EcdsaPublicKey pub;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -869,7 +869,7 @@ struct TALER_AgeCommitmentHash
|
|||||||
*/
|
*/
|
||||||
struct TALER_AgeAttestation
|
struct TALER_AgeAttestation
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
|
struct GNUNET_CRYPTO_EcdsaSignature signature;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct TALER_AgeCommitmentHash TALER_ZeroAgeCommitmentHash;
|
extern const struct TALER_AgeCommitmentHash TALER_ZeroAgeCommitmentHash;
|
||||||
@ -3326,7 +3326,7 @@ struct TALER_AgeCommitment
|
|||||||
*
|
*
|
||||||
* The list has been allocated via GNUNET_malloc.
|
* The list has been allocated via GNUNET_malloc.
|
||||||
*/
|
*/
|
||||||
struct TALER_AgeCommitmentPublicKeyP *pub;
|
struct TALER_AgeCommitmentPublicKeyP *keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TALER_AgeProof
|
struct TALER_AgeProof
|
||||||
@ -3347,7 +3347,7 @@ struct TALER_AgeProof
|
|||||||
*
|
*
|
||||||
* The list has been allocated via GNUNET_malloc.
|
* The list has been allocated via GNUNET_malloc.
|
||||||
*/
|
*/
|
||||||
struct TALER_AgeCommitmentPrivateKeyP *priv;
|
struct TALER_AgeCommitmentPrivateKeyP *keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TALER_AgeCommitmentProof
|
struct TALER_AgeCommitmentProof
|
||||||
|
@ -438,10 +438,11 @@ TALER_EXCHANGE_refreshes_reveal (
|
|||||||
for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++)
|
for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++)
|
||||||
{
|
{
|
||||||
GNUNET_assert (0 ==
|
GNUNET_assert (0 ==
|
||||||
json_array_append_new (old_age_commitment,
|
json_array_append_new (
|
||||||
GNUNET_JSON_from_data_auto (
|
old_age_commitment,
|
||||||
&rd->melt_age_commitment_proof->
|
GNUNET_JSON_from_data_auto (
|
||||||
commitment.pub[i])));
|
&rd->melt_age_commitment_proof->
|
||||||
|
commitment.keys[i])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@ libtalerutil_la_LDFLAGS = \
|
|||||||
AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
|
AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
|
||||||
|
|
||||||
check_PROGRAMS = \
|
check_PROGRAMS = \
|
||||||
|
test_age_restriction \
|
||||||
test_amount \
|
test_amount \
|
||||||
test_crypto \
|
test_crypto \
|
||||||
test_helper_eddsa \
|
test_helper_eddsa \
|
||||||
@ -127,6 +128,11 @@ check_PROGRAMS = \
|
|||||||
TESTS = \
|
TESTS = \
|
||||||
$(check_PROGRAMS)
|
$(check_PROGRAMS)
|
||||||
|
|
||||||
|
test_age_restriction_SOURCES = \
|
||||||
|
test_age_restriction.c
|
||||||
|
test_age_restriction_LDADD = \
|
||||||
|
-lgnunetutil \
|
||||||
|
libtalerutil.la
|
||||||
|
|
||||||
test_amount_SOURCES = \
|
test_amount_SOURCES = \
|
||||||
test_amount.c
|
test_amount.c
|
||||||
|
@ -46,9 +46,9 @@ TALER_age_commitment_hash (
|
|||||||
for (size_t i = 0; i < commitment->num; i++)
|
for (size_t i = 0; i < commitment->num; i++)
|
||||||
{
|
{
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
&commitment->pub[i],
|
&commitment->keys[i],
|
||||||
sizeof(struct
|
sizeof(struct
|
||||||
GNUNET_CRYPTO_EddsaPublicKey));
|
GNUNET_CRYPTO_EcdsaPublicKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
GNUNET_CRYPTO_hash_context_finish (hash_context,
|
||||||
@ -62,7 +62,7 @@ TALER_age_commitment_hash (
|
|||||||
/* To a given age value between 0 and 31, returns the index of the age group
|
/* To a given age value between 0 and 31, returns the index of the age group
|
||||||
* defined by the given mask.
|
* defined by the given mask.
|
||||||
*/
|
*/
|
||||||
static uint8_t
|
uint8_t
|
||||||
get_age_group (
|
get_age_group (
|
||||||
const struct TALER_AgeMask *mask,
|
const struct TALER_AgeMask *mask,
|
||||||
uint8_t age)
|
uint8_t age)
|
||||||
@ -102,14 +102,14 @@ TALER_age_restriction_commit (
|
|||||||
new->commitment.mask.bits = mask->bits;
|
new->commitment.mask.bits = mask->bits;
|
||||||
new->commitment.num = num_pub;
|
new->commitment.num = num_pub;
|
||||||
new->proof.num = num_priv;
|
new->proof.num = num_priv;
|
||||||
new->proof.priv = NULL;
|
new->proof.keys = NULL;
|
||||||
|
|
||||||
new->commitment.pub = GNUNET_new_array (
|
new->commitment.keys = GNUNET_new_array (
|
||||||
num_pub,
|
num_pub,
|
||||||
struct TALER_AgeCommitmentPublicKeyP);
|
struct TALER_AgeCommitmentPublicKeyP);
|
||||||
|
|
||||||
if (0 < num_priv)
|
if (0 < num_priv)
|
||||||
new->proof.priv = GNUNET_new_array (
|
new->proof.keys = GNUNET_new_array (
|
||||||
num_priv,
|
num_priv,
|
||||||
struct TALER_AgeCommitmentPrivateKeyP);
|
struct TALER_AgeCommitmentPrivateKeyP);
|
||||||
|
|
||||||
@ -119,35 +119,40 @@ TALER_age_restriction_commit (
|
|||||||
* elliptic curve, so we can't simply fill the struct with random values. */
|
* elliptic curve, so we can't simply fill the struct with random values. */
|
||||||
for (i = 0; i < num_pub; i++)
|
for (i = 0; i < num_pub; i++)
|
||||||
{
|
{
|
||||||
uint64_t saltBE = htonl (salt + i);
|
uint64_t salti = salt + i;
|
||||||
struct TALER_AgeCommitmentPrivateKeyP key = {0};
|
struct TALER_AgeCommitmentPrivateKeyP key = {0};
|
||||||
struct TALER_AgeCommitmentPrivateKeyP *priv = &key;
|
struct TALER_AgeCommitmentPrivateKeyP *pkey = &key;
|
||||||
|
|
||||||
|
|
||||||
/* Only save the private keys for age groups less than num_priv */
|
/* Only save the private keys for age groups less than num_priv */
|
||||||
if (i < num_priv)
|
if (i < num_priv)
|
||||||
priv = &new->proof.priv[i];
|
pkey = &new->proof.keys[i];
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_kdf (priv,
|
GNUNET_CRYPTO_kdf (pkey,
|
||||||
sizeof (*priv),
|
sizeof (*pkey),
|
||||||
&saltBE,
|
&salti,
|
||||||
sizeof (saltBE),
|
sizeof (salti),
|
||||||
"taler-age-commitment-derivation",
|
"age commitment",
|
||||||
strlen (
|
strlen ("age derivation"),
|
||||||
"taler-age-commitment-derivation"),
|
|
||||||
NULL, 0))
|
NULL, 0))
|
||||||
goto FAIL;
|
goto FAIL;
|
||||||
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&priv->eddsa_priv,
|
/* See GNUNET_CRYPTO_ecdsa_key_create */
|
||||||
&new->commitment.pub[i].eddsa_pub);
|
pkey->priv.d[0] &= 248;
|
||||||
|
pkey->priv.d[31] &= 127;
|
||||||
|
pkey->priv.d[31] |= 64;
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_ecdsa_key_get_public (&pkey->priv,
|
||||||
|
&new->commitment.keys[i].pub);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
|
|
||||||
FAIL:
|
FAIL:
|
||||||
GNUNET_free (new->commitment.pub);
|
GNUNET_free (new->commitment.keys);
|
||||||
if (NULL != new->proof.priv)
|
if (NULL != new->proof.keys)
|
||||||
GNUNET_free (new->proof.priv);
|
GNUNET_free (new->proof.keys);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,128 +163,52 @@ TALER_age_commitment_derive (
|
|||||||
const uint64_t salt,
|
const uint64_t salt,
|
||||||
struct TALER_AgeCommitmentProof *new)
|
struct TALER_AgeCommitmentProof *new)
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_EccScalar scalar;
|
char label[sizeof(uint64_t) + 1] = {0};
|
||||||
uint64_t saltBT = htonl (salt);
|
|
||||||
int64_t factor;
|
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
GNUNET_CRYPTO_kdf (
|
|
||||||
&factor,
|
|
||||||
sizeof (factor),
|
|
||||||
&saltBT,
|
|
||||||
sizeof (saltBT),
|
|
||||||
"taler-age-restriction-derivation",
|
|
||||||
strlen ("taler-age-restriction-derivation"),
|
|
||||||
NULL, 0));
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_ecc_scalar_from_int (factor, &scalar);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* age commitment consists of GNUNET_CRYPTO_Eddsa{Private,Public}Key
|
|
||||||
*
|
|
||||||
* GNUNET_CRYPTO_EddsaPrivateKey is a
|
|
||||||
* unsigned char d[256 / 8];
|
|
||||||
*
|
|
||||||
* GNUNET_CRYPTO_EddsaPublicKey is a
|
|
||||||
* unsigned char q_y[256 / 8];
|
|
||||||
*
|
|
||||||
* We want to multiply, both, the Private Key by an integer factor and the
|
|
||||||
* public key (point on curve) with the equivalent scalar.
|
|
||||||
*
|
|
||||||
* From the salt we will derive
|
|
||||||
* 1. a scalar to multiply the public keys with
|
|
||||||
* 2. a factor to multiply the private key with
|
|
||||||
*
|
|
||||||
* Invariants:
|
|
||||||
* point*scalar == public(private*factor)
|
|
||||||
*
|
|
||||||
* A point on a curve is GNUNET_CRYPTO_EccPoint which is
|
|
||||||
* unsigned char v[256 / 8];
|
|
||||||
*
|
|
||||||
* A ECC scalar for use in point multiplications is a
|
|
||||||
* GNUNET_CRYPTO_EccScalar which is a
|
|
||||||
* unsigned char v[256 / 8];
|
|
||||||
* */
|
|
||||||
|
|
||||||
GNUNET_assert (NULL != new);
|
GNUNET_assert (NULL != new);
|
||||||
GNUNET_assert (orig->commitment.num== __builtin_popcount (
|
GNUNET_assert (orig->proof.num <=
|
||||||
orig->commitment.mask.bits) - 1);
|
orig->commitment.num);
|
||||||
GNUNET_assert (orig->proof.num <= orig->commitment.num);
|
GNUNET_assert (orig->commitment.num ==
|
||||||
|
__builtin_popcount (orig->commitment.mask.bits) - 1);
|
||||||
|
|
||||||
new->commitment.mask = orig->commitment.mask;
|
new->commitment.mask = orig->commitment.mask;
|
||||||
new->commitment.num = orig->commitment.num;
|
new->commitment.num = orig->commitment.num;
|
||||||
new->proof.num = orig->proof.num;
|
new->commitment.keys = GNUNET_new_array (
|
||||||
new->commitment.pub = GNUNET_new_array (
|
|
||||||
new->commitment.num,
|
new->commitment.num,
|
||||||
struct TALER_AgeCommitmentPublicKeyP);
|
struct TALER_AgeCommitmentPublicKeyP);
|
||||||
new->proof.priv = GNUNET_new_array (
|
|
||||||
new->proof.num,
|
|
||||||
struct TALER_AgeCommitmentPrivateKeyP);
|
|
||||||
|
|
||||||
/* scalar multiply the public keys on the curve */
|
new->proof.num = orig->proof.num;
|
||||||
|
new->proof.keys = NULL;
|
||||||
|
if (0 != new->proof.num)
|
||||||
|
new->proof.keys = GNUNET_new_array (
|
||||||
|
new->proof.num,
|
||||||
|
struct TALER_AgeCommitmentPrivateKeyP);
|
||||||
|
|
||||||
|
memcpy (label, &salt, sizeof(salt));
|
||||||
|
|
||||||
|
/* 1. Derive the public keys */
|
||||||
for (size_t i = 0; i < orig->commitment.num; i++)
|
for (size_t i = 0; i < orig->commitment.num; i++)
|
||||||
{
|
{
|
||||||
/* We shift all keys by the same scalar */
|
GNUNET_CRYPTO_ecdsa_public_key_derive (
|
||||||
struct GNUNET_CRYPTO_EccPoint *p = (struct
|
&orig->commitment.keys[i].pub,
|
||||||
GNUNET_CRYPTO_EccPoint *) &orig->
|
label,
|
||||||
commitment.pub[i];
|
"age commitment derive",
|
||||||
struct GNUNET_CRYPTO_EccPoint *np = (struct
|
&new->commitment.keys[i].pub);
|
||||||
GNUNET_CRYPTO_EccPoint *) &new->
|
|
||||||
commitment.pub[i];
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
GNUNET_CRYPTO_ecc_pmul_mpi (
|
|
||||||
p,
|
|
||||||
&scalar,
|
|
||||||
np))
|
|
||||||
goto FAIL;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* multiply the private keys */
|
/* 2. Derive the private keys */
|
||||||
/* we borough ideas from GNUNET_CRYPTO_ecdsa_private_key_derive */
|
for (size_t i = 0; i < orig->proof.num; i++)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < orig->proof.num; i++)
|
struct GNUNET_CRYPTO_EcdsaPrivateKey *priv;
|
||||||
{
|
priv = GNUNET_CRYPTO_ecdsa_private_key_derive (
|
||||||
uint8_t dc[32];
|
&orig->proof.keys[i].priv,
|
||||||
gcry_mpi_t f, x, d, n;
|
label,
|
||||||
gcry_ctx_t ctx;
|
"age commitment derive");
|
||||||
|
new->proof.keys[i].priv = *priv;
|
||||||
GNUNET_assert (0==gcry_mpi_ec_new (&ctx, NULL, "Ed25519"));
|
GNUNET_free (priv);
|
||||||
n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_mpi_scan_unsigned (&f, (unsigned char*) &factor,
|
|
||||||
sizeof(factor));
|
|
||||||
|
|
||||||
for (size_t j = 0; j < 32; 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);
|
|
||||||
gcry_mpi_mulm (d, f, x, n);
|
|
||||||
GNUNET_CRYPTO_mpi_print_unsigned (dc, sizeof(dc), d);
|
|
||||||
|
|
||||||
for (size_t j = 0; j <32; j++)
|
|
||||||
new->proof.priv[i].eddsa_priv.d[j] = dc[31 - 1];
|
|
||||||
|
|
||||||
sodium_memzero (dc, sizeof(dc));
|
|
||||||
gcry_mpi_release (d);
|
|
||||||
gcry_mpi_release (x);
|
|
||||||
gcry_mpi_release (n);
|
|
||||||
gcry_mpi_release (f);
|
|
||||||
gcry_ctx_release (ctx);
|
|
||||||
|
|
||||||
/* TODO: add test to make sure that the calculated private key generate
|
|
||||||
* the same public keys */
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
|
|
||||||
FAIL:
|
|
||||||
GNUNET_free (new->commitment.pub);
|
|
||||||
GNUNET_free (new->proof.priv);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -309,7 +238,7 @@ TALER_age_commitment_attest (
|
|||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group >= cp->proof.num)
|
if (group > cp->proof.num)
|
||||||
return GNUNET_NO;
|
return GNUNET_NO;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -320,9 +249,9 @@ TALER_age_commitment_attest (
|
|||||||
.age = age
|
.age = age
|
||||||
};
|
};
|
||||||
|
|
||||||
GNUNET_CRYPTO_eddsa_sign (&cp->proof.priv[group - 1].eddsa_priv,
|
GNUNET_CRYPTO_ecdsa_sign (&cp->proof.keys[group - 1].priv,
|
||||||
&at,
|
&at,
|
||||||
&attest->eddsa_signature);
|
&attest->signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
@ -349,7 +278,7 @@ TALER_age_commitment_verify (
|
|||||||
if (0 == group)
|
if (0 == group)
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
|
|
||||||
if (group >= comm->num)
|
if (group > comm->num)
|
||||||
return GNUNET_NO;
|
return GNUNET_NO;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -361,10 +290,10 @@ TALER_age_commitment_verify (
|
|||||||
};
|
};
|
||||||
|
|
||||||
return
|
return
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_AGE_ATTESTATION,
|
GNUNET_CRYPTO_ecdsa_verify (TALER_SIGNATURE_WALLET_AGE_ATTESTATION,
|
||||||
&at,
|
&at,
|
||||||
&attest->eddsa_signature,
|
&attest->signature,
|
||||||
&comm->pub[group - 1].eddsa_pub);
|
&comm->keys[group - 1].pub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,10 +305,10 @@ TALER_age_commitment_free (
|
|||||||
if (NULL == commitment)
|
if (NULL == commitment)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (NULL != commitment->pub)
|
if (NULL != commitment->keys)
|
||||||
{
|
{
|
||||||
GNUNET_free (commitment->pub);
|
GNUNET_free (commitment->keys);
|
||||||
commitment->pub = NULL;
|
commitment->keys = NULL;
|
||||||
}
|
}
|
||||||
GNUNET_free (commitment);
|
GNUNET_free (commitment);
|
||||||
}
|
}
|
||||||
@ -389,14 +318,14 @@ void
|
|||||||
TALER_age_proof_free (
|
TALER_age_proof_free (
|
||||||
struct TALER_AgeProof *proof)
|
struct TALER_AgeProof *proof)
|
||||||
{
|
{
|
||||||
if (NULL != proof->priv)
|
if (NULL != proof->keys)
|
||||||
{
|
{
|
||||||
GNUNET_CRYPTO_zero_keys (
|
GNUNET_CRYPTO_zero_keys (
|
||||||
proof->priv,
|
proof->keys,
|
||||||
sizeof(*proof->priv) * proof->num);
|
sizeof(*proof->keys) * proof->num);
|
||||||
|
|
||||||
GNUNET_free (proof->priv);
|
GNUNET_free (proof->keys);
|
||||||
proof->priv = NULL;
|
proof->keys = NULL;
|
||||||
}
|
}
|
||||||
GNUNET_free (proof);
|
GNUNET_free (proof);
|
||||||
}
|
}
|
||||||
@ -406,19 +335,19 @@ void
|
|||||||
TALER_age_commitment_proof_free (
|
TALER_age_commitment_proof_free (
|
||||||
struct TALER_AgeCommitmentProof *cp)
|
struct TALER_AgeCommitmentProof *cp)
|
||||||
{
|
{
|
||||||
if (NULL != cp->proof.priv)
|
if (NULL != cp->proof.keys)
|
||||||
{
|
{
|
||||||
GNUNET_CRYPTO_zero_keys (
|
GNUNET_CRYPTO_zero_keys (
|
||||||
cp->proof.priv,
|
cp->proof.keys,
|
||||||
sizeof(*cp->proof.priv) * cp->proof.num);
|
sizeof(*cp->proof.keys) * cp->proof.num);
|
||||||
|
|
||||||
GNUNET_free (cp->proof.priv);
|
GNUNET_free (cp->proof.keys);
|
||||||
cp->proof.priv = NULL;
|
cp->proof.keys = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != cp->commitment.pub)
|
if (NULL != cp->commitment.keys)
|
||||||
{
|
{
|
||||||
GNUNET_free (cp->commitment.pub);
|
GNUNET_free (cp->commitment.keys);
|
||||||
cp->commitment.pub = NULL;
|
cp->commitment.keys = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
135
src/util/test_age_restriction.c
Normal file
135
src/util/test_age_restriction.c
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
(C) 2022 Taler Systems SA
|
||||||
|
|
||||||
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file util/test_age_restriction.c
|
||||||
|
* @brief Tests for age restriction specific logic
|
||||||
|
* @author Özgür Kesim
|
||||||
|
*/
|
||||||
|
#include "platform.h"
|
||||||
|
#include "taler_util.h"
|
||||||
|
#include "taler_crypto_lib.h"
|
||||||
|
|
||||||
|
static struct TALER_AgeMask age_mask = {
|
||||||
|
.bits = 1 | 1 << 8 | 1 << 10 | 1 << 12 | 1 << 14 | 1 << 16 | 1 << 18 | 1 << 21
|
||||||
|
};
|
||||||
|
|
||||||
|
extern uint8_t
|
||||||
|
get_age_group (
|
||||||
|
const struct TALER_AgeMask *mask,
|
||||||
|
uint8_t age);
|
||||||
|
|
||||||
|
enum GNUNET_GenericReturnValue
|
||||||
|
test_attestation (void)
|
||||||
|
{
|
||||||
|
uint8_t age;
|
||||||
|
for (age = 0; age < 35; age++)
|
||||||
|
{
|
||||||
|
enum GNUNET_GenericReturnValue ret;
|
||||||
|
struct TALER_AgeCommitmentProof acp[3] = {0};
|
||||||
|
struct TALER_AgeAttestation at = {0};
|
||||||
|
uint8_t age_group = get_age_group (&age_mask, age);
|
||||||
|
uint64_t salt = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||||
|
UINT64_MAX);
|
||||||
|
|
||||||
|
ret = TALER_age_restriction_commit (&age_mask,
|
||||||
|
age,
|
||||||
|
salt,
|
||||||
|
&acp[0]);
|
||||||
|
|
||||||
|
printf (
|
||||||
|
"commit(age:%d) == %d; proof.num: %ld; age_group: %d\n",
|
||||||
|
age,
|
||||||
|
ret,
|
||||||
|
acp[0].proof.num,
|
||||||
|
age_group);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i<2; i++)
|
||||||
|
{
|
||||||
|
/* Also derive another commitment right away */
|
||||||
|
salt = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||||
|
UINT64_MAX);
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_age_commitment_derive (&acp[i],
|
||||||
|
salt,
|
||||||
|
&acp[i + 1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for (uint8_t min = 0; min < 22; min++)
|
||||||
|
{
|
||||||
|
uint8_t min_group = get_age_group (&age_mask, min);
|
||||||
|
|
||||||
|
ret = TALER_age_commitment_attest (&acp[i],
|
||||||
|
min,
|
||||||
|
&at);
|
||||||
|
|
||||||
|
printf (
|
||||||
|
"[%s]: attest(min:%d, age:%d) == %d; age_group: %d, min_group: %d\n",
|
||||||
|
i == 0 ? "commit" : "derive",
|
||||||
|
min,
|
||||||
|
age,
|
||||||
|
ret,
|
||||||
|
age_group,
|
||||||
|
min_group);
|
||||||
|
|
||||||
|
if (min_group <= age_group &&
|
||||||
|
GNUNET_OK != ret)
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
|
||||||
|
if (min_group > age_group &&
|
||||||
|
GNUNET_NO != ret)
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
|
||||||
|
if (min_group > age_group)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = TALER_age_commitment_verify (&acp[i].commitment,
|
||||||
|
min,
|
||||||
|
&at);
|
||||||
|
|
||||||
|
printf (
|
||||||
|
"[%s]: verify(min:%d, age:%d) == %d; age_group:%d, min_group: %d\n",
|
||||||
|
i == 0 ? "commit" : "derive",
|
||||||
|
min,
|
||||||
|
age,
|
||||||
|
ret,
|
||||||
|
age_group,
|
||||||
|
min_group);
|
||||||
|
|
||||||
|
if (GNUNET_OK != ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
const char *const argv[])
|
||||||
|
{
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
if (GNUNET_OK != test_attestation ())
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* end of test_age_restriction.c */
|
Loading…
Reference in New Issue
Block a user