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)
|