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 (7008B)


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