aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/age_restriction.c35
-rw-r--r--src/util/test_age_restriction.c64
-rw-r--r--src/util/wallet_signatures.c19
3 files changed, 96 insertions, 22 deletions
diff --git a/src/util/age_restriction.c b/src/util/age_restriction.c
index f0d99fe66..b667fa3a9 100644
--- a/src/util/age_restriction.c
+++ b/src/util/age_restriction.c
@@ -76,7 +76,7 @@ TALER_age_commitment_hash (
* defined by the given mask.
*/
uint8_t
-get_age_group (
+TALER_get_age_group (
const struct TALER_AgeMask *mask,
uint8_t age)
{
@@ -95,6 +95,27 @@ get_age_group (
}
+uint8_t
+TALER_get_lowest_age (
+ const struct TALER_AgeMask *mask,
+ uint8_t age)
+{
+ uint32_t m = mask->bits;
+ uint8_t group = TALER_get_age_group (mask, age);
+ uint8_t lowest = 0;
+
+ while (group > 0)
+ {
+ m = m >> 1;
+ if (m & 1)
+ group--;
+ lowest++;
+ }
+
+ return lowest;
+}
+
+
#ifdef AGE_RESTRICTION_WITH_ECDSA
/* @brief Helper function to generate a ECDSA private key
*
@@ -150,7 +171,7 @@ TALER_age_restriction_commit (
GNUNET_assert (mask->bits & 1); /* first bit must have been set */
num_pub = __builtin_popcount (mask->bits) - 1;
- num_priv = get_age_group (mask, age);
+ num_priv = TALER_get_age_group (mask, age);
GNUNET_assert (31 > num_priv);
GNUNET_assert (num_priv <= num_pub);
@@ -335,8 +356,8 @@ TALER_age_commitment_attest (
GNUNET_assert (NULL != attest);
GNUNET_assert (NULL != cp);
- group = get_age_group (&cp->commitment.mask,
- age);
+ group = TALER_get_age_group (&cp->commitment.mask,
+ age);
GNUNET_assert (group < 32);
@@ -386,8 +407,8 @@ TALER_age_commitment_verify (
GNUNET_assert (NULL != attest);
GNUNET_assert (NULL != comm);
- group = get_age_group (&comm->mask,
- age);
+ group = TALER_get_age_group (&comm->mask,
+ age);
GNUNET_assert (group < 32);
@@ -604,7 +625,7 @@ TALER_age_restriction_from_secret (
GNUNET_assert (mask->bits & 1); /* fist bit must have been set */
num_pub = __builtin_popcount (mask->bits) - 1;
- num_priv = get_age_group (mask, max_age);
+ num_priv = TALER_get_age_group (mask, max_age);
GNUNET_assert (31 > num_priv);
GNUNET_assert (num_priv <= num_pub);
diff --git a/src/util/test_age_restriction.c b/src/util/test_age_restriction.c
index 77717616f..e1979314e 100644
--- a/src/util/test_age_restriction.c
+++ b/src/util/test_age_restriction.c
@@ -21,11 +21,7 @@
*/
#include "platform.h"
#include "taler_util.h"
-
-extern uint8_t
-get_age_group (
- const struct TALER_AgeMask *mask,
- uint8_t age);
+#include <gnunet/gnunet_common.h>
/**
* Encodes the age mask into a string, like "8:10:12:14:16:18:21"
@@ -113,10 +109,10 @@ test_groups (void)
for (uint8_t i = 0; i < 32; i++)
{
- uint8_t r = get_age_group (&mask, i);
+ uint8_t r = TALER_get_age_group (&mask, i);
char *m = age_mask_to_string (&mask);
- printf ("get_age_group(%s, %2d) = %d vs %d (exp)\n",
+ printf ("TALER_get_age_group(%s, %2d) = %d vs %d (exp)\n",
m,
i,
r,
@@ -133,6 +129,52 @@ test_groups (void)
}
+enum GNUNET_GenericReturnValue
+test_lowest (void)
+{
+ struct TALER_AgeMask mask = {
+ .bits = 1 | 1 << 5 | 1 << 9 | 1 << 13 | 1 << 17 | 1 << 21
+ };
+
+ struct { uint8_t age; uint8_t expected; }
+ test [] = {
+ {.age = 1, .expected = 0 },
+ {.age = 2, .expected = 0 },
+ {.age = 3, .expected = 0 },
+ {.age = 4, .expected = 0 },
+ {.age = 5, .expected = 5 },
+ {.age = 6, .expected = 5 },
+ {.age = 7, .expected = 5 },
+ {.age = 8, .expected = 5 },
+ {.age = 9, .expected = 9 },
+ {.age = 10, .expected = 9 },
+ {.age = 11, .expected = 9 },
+ {.age = 12, .expected = 9 },
+ {.age = 13, .expected = 13 },
+ {.age = 14, .expected = 13 },
+ {.age = 15, .expected = 13 },
+ {.age = 16, .expected = 13 },
+ {.age = 17, .expected = 17 },
+ {.age = 18, .expected = 17 },
+ {.age = 19, .expected = 17 },
+ {.age = 20, .expected = 17 },
+ {.age = 21, .expected = 21 },
+ {.age = 22, .expected = 21 },
+ };
+
+ for (uint8_t n = 0; n < 21; n++)
+ {
+ uint8_t l = TALER_get_lowest_age (&mask, test[n].age);
+ printf ("lowest[%d] for age %d, expected lowest: %d, got: %d\n",
+ n, test[n].age, test[n].expected, l);
+ if (test[n].expected != l)
+ return GNUNET_SYSERR;
+ }
+
+ return GNUNET_OK;
+}
+
+
static struct TALER_AgeMask age_mask = {
.bits = 1 | 1 << 8 | 1 << 10 | 1 << 12 | 1 << 14 | 1 << 16 | 1 << 18 | 1 << 21
};
@@ -146,7 +188,7 @@ test_attestation (void)
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);
+ uint8_t age_group = TALER_get_age_group (&age_mask, age);
struct GNUNET_HashCode seed;
@@ -183,7 +225,7 @@ test_attestation (void)
{
for (uint8_t min = 0; min < 22; min++)
{
- uint8_t min_group = get_age_group (&age_mask, min);
+ uint8_t min_group = TALER_get_age_group (&age_mask, min);
ret = TALER_age_commitment_attest (&acp[i],
min,
@@ -259,10 +301,12 @@ main (int argc,
NULL);
if (GNUNET_OK != test_groups ())
return 1;
+ if (GNUNET_OK != test_lowest ())
+ return 2;
if (GNUNET_OK != test_attestation ())
{
GNUNET_break (0);
- return 2;
+ return 3;
}
return 0;
}
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 221865e73..0e5db2b51 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -634,9 +634,14 @@ struct TALER_AgeWithdrawRequestPS
struct TALER_AmountNBO amount_with_fee;
/**
+ * The mask that defines the age groups
+ */
+ struct TALER_AgeMask mask;
+
+ /**
* Maximum age group that the coins are going to be restricted to.
*/
- uint32_t max_age_group;
+ uint8_t max_age_group;
};
@@ -646,7 +651,8 @@ void
TALER_wallet_age_withdraw_sign (
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
const struct TALER_Amount *amount_with_fee,
- uint32_t max_age_group,
+ const struct TALER_AgeMask *mask,
+ uint8_t max_age,
const struct TALER_ReservePrivateKeyP *reserve_priv,
struct TALER_ReserveSignatureP *reserve_sig)
{
@@ -654,7 +660,8 @@ TALER_wallet_age_withdraw_sign (
.purpose.size = htonl (sizeof (req)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW),
.h_commitment = *h_commitment,
- .max_age_group = max_age_group
+ .mask = *mask,
+ .max_age_group = TALER_get_age_group (mask, max_age)
};
TALER_amount_hton (&req.amount_with_fee,
@@ -669,7 +676,8 @@ enum GNUNET_GenericReturnValue
TALER_wallet_age_withdraw_verify (
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
const struct TALER_Amount *amount_with_fee,
- uint32_t max_age_group,
+ const struct TALER_AgeMask *mask,
+ uint8_t max_age,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ReserveSignatureP *reserve_sig)
{
@@ -677,7 +685,8 @@ TALER_wallet_age_withdraw_verify (
.purpose.size = htonl (sizeof (awsrd)),
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW),
.h_commitment = *h_commitment,
- .max_age_group = max_age_group
+ .mask = *mask,
+ .max_age_group = TALER_get_age_group (mask, max_age)
};
TALER_amount_hton (&awsrd.amount_with_fee,