exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

tv_age_restriction.c (6858B)


      1 /**
      2  * @file util/tv_age_restriction.c
      3  * @brief Generate test vectors for age restriction
      4  * @author Özgür Kesim
      5  *
      6  * compile in exchange/src/util with
      7  *
      8  * gcc tv_age_restriction.c \
      9  *    -lgnunetutil -lgnunetjson -lsodium -ljansson \
     10  *    -L/usr/lib/x86_64-linux-gnu -lmicrohttpd -ltalerutil \
     11  *    -I../include \
     12  *    -o tv_age_restriction
     13  *
     14  */
     15 #include <gnunet/gnunet_json_lib.h>
     16 #include <gnunet/gnunet_util_lib.h>
     17 #include <jansson.h>
     18 #include <taler/taler_util.h>
     19 #include <taler/taler_crypto_lib.h>
     20 
     21 static struct TALER_AgeMask age_masks[] = {
     22   { .bits = 1
     23             | 1 << 8 | 1 << 14 | 1 << 18 },
     24   { .bits = 1
     25             | 1 << 8 | 1 << 10 | 1 << 12
     26             | 1 << 14 | 1 << 16 | 1 << 18 | 1 << 21 },
     27 };
     28 
     29 extern uint8_t
     30 get_age_group (
     31   const struct TALER_AgeMask *mask,
     32   uint8_t age);
     33 
     34 /**
     35  * Encodes the age mask into a string, like "8:10:12:14:16:18:21"
     36  */
     37 char *
     38 age_mask_to_string (
     39   const struct TALER_AgeMask *mask)
     40 {
     41   uint32_t bits = mask->bits;
     42   unsigned int n = 0;
     43   char *buf = GNUNET_malloc (32 * 3); // max characters possible
     44   char *pos = buf;
     45 
     46   if (NULL == buf)
     47   {
     48     return buf;
     49   }
     50 
     51   while (bits != 0)
     52   {
     53     bits >>= 1;
     54     n++;
     55     if (0 == (bits & 1))
     56     {
     57       continue;
     58     }
     59 
     60     if (n > 9)
     61     {
     62       *(pos++) = '0' + n / 10;
     63     }
     64     *(pos++) = '0' + n % 10;
     65 
     66     if (0 != (bits >> 1))
     67     {
     68       *(pos++) = ':';
     69     }
     70   }
     71   return buf;
     72 }
     73 
     74 
     75 static json_t *
     76 cp_to_j (
     77   const struct GNUNET_HashCode *seed,
     78   struct TALER_AgeCommitmentProof *acp,
     79   uint8_t seq)
     80 {
     81   json_t *j_commitment;
     82   json_t *j_proof;
     83   json_t *j_pubs;
     84   json_t *j_privs;
     85   struct TALER_AgeCommitmentHashP hac = {0};
     86   char buf[256] = {0};
     87 
     88   TALER_age_commitment_hash (&acp->commitment, &hac);
     89 
     90   j_pubs = json_array ();
     91   GNUNET_assert (NULL != j_pubs);
     92   for (unsigned int i = 0; i < acp->commitment.num; i++)
     93   {
     94     json_t *j_pub = GNUNET_JSON_PACK (
     95       GNUNET_JSON_pack_data_auto (NULL,
     96                                   &acp->commitment.keys[i]));
     97     json_array_append_new (j_pubs, j_pub);
     98   }
     99 
    100   j_commitment = GNUNET_JSON_PACK (
    101     GNUNET_JSON_pack_uint64 ("num", acp->commitment.num),
    102     GNUNET_JSON_pack_array_steal ("edx25519_pubs", j_pubs),
    103     GNUNET_JSON_pack_data_auto ("h_age_commitment", &hac));
    104 
    105 
    106   j_privs = json_array ();
    107   GNUNET_assert (NULL != j_privs);
    108   for (unsigned int i = 0; i < acp->proof.num; i++)
    109   {
    110     json_t *j_priv = GNUNET_JSON_PACK (
    111       GNUNET_JSON_pack_data_auto (NULL,
    112                                   &acp->proof.keys[i]));
    113     json_array_append_new (j_privs, j_priv);
    114   }
    115   j_proof = GNUNET_JSON_PACK (
    116     GNUNET_JSON_pack_uint64 ("num", acp->proof.num),
    117     GNUNET_JSON_pack_array_steal ("edx25519_privs", j_privs));
    118 
    119   if (0 == seq)
    120   {
    121     strcpy (buf, "commit()");
    122   }
    123   else
    124   {
    125     sprintf (buf,
    126              "derive_from(%d)",
    127              seq);
    128   }
    129 
    130   return GNUNET_JSON_PACK (
    131     GNUNET_JSON_pack_string ("generated_by", buf),
    132     GNUNET_JSON_pack_data_auto ("seed", seed),
    133     GNUNET_JSON_pack_object_steal ("proof", j_proof),
    134     GNUNET_JSON_pack_object_steal ("commitment", j_commitment));
    135 
    136 };
    137 
    138 static json_t *
    139 generate (
    140   struct TALER_AgeMask *mask)
    141 {
    142   uint8_t age;
    143   json_t *j_commitproofs;
    144   j_commitproofs = json_array ();
    145 
    146   for (age = 0; age < 24; age += 2)
    147   {
    148     json_t *j_top = json_object ();
    149     json_t *j_seq = json_array ();
    150     enum GNUNET_GenericReturnValue ret;
    151     struct TALER_AgeCommitmentProof acp[3] = {0};
    152     uint8_t age_group = get_age_group (mask, age);
    153     struct GNUNET_HashCode seed;
    154 
    155     GNUNET_CRYPTO_random_block (&seed,
    156                                 sizeof(seed));
    157 
    158     json_object_set (j_top,
    159                      "committed_age",
    160                      json_integer (age));
    161 
    162     ret = TALER_age_restriction_commit (mask,
    163                                         age,
    164                                         &seed,
    165                                         &acp[0]);
    166 
    167     GNUNET_assert (GNUNET_OK == ret);
    168 
    169     /* Also derive two more commitments right away */
    170     for (uint8_t i = 0; i<2; i++)
    171     {
    172       struct GNUNET_HashCode salt;
    173       GNUNET_CRYPTO_random_block (&salt,
    174                                   sizeof (salt));
    175       GNUNET_assert (GNUNET_OK ==
    176                      TALER_age_commitment_derive (&acp[i],
    177                                                   &salt,
    178                                                   &acp[i + 1]));
    179     }
    180 
    181     for (uint8_t i = 0; i < 3; i++)
    182     {
    183       json_t *j_cp = cp_to_j (&seed, &acp[i], i);
    184       json_t *j_attestations = json_array ();
    185 
    186       for (uint8_t min = 0; min < 22; min++)
    187       {
    188         json_t *j_attest = json_object ();
    189         json_t *j_reason;
    190         uint8_t min_group = get_age_group (mask, min);
    191         struct TALER_AgeAttestationP at = {0};
    192 
    193         json_object_set (j_attest,
    194                          "required_minimum_age",
    195                          json_integer (min));
    196         json_object_set (j_attest,
    197                          "calculated_age_group",
    198                          json_integer (min_group));
    199 
    200         ret = TALER_age_commitment_attest (&acp[i],
    201                                            min,
    202                                            &at);
    203 
    204 
    205         if (0 == min_group)
    206           j_reason =  json_string (
    207             "not required: age group is 0");
    208         else if (min_group > age_group)
    209           j_reason = json_string (
    210             "not applicable: committed age too small");
    211         else
    212           j_reason = GNUNET_JSON_PACK (
    213             GNUNET_JSON_pack_data_auto (NULL, &at));
    214 
    215         json_object_set (j_attest,
    216                          "attestation",
    217                          j_reason);
    218 
    219         json_array_append_new (j_attestations,
    220                                j_attest);
    221 
    222       }
    223 
    224       json_object_set (j_cp, "attestations", j_attestations);
    225       json_array_append (j_seq,  j_cp);
    226 
    227       TALER_age_commitment_proof_free (&acp[i]);
    228     }
    229 
    230     json_object_set (j_top, "commitment_proof_attestation_seq", j_seq);
    231     json_array_append_new (j_commitproofs, j_top);
    232   }
    233 
    234   return j_commitproofs;
    235 }
    236 
    237 
    238 int
    239 main (int argc,
    240       const char *const argv[])
    241 {
    242   (void) argc;
    243   (void) argv;
    244   json_t *j_data = json_array ();
    245   for (unsigned int i = 0; i < 2; i++)
    246   {
    247     struct TALER_AgeMask mask = age_masks[i];
    248     json_t *j_test = json_object ();
    249     json_object_set (j_test,
    250                      "age_groups",
    251                      json_string (age_mask_to_string (&mask)));
    252     json_object_set (j_test,
    253                      "age_mask",
    254                      json_integer (mask.bits));
    255     json_object_set (j_test,
    256                      "test_data",
    257                      generate (&mask));
    258     json_array_append_new (j_data, j_test);
    259   }
    260   printf ("%s\n", json_dumps (j_data, JSON_INDENT (2)
    261                               | JSON_COMPACT));
    262 
    263   json_decref (j_data);
    264   return 0;
    265 }
    266 
    267 
    268 /* end of tv_age_restriction.c */