LCOV - code coverage report
Current view: top level - src - bbs_util.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 78.6 % 295 232
Test Date: 2025-06-13 08:12:24 Functions: 100.0 % 24 24

            Line data    Source code
       1              : #include "bbs.h"
       2              : #include "bbs_util.h"
       3              : 
       4              : inline void
       5          220 : bn_write_bbs (
       6              :         uint8_t     bin[BBS_SCALAR_LEN],
       7              :         const bn_t  n
       8              :         )
       9              : {
      10          220 :         bn_write_bin (bin, BBS_SCALAR_LEN, n);
      11          220 : }
      12              : 
      13              : 
      14              : inline void
      15           84 : bn_read_bbs (
      16              :         bn_t           n,
      17              :         const uint8_t  bin[BBS_SCALAR_LEN]
      18              :         )
      19              : {
      20           84 :         bn_read_bin (n, bin, BBS_SCALAR_LEN);
      21           84 :         if (bn_cmp (n, &core_get ()->prime) != RLC_LT)
      22              :         {
      23            0 :                 RLC_THROW (ERR_NO_VALID);
      24              :         }
      25           84 : }
      26              : 
      27              : 
      28              : void
      29          256 : ep_write_bbs (
      30              :         uint8_t     bin[BBS_G1_ELEM_LEN],
      31              :         const ep_t  p
      32              :         )
      33              : {
      34              :         ep_t t;
      35              :         ep_null (t);
      36              : 
      37          256 :         if (ep_is_infty (p))
      38              :         {
      39            0 :                 RLC_THROW (ERR_NO_VALID);
      40              :         }
      41              : 
      42          256 :         ep_norm (t, p);
      43          256 :         ep_pck (t, t);
      44          256 :         fp_write_bin (bin, BBS_G1_ELEM_LEN, t->x);
      45          256 :         bin[0] |= (1 << 7) | (fp_get_bit (t->y, 0) << 5);
      46              :         ep_free (t);
      47          256 : }
      48              : 
      49              : 
      50              : void
      51           66 : ep_read_bbs (
      52              :         ep_t           p,
      53              :         const uint8_t  bin[BBS_G1_ELEM_LEN]
      54              :         )
      55              : {
      56              :         uint8_t buffer[BBS_G1_ELEM_LEN];
      57           66 :         uint8_t flags = bin[0] & 0xe0;
      58              : 
      59          462 :         for (int i = 0; i<BBS_G1_ELEM_LEN / 8; i++)
      60          396 :                 ((uint64_t*) buffer)[i] = ((uint64_t*) bin)[i];
      61           66 :         buffer[0] ^= flags;
      62           66 :         if (0x80 != flags && 0xa0 != flags)
      63              :         {
      64              :                 // In particular, we should never read the neutral element!
      65              :                 // Allowing that would make the algorithms insecure.
      66            0 :                 RLC_THROW (ERR_NO_VALID);
      67              :         }
      68              : 
      69           66 :         p->coord = BASIC;
      70           66 :         fp_read_bin (p->x, buffer, BBS_G1_ELEM_LEN);
      71           66 :         fp_zero (p->y);
      72           66 :         fp_set_bit (p->y, 0, (flags >> 5) & 1);
      73           66 :         fp_set_dig (p->z, 1);
      74           66 :         ep_upk (p, p);
      75              : 
      76           66 :         if (! ep_on_curve (p))
      77              :         {
      78            0 :                 RLC_THROW (ERR_NO_VALID);
      79              :         }
      80           66 : }
      81              : 
      82              : 
      83              : void
      84            4 : ep2_write_bbs (
      85              :         uint8_t      bin[BBS_G2_ELEM_LEN],
      86              :         const ep2_t  p
      87              :         )
      88              : {
      89              :         ep2_t t;
      90              :         ep2_null (t);
      91              : 
      92            4 :         if (ep2_is_infty (p))
      93              :         {
      94              :                 // Should not happen
      95            0 :                 RLC_THROW (ERR_NO_VALID);
      96              :         }
      97              : 
      98            4 :         ep2_norm (t, p);
      99            4 :         ep2_pck (t, t);
     100            4 :         fp_write_bin (bin,                       BBS_G2_ELEM_LEN / 2, t->x[1]);
     101            4 :         fp_write_bin (bin + BBS_G2_ELEM_LEN / 2, BBS_G2_ELEM_LEN / 2, t->x[0]);
     102            4 :         bin[0] |= (1 << 7) | (fp_get_bit (t->y[0], 0) << 5);
     103              :         ep2_free (t);
     104            4 : }
     105              : 
     106              : 
     107              : void
     108           14 : ep2_read_bbs (
     109              :         ep2_t          p,
     110              :         const uint8_t  bin[BBS_G2_ELEM_LEN]
     111              :         )
     112              : {
     113              :         uint8_t buffer[BBS_G2_ELEM_LEN];
     114           14 :         uint8_t flags = bin[0] & 0xe0;
     115              : 
     116          182 :         for (int i = 0; i<BBS_G2_ELEM_LEN / 8; i++)
     117          168 :                 ((uint64_t*) buffer)[i] = ((uint64_t*) bin)[i];
     118           14 :         buffer[0] ^= flags;
     119           14 :         if (0x80 != flags && 0xa0 != flags)
     120              :         {
     121              :                 // In particular, we should never read the neutral element!
     122              :                 // Allowing that would make the algorithms insecure.
     123            0 :                 RLC_THROW (ERR_NO_VALID);
     124              :         }
     125              : 
     126           14 :         p->coord = BASIC;
     127           14 :         fp_read_bin (p->x[1], buffer,                       BBS_G2_ELEM_LEN / 2);
     128           14 :         fp_read_bin (p->x[0], buffer + BBS_G2_ELEM_LEN / 2, BBS_G2_ELEM_LEN / 2);
     129           14 :         fp2_zero (p->y);
     130           14 :         fp_set_bit (p->y[0], 0, (flags >> 5) & 1);
     131           14 :         fp_zero (p->y[1]);
     132           14 :         fp2_set_dig (p->z, 1);
     133           14 :         ep2_upk (p, p);
     134              : 
     135           14 :         if (! ep2_on_curve (p))
     136              :         {
     137            0 :                 RLC_THROW (ERR_NO_VALID);
     138              :         }
     139           14 : }
     140              : 
     141              : 
     142              : // Note: Incremental expand_message API with fixed 48B output needed multiple times during BBS execution. 
     143              : // During generator creation bigger outputs are needed, however not with an incremental API.
     144              : 
     145              : // SHA256
     146          184 : int expand_message_init_sha256 (
     147              :         union bbs_hash_context *ctx
     148              :         )
     149              : {
     150          184 :         uint64_t       zero[]  = {0, 0, 0, 0, 0, 0, 0, 0};
     151          184 :         int            res     = BBS_ERROR;
     152              : 
     153          184 :         if (shaSuccess != SHA256Reset (&ctx->sha256))
     154            0 :                 goto cleanup;
     155          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, (uint8_t*) zero, 64))
     156            0 :                 goto cleanup;
     157              : 
     158          184 :         res = BBS_OK;
     159          184 : cleanup:
     160          184 :         return res;
     161              : }
     162              : 
     163              : 
     164          499 : int expand_message_update_sha256 (
     165              :         union bbs_hash_context *ctx,
     166              :         const uint8_t *msg,
     167              :         uint32_t       msg_len
     168              :         )
     169              : {
     170          499 :         int            res     = BBS_ERROR;
     171              : 
     172          499 :         if (shaSuccess != SHA256Input (&ctx->sha256, msg, msg_len))
     173            0 :                 goto cleanup;
     174              : 
     175          499 :         res = BBS_OK;
     176          499 : cleanup:
     177          499 :         return res;
     178              : }
     179              : 
     180              : 
     181          184 : int expand_message_finalize_48B_sha256 (
     182              :         union bbs_hash_context *ctx,
     183              :         uint8_t        out[48],
     184              :         const uint8_t *dst,
     185              :         uint8_t        dst_len
     186              :         )
     187              : {
     188              :         uint8_t        b_0[32];
     189              :         uint8_t        b_1[32];
     190              :         uint8_t        b_2[32];
     191          184 :         int            res     = BBS_ERROR;
     192          184 :         uint8_t        num     = 0;
     193              : 
     194          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, &num, 1))
     195            0 :                 goto cleanup;
     196          184 :         num = 48;
     197          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, &num, 1))
     198            0 :                 goto cleanup;
     199          184 :         num = 0;
     200          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, &num, 1))
     201            0 :                 goto cleanup;
     202          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, dst, dst_len))
     203            0 :                 goto cleanup;
     204          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, &dst_len, 1))
     205            0 :                 goto cleanup;
     206          184 :         if (shaSuccess != SHA256Result (&ctx->sha256, b_0))
     207            0 :                 goto cleanup;
     208              : 
     209              :         // b_1 = H( b_0, I2OSP(1,1), dst, I2OSP(dst_len, 1))
     210          184 :         if (shaSuccess != SHA256Reset (&ctx->sha256))
     211            0 :                 goto cleanup;
     212          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, b_0, 32))
     213            0 :                 goto cleanup;
     214          184 :         num = 1;
     215          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, &num, 1))
     216            0 :                 goto cleanup;
     217          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, dst, dst_len))
     218            0 :                 goto cleanup;
     219          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, &dst_len, 1))
     220            0 :                 goto cleanup;
     221          184 :         if (shaSuccess != SHA256Result (&ctx->sha256, b_1))
     222            0 :                 goto cleanup;
     223              : 
     224              :         // b_0 ^= b_1
     225          920 :         for (int i = 0; i<4; i++)
     226          736 :                 ((uint64_t*) b_0)[i] ^= ((uint64_t*) b_1)[i];
     227              : 
     228              :         // b_2 = H( b_0, I2OSP(2,1), dst, I2OSP(dst_len, 1))
     229          184 :         if (shaSuccess != SHA256Reset (&ctx->sha256))
     230            0 :                 goto cleanup;
     231          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, b_0, 32))
     232            0 :                 goto cleanup;
     233          184 :         num = 2;
     234          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, &num, 1))
     235            0 :                 goto cleanup;
     236          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, dst, dst_len))
     237            0 :                 goto cleanup;
     238          184 :         if (shaSuccess != SHA256Input (&ctx->sha256, &dst_len, 1))
     239            0 :                 goto cleanup;
     240          184 :         if (shaSuccess != SHA256Result (&ctx->sha256, b_2))
     241            0 :                 goto cleanup;
     242              : 
     243          920 :         for (int i = 0; i<4; i++)
     244          736 :                 ((uint64_t*) out)[i] = ((uint64_t*) b_1)[i];
     245          552 :         for (int i = 4; i<6; i++)
     246          368 :                 ((uint64_t*) out)[i] = ((uint64_t*) b_2)[i - 4];
     247              : 
     248          184 :         res = BBS_OK;
     249          184 : cleanup:
     250          184 :         return res;
     251              : }
     252              : 
     253              : 
     254           89 : int expand_message_dyn_sha256 (
     255              :         uint8_t       *out,
     256              :         uint32_t       out_len,
     257              :         const uint8_t *msg,
     258              :         uint32_t       msg_len,
     259              :         const uint8_t *dst,
     260              :         uint8_t        dst_len
     261              :         )
     262              : {
     263              :         // Hash to curve g1
     264              :         // relic does implement this as ep_map_sswum, but hard-codes the dst, so
     265              :         // we need to reimplement the high level parts here
     266              :         RLC_TRY {
     267           89 :                 md_xmd (out, out_len, msg, msg_len, dst, dst_len);
     268              :         }
     269              :         RLC_CATCH_ANY {
     270              :                 return BBS_ERROR;
     271              :         }
     272           89 :         return BBS_OK;
     273              : }
     274              : 
     275              : 
     276              : // SHAKE256
     277          393 : int expand_message_init_shake256 (
     278              :         union bbs_hash_context *ctx
     279              :         )
     280              : {
     281          393 :         int           res       = shake256_init (&ctx->shake256);
     282          393 :         if (res)
     283              :         {
     284          393 :                 return BBS_OK;
     285              :         }
     286              :         else
     287              :         {
     288            0 :                 return BBS_ERROR;
     289              :         }
     290              : }
     291              : 
     292              : 
     293          848 : int expand_message_update_shake256 (
     294              :         union bbs_hash_context *ctx,
     295              :         const uint8_t *msg,
     296              :         uint32_t       msg_len
     297              :         )
     298              : {
     299          848 :         int           res       = shake_update (&ctx->shake256, msg, msg_len);
     300          848 :         if (res)
     301              :         {
     302          848 :                 return BBS_OK;
     303              :         }
     304              :         else
     305              :         {
     306            0 :                 return BBS_ERROR;
     307              :         }
     308              : }
     309              : 
     310              : 
     311              : /**
     312              :  * @brief Finalizes the expand_message xof operation with flexible output size.
     313              :  *
     314              :  * https://www.rfc-editor.org/rfc/rfc9380.html#name-expand_message_xof
     315              : */
     316              : int
     317          393 : expand_message_finalize_dyn_shake256 (
     318              :         union bbs_hash_context *ctx,
     319              :         uint8_t       *out,
     320              :         uint32_t       out_len,
     321              :         const uint8_t *dst,
     322              :         uint8_t        dst_len
     323              :         )
     324              : {
     325          393 :         int res = BBS_ERROR;
     326          393 :         if (out_len > 65535)
     327              :         {
     328            0 :                 goto cleanup;
     329              :         }
     330              :         if (dst_len > 255)
     331              :         {
     332              :                 goto cleanup;
     333              :         }
     334              :         // H(msg || I2OSP(len_in_bytes, 2) || DST || I2OSP(len(DST), 1), len_in_bytes)
     335          393 :         uint8_t num = out_len / 256;
     336          393 :         if (shake_update (&ctx->shake256, &num, 1) == 0)
     337            0 :                 goto cleanup;
     338          393 :         num = out_len % 256;
     339          393 :         if (shake_update (&ctx->shake256, &num, 1) == 0)
     340            0 :                 goto cleanup;
     341          393 :         if (shake_update (&ctx->shake256, dst, dst_len) == 0)
     342            0 :                 goto cleanup;
     343          393 :         if (shake_update (&ctx->shake256, &dst_len, 1) == 0)
     344            0 :                 goto cleanup;
     345              : 
     346          393 :         shake_xof (&ctx->shake256);
     347              :         // if (Keccak_HashFinal (&ctx->shake256, NULL) != KECCAK_SUCCESS)
     348              :         //      goto cleanup;
     349          393 :         shake_out (&ctx->shake256, out, out_len);
     350          393 :         res = BBS_OK;
     351          393 : cleanup:
     352          393 :         return res;
     353              : }
     354              : 
     355              : 
     356              : /**
     357              :  * @brief Finalizes the expand_message xof operation with fixed output size of 48 bytes.
     358              :  *
     359              :  * https://www.rfc-editor.org/rfc/rfc9380.html#name-expand_message_xof
     360              : */
     361          260 : int expand_message_finalize_48B_shake256 (
     362              :         union bbs_hash_context *ctx,
     363              :         uint8_t        out[48],
     364              :         const uint8_t *dst,
     365              :         uint8_t        dst_len
     366              :         )
     367              : {
     368          260 :         return expand_message_finalize_dyn_shake256 (ctx, out, 48, dst, dst_len);
     369              : }
     370              : 
     371              : 
     372              : int
     373          133 : expand_message_dyn_shake256 (
     374              :         uint8_t       *out,
     375              :         uint32_t       out_len,
     376              :         const uint8_t *msg,
     377              :         uint32_t       msg_len,
     378              :         const uint8_t *dst,
     379              :         uint8_t        dst_len
     380              :         )
     381              : {
     382              :         union bbs_hash_context ctx;
     383          133 :         int                  res       = BBS_ERROR;
     384              : 
     385          133 :         if (BBS_OK !=  expand_message_init_shake256 (&ctx))
     386              :         {
     387            0 :                 goto cleanup;
     388              :         }
     389              : 
     390          133 :         if (BBS_OK != expand_message_update_shake256 (&ctx, msg, msg_len))
     391              :         {
     392            0 :                 goto cleanup;
     393              :         }
     394              : 
     395          133 :         if (BBS_OK != expand_message_finalize_dyn_shake256 (&ctx,
     396              :                                                                 out,
     397              :                                                                 out_len,
     398              :                                                                 dst,
     399              :                                                                 dst_len))
     400              :         {
     401            0 :                 goto cleanup;
     402              :         }
     403              : 
     404          133 :         res = BBS_OK;
     405          133 : cleanup:
     406          133 :         return res;
     407              : }
     408              : 
     409              : 
     410              : inline int
     411          220 : hash_to_scalar_init (
     412              :         bbs_cipher_suite_t *cipher_suite,
     413              :         union bbs_hash_context *ctx
     414              :         )
     415              : {
     416          220 :         return cipher_suite->expand_message_init (ctx);
     417              : }
     418              : 
     419              : 
     420              : inline int
     421          766 : hash_to_scalar_update (
     422              :         bbs_cipher_suite_t *cipher_suite,
     423              :         union bbs_hash_context *ctx,
     424              :         const uint8_t      *msg,
     425              :         uint32_t            msg_len
     426              :         )
     427              : {
     428          766 :         return cipher_suite->expand_message_update (ctx, msg, msg_len);
     429              : }
     430              : 
     431              : 
     432              : inline int
     433          220 : hash_to_scalar_finalize (
     434              :         bbs_cipher_suite_t *cipher_suite,
     435              :         union bbs_hash_context *ctx,
     436              :         bn_t                out,
     437              :         const uint8_t      *dst,
     438              :         uint8_t             dst_len
     439              :         )
     440              : {
     441              :         uint8_t buffer[48];
     442          220 :         int     res = BBS_ERROR;
     443              : 
     444          220 :         if (BBS_OK != cipher_suite->expand_message_finalize_48B (ctx, buffer, dst, dst_len))
     445              :         {
     446            0 :                 goto cleanup;
     447              :         }
     448              : 
     449              :         RLC_TRY {
     450          220 :                 bn_read_bin (out, buffer, 48);
     451          220 :                 bn_mod (out, out, &(core_get ()->ep_r));
     452              :         }
     453              :         RLC_CATCH_ANY {
     454              :                 goto cleanup;
     455              :         }
     456              : 
     457          220 :         res = BBS_OK;
     458          220 : cleanup:
     459          220 :         return res;
     460              : }
     461              : 
     462              : 
     463              : int
     464          170 : hash_to_scalar (
     465              :         bbs_cipher_suite_t *cipher_suite,
     466              :         bn_t                out,
     467              :         const uint8_t      *dst,
     468              :         uint8_t             dst_len,
     469              :         uint64_t            num_messages,
     470              :         ...
     471              :         )
     472              : {
     473              :         va_list  ap;
     474          170 :         uint8_t *msg     = 0;
     475          170 :         uint32_t msg_len = 0;
     476              :         union bbs_hash_context hash_ctx;
     477          170 :         int      res     = BBS_ERROR;
     478              : 
     479          170 :         if (BBS_OK != hash_to_scalar_init (cipher_suite, &hash_ctx))
     480              :         {
     481            0 :                 goto cleanup;
     482              :         }
     483              : 
     484          170 :         va_start (ap, num_messages);
     485          362 :         for(uint64_t i=0; i< num_messages; i++)
     486              :         {
     487          192 :                 msg = va_arg (ap, uint8_t*);
     488          192 :                 msg_len = va_arg (ap, uint32_t);
     489          192 :                 if (BBS_OK != hash_to_scalar_update (cipher_suite,
     490              :                                                      &hash_ctx,
     491              :                                                      msg,
     492              :                                                      msg_len))
     493              :                 {
     494            0 :                         goto cleanup;
     495              :                 }
     496              :         }
     497          170 :         va_end (ap);
     498              : 
     499          170 :         if (BBS_OK != hash_to_scalar_finalize (cipher_suite,
     500              :                                                &hash_ctx,
     501              :                                                out,
     502              :                                                dst,
     503              :                                                dst_len))
     504              :         {
     505            0 :                 goto cleanup;
     506              :         }
     507              : 
     508          170 :         res = BBS_OK;
     509          170 : cleanup:
     510          170 :         return res;
     511              : }
     512              : 
     513              : 
     514              : int
     515           28 : calculate_domain_init (
     516              :         bbs_cipher_suite_t *cipher_suite,
     517              :         union bbs_hash_context *ctx,
     518              :         const uint8_t       pk[BBS_PK_LEN],
     519              :         uint64_t            num_messages
     520              :         )
     521              : {
     522           28 :         uint64_t num_messages_be = UINT64_H2BE (num_messages);
     523           28 :         int      res             = BBS_ERROR;
     524              : 
     525           28 :         if (BBS_OK != hash_to_scalar_init (cipher_suite, ctx))
     526              :         {
     527            0 :                 goto cleanup;
     528              :         }
     529              : 
     530           28 :         if (BBS_OK != hash_to_scalar_update (cipher_suite, ctx, pk, BBS_PK_LEN))
     531              :         {
     532            0 :                 goto cleanup;
     533              :         }
     534              : 
     535           28 :         if (BBS_OK != hash_to_scalar_update (cipher_suite, ctx, (uint8_t*) &num_messages_be, 8))
     536              :         {
     537            0 :                 goto cleanup;
     538              :         }
     539              : 
     540           28 :         res = BBS_OK;
     541           28 : cleanup:
     542           28 :         return res;
     543              : }
     544              : 
     545              : 
     546              : int
     547          172 : calculate_domain_update (
     548              :         bbs_cipher_suite_t *cipher_suite,
     549              :         union bbs_hash_context *ctx,
     550              :         const ep_t          generator
     551              :         )
     552              : {
     553          172 :         int     res = BBS_ERROR;
     554              :         uint8_t buffer[BBS_G1_ELEM_LEN];
     555              : 
     556              :         RLC_TRY {
     557          172 :                 ep_write_bbs (buffer, generator);
     558              :         }
     559              :         RLC_CATCH_ANY {
     560              :                 goto cleanup;
     561              :         }
     562              : 
     563          172 :         if (BBS_OK != hash_to_scalar_update (cipher_suite, ctx, buffer, BBS_G1_ELEM_LEN))
     564              :         {
     565            0 :                 goto cleanup;
     566              :         }
     567              : 
     568          172 :         res = BBS_OK;
     569          172 : cleanup:
     570          172 :         return res;
     571              : }
     572              : 
     573              : 
     574              : int
     575           28 : calculate_domain_finalize (
     576              :         bbs_cipher_suite_t *cipher_suite,
     577              :         union bbs_hash_context *ctx,
     578              :         bn_t                out,
     579              :         const uint8_t      *header,
     580              :         uint64_t            header_len,
     581              :         const uint8_t      *api_id,
     582              :         uint8_t             api_id_len
     583              :         )
     584              : {
     585           28 :         int      res           = BBS_ERROR;
     586              :         uint8_t  domain_dst[256];
     587           28 :         uint64_t header_len_be = UINT64_H2BE (header_len);
     588              : 
     589           28 :         if (api_id_len > 251)
     590              :         {
     591            0 :                 goto cleanup;
     592              :         }
     593              : 
     594         1296 :         for (int i = 0; i < api_id_len; i++)
     595         1268 :                 domain_dst[i] = api_id[i];
     596          140 :         for (int i = 0; i < 4; i++)
     597          112 :                 domain_dst[i + api_id_len] = "H2S_"[i];
     598              : 
     599           28 :         if (BBS_OK != hash_to_scalar_update (cipher_suite, ctx, api_id, api_id_len))
     600              :         {
     601            0 :                 goto cleanup;
     602              :         }
     603              : 
     604           28 :         if (BBS_OK != hash_to_scalar_update (cipher_suite, ctx, (uint8_t*) &header_len_be, 8))
     605              :         {
     606            0 :                 goto cleanup;
     607              :         }
     608              : 
     609           28 :         if (BBS_OK != hash_to_scalar_update (cipher_suite, ctx, header, header_len))
     610              :         {
     611            0 :                 goto cleanup;
     612              :         }
     613              : 
     614           28 :         if (BBS_OK != hash_to_scalar_finalize (cipher_suite, ctx, out, domain_dst, api_id_len + 4))
     615              :         {
     616            0 :                 goto cleanup;
     617              :         }
     618              : 
     619           28 :         res = BBS_OK;
     620           28 : cleanup:
     621           28 :         return res;
     622              : }
     623              : 
     624              : /*
     625              : int
     626              : calculate_domain (
     627              :         bbs_cipher_suite_t *cipher_suite,
     628              :         bn_t                out,
     629              :         const uint8_t       pk[BBS_PK_LEN],
     630              :         uint64_t            num_messages,
     631              :         const uint8_t      *header,
     632              :         uint64_t            header_len,
     633              :         const uint8_t      *api_id,
     634              :         uint8_t             api_id_len,
     635              :         ...
     636              :         )
     637              : {
     638              :         va_list ap;
     639              :         ep_t   *generator;
     640              :         union bbs_hash_context hash_ctx;
     641              :         int     res = BBS_ERROR;
     642              : 
     643              :         if (BBS_OK != calculate_domain_init (cipher_suite, &hash_ctx, pk,
     644              :                                              num_messages))
     645              :         {
     646              :                 goto cleanup;
     647              :         }
     648              : 
     649              :         va_start (ap, api_id_len);
     650              :         while ((generator = va_arg (ap, ep_t*)))
     651              :         {
     652              :                 if (BBS_OK != calculate_domain_update (cipher_suite,
     653              :                                                        &hash_ctx,
     654              :                                                        *generator))
     655              :                 {
     656              :                         goto cleanup;
     657              :                 }
     658              :         }
     659              :         va_end (ap);
     660              : 
     661              :         if (BBS_OK != calculate_domain_finalize (cipher_suite,
     662              :                                                  &hash_ctx,
     663              :                                                  out,
     664              :                                                  header,
     665              :                                                  header_len,
     666              :                                                  api_id,
     667              :                                                  api_id_len)
     668              :             )
     669              :         {
     670              :                 goto cleanup;
     671              :         }
     672              : 
     673              :         res = BBS_OK;
     674              : cleanup:
     675              :         return res;
     676              : }
     677              : */
     678              : 
     679              : int
     680           30 : create_generator_init (
     681              :         bbs_cipher_suite_t *cipher_suite,
     682              :         uint8_t             state[48 + 8],
     683              :         const uint8_t      *api_id,
     684              :         uint32_t            api_id_len
     685              :         )
     686              : {
     687              :         uint8_t buffer[256];
     688              :         union bbs_hash_context hash_ctx;
     689           30 :         int     res = BBS_ERROR;
     690              : 
     691           30 :         if (api_id_len > 255 - 19)
     692              :         {
     693            0 :                 goto cleanup;
     694              :         }
     695              : 
     696         1388 :         for (uint32_t i = 0; i < api_id_len; i++)
     697         1358 :                 buffer[i] = api_id[i];
     698          600 :         for (uint32_t i = 0; i < 19; i++)
     699          570 :                 buffer[i + api_id_len] = "SIG_GENERATOR_SEED_"[i];
     700              : 
     701           30 :         if (BBS_OK != cipher_suite->expand_message_init (&hash_ctx))
     702              :         {
     703            0 :                 goto cleanup;
     704              :         }
     705              : 
     706           30 :         if (BBS_OK != cipher_suite->expand_message_update (&hash_ctx,
     707              :                                              api_id,
     708              :                                              api_id_len))
     709              :         {
     710            0 :                 goto cleanup;
     711              :         }
     712              : 
     713           30 :         if (BBS_OK != cipher_suite->expand_message_update (&hash_ctx,
     714              :                                              (uint8_t*) "MESSAGE_GENERATOR_SEED",
     715              :                                              22))
     716              :         {
     717            0 :                 goto cleanup;
     718              :         }
     719              : 
     720           30 :         if (BBS_OK != cipher_suite->expand_message_finalize_48B (&hash_ctx,
     721              :                                                    state,
     722              :                                                    buffer,
     723           30 :                                                    api_id_len + 19))
     724              :         {
     725            0 :                 goto cleanup;
     726              :         }
     727              : 
     728           30 :         *((uint64_t*) (state + 48)) = 1LL;
     729              : 
     730           30 :         res                         = BBS_OK;
     731           30 : cleanup:
     732           30 :         return res;
     733              : }
     734              : 
     735              : int
     736          194 : create_generator_next (
     737              :         bbs_cipher_suite_t *cipher_suite,
     738              :         uint8_t             state[48 + 8],
     739              :         ep_t                generator,
     740              :         const uint8_t      *api_id,
     741              :         uint32_t            api_id_len
     742              :         )
     743              : {
     744              :         uint8_t  dst_buf[256];
     745              :         uint8_t  rand_buf[128];
     746          194 :         uint64_t i_be = UINT64_H2BE (*((uint64_t*) (state + 48)));
     747              :         union bbs_hash_context hash_ctx;
     748          194 :         int      res  = BBS_ERROR;
     749              : 
     750          194 :         if (api_id_len > 255 - 19)
     751              :         {
     752            0 :                 goto cleanup;
     753              :         }
     754              : 
     755              :         // check that count (i.e. *((uint64_t*) state + 48) < 2**64
     756          194 :         if (0xffffffffffffffff == *((uint64_t*) (state + 48)))
     757              :         {
     758            0 :                 goto cleanup;
     759              :         }
     760              : 
     761          194 :         *((uint64_t*) (state + 48)) += 1LL;
     762              : 
     763         8948 :         for (uint32_t i = 0; i < api_id_len; i++)
     764         8754 :                 dst_buf[i] = api_id[i];
     765         3880 :         for (uint32_t i = 0; i < 19; i++)
     766         3686 :                 dst_buf[i + api_id_len] = "SIG_GENERATOR_SEED_"[i];
     767              : 
     768          194 :         if (BBS_OK != cipher_suite->expand_message_init (&hash_ctx))
     769              :         {
     770            0 :                 goto cleanup;
     771              :         }
     772              : 
     773          194 :         if (BBS_OK != cipher_suite->expand_message_update (&hash_ctx, state, 48))
     774              :         {
     775            0 :                 goto cleanup;
     776              :         }
     777              : 
     778          194 :         if (BBS_OK != cipher_suite->expand_message_update (&hash_ctx,
     779              :                                              (uint8_t*) &i_be,
     780              :                                              8))
     781              :         {
     782            0 :                 goto cleanup;
     783              :         }
     784              : 
     785          194 :         if (BBS_OK != cipher_suite->expand_message_finalize_48B (&hash_ctx,
     786              :                                                    state,
     787              :                                                    dst_buf,
     788          194 :                                                    api_id_len + 19))
     789              :         {
     790            0 :                 goto cleanup;
     791              :         }
     792              : 
     793         3686 :         for (int i = 0; i < 18; i++)
     794         3492 :                 dst_buf[i + api_id_len] = "SIG_GENERATOR_DST_"[i];
     795              : 
     796          194 :         if (BBS_OK != cipher_suite->expand_message_dyn (rand_buf,
     797              :                                                         128,
     798              :                                                         state,
     799              :                                                         48,
     800              :                                                         dst_buf,
     801          194 :                                                         cipher_suite->api_id_len + 18))
     802              :         {
     803            0 :                 goto cleanup;
     804              :         }
     805              : 
     806              :         RLC_TRY {
     807          194 :                 ep_map_rnd(generator, rand_buf, 128);
     808              :         }
     809              :         RLC_CATCH_ANY {
     810              :                 goto cleanup;
     811              :         }
     812              : 
     813          194 :         res = BBS_OK;
     814          194 : cleanup:
     815          194 :         return res;
     816              : }
     817              : 
     818              : 
     819              : // Notes on hash_to_curve for g1:
     820              : //
     821              : // hash_to_curve(msg): (Includes DST for hash_to_field)
     822              : // 1. u = hash_to_field(msg, 2)
     823              : // 2. Q0 = map_to_curve(u[0])
     824              : // 3. Q1 = map_to_curve(u[1])
     825              : // 4. R = Q0 + Q1              # Point addition
     826              : // 5. P = clear_cofactor(R)
     827              : // 6. return P
     828              : //
     829              : // hash_to_field(msg,count): (Requires a DST)
     830              : // 1. len_in_bytes = count * m * L
     831              : // 2. uniform_bytes = expand_message(msg, DST, len_in_bytes)
     832              : // 3. for i in (0, ..., count - 1):
     833              : // 4.   for j in (0, ..., m - 1):
     834              : // 5.     elm_offset = L * (j + i * m)
     835              : // 6.     tv = substr(uniform_bytes, elm_offset, L)
     836              : // 7.     e_j = OS2IP(tv) mod p
     837              : // 8.   u_i = (e_0, ..., e_(m - 1))
     838              : // 9. return (u_0, ..., u_(count - 1))
     839              : //
     840              : // m = 1
     841              : // L = 64
     842              : //
     843              : // clear_cofactor(P) := h_eff * P
     844              : //
     845              : // h_eff = 0xd201000000010001 (implemented by relic?)
     846              : //
     847              : // map_to_curve(u):
     848              : // 1. (x', y') = map_to_curve_simple_swu(u)    # (x', y') is on E'
     849              : // 2.   (x, y) = iso_map(x', y')               # (x, y) is on E
     850              : // 3. return (x, y)
        

Generated by: LCOV version 2.0-1