選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

189 行
7.6 KiB

  1. /// @file rainbow_keypair.c
  2. /// @brief implementations of functions in rainbow_keypair.h
  3. ///
  4. #include "rainbow_keypair.h"
  5. #include "blas.h"
  6. #include "blas_comm.h"
  7. #include "rainbow_blas.h"
  8. #include "rainbow_keypair_computation.h"
  9. #include "utils_prng.h"
  10. #include <stdint.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. static void generate_S_T(unsigned char *s_and_t, prng_t *prng0) {
  14. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, s_and_t, _O1_BYTE * _O2); // S1
  15. s_and_t += _O1_BYTE * _O2;
  16. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, s_and_t, _V1_BYTE * _O1); // T1
  17. s_and_t += _V1_BYTE * _O1;
  18. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, s_and_t, _V1_BYTE * _O2); // T2
  19. s_and_t += _V1_BYTE * _O2;
  20. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, s_and_t, _O1_BYTE * _O2); // T3
  21. }
  22. static unsigned int generate_l1_F12(unsigned char *sk, prng_t *prng0) {
  23. unsigned int n_byte_generated = 0;
  24. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, sk, _O1_BYTE * N_TRIANGLE_TERMS(_V1)); // l1_F1
  25. sk += _O1_BYTE * N_TRIANGLE_TERMS(_V1);
  26. n_byte_generated += _O1_BYTE * N_TRIANGLE_TERMS(_V1);
  27. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, sk, _O1_BYTE * _V1 * _O1); // l1_F2
  28. n_byte_generated += _O1_BYTE * _V1 * _O1;
  29. return n_byte_generated;
  30. }
  31. static unsigned int generate_l2_F12356(unsigned char *sk, prng_t *prng0) {
  32. unsigned int n_byte_generated = 0;
  33. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, sk, _O2_BYTE * N_TRIANGLE_TERMS(_V1)); // l2_F1
  34. sk += _O2_BYTE * N_TRIANGLE_TERMS(_V1);
  35. n_byte_generated += _O2_BYTE * N_TRIANGLE_TERMS(_V1);
  36. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, sk, _O2_BYTE * _V1 * _O1); // l2_F2
  37. sk += _O2_BYTE * _V1 * _O1;
  38. n_byte_generated += _O2_BYTE * _V1 * _O1;
  39. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, sk, _O2_BYTE * _V1 * _O2); // l2_F3
  40. sk += _O2_BYTE * _V1 * _O1;
  41. n_byte_generated += _O2_BYTE * _V1 * _O1;
  42. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, sk, _O2_BYTE * N_TRIANGLE_TERMS(_O1)); // l2_F5
  43. sk += _O2_BYTE * N_TRIANGLE_TERMS(_O1);
  44. n_byte_generated += _O2_BYTE * N_TRIANGLE_TERMS(_O1);
  45. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng0, sk, _O2_BYTE * _O1 * _O2); // l2_F6
  46. n_byte_generated += _O2_BYTE * _O1 * _O2;
  47. return n_byte_generated;
  48. }
  49. static void generate_B1_B2(unsigned char *sk, prng_t *prng0) {
  50. sk += generate_l1_F12(sk, prng0);
  51. generate_l2_F12356(sk, prng0);
  52. }
  53. static void calculate_t4(unsigned char *t2_to_t4, const unsigned char *t1, const unsigned char *t3) {
  54. // t4 = T_sk.t1 * T_sk.t3 - T_sk.t2
  55. unsigned char temp[_V1_BYTE + 32];
  56. unsigned char *t4 = t2_to_t4;
  57. for (unsigned int i = 0; i < _O2; i++) { /// t3 width
  58. gfmat_prod(temp, t1, _V1_BYTE, _O1, t3);
  59. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_gf256v_add(t4, temp, _V1_BYTE);
  60. t4 += _V1_BYTE;
  61. t3 += _O1_BYTE;
  62. }
  63. }
  64. static void obsfucate_l1_polys(unsigned char *l1_polys, const unsigned char *l2_polys, unsigned int n_terms, const unsigned char *s1) {
  65. unsigned char temp[_O1_BYTE + 32];
  66. while (n_terms--) {
  67. gfmat_prod(temp, s1, _O1_BYTE, _O2, l2_polys);
  68. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_gf256v_add(l1_polys, temp, _O1_BYTE);
  69. l1_polys += _O1_BYTE;
  70. l2_polys += _O2_BYTE;
  71. }
  72. }
  73. /////////////////// Classic //////////////////////////////////
  74. ///////////////////// Cyclic //////////////////////////////////
  75. void PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_generate_keypair_cyclic(cpk_t *pk, sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed) {
  76. memcpy(pk->pk_seed, pk_seed, LEN_PKSEED);
  77. memcpy(sk->sk_seed, sk_seed, LEN_SKSEED);
  78. // prng for sk
  79. prng_t prng;
  80. prng_t *prng0 = &prng;
  81. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_set(prng0, sk_seed, LEN_SKSEED);
  82. generate_S_T(sk->s1, prng0); // S,T: only a part of sk
  83. unsigned char t2[sizeof(sk->t4)];
  84. memcpy(t2, sk->t4, _V1_BYTE * _O2); // temporarily store t2
  85. calculate_t4(sk->t4, sk->t1, sk->t3); // t2 <- t4
  86. // prng for pk
  87. sk_t inst_Qs;
  88. sk_t *Qs = &inst_Qs;
  89. prng_t *prng1 = &prng;
  90. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_set(prng1, pk_seed, LEN_PKSEED);
  91. generate_B1_B2(Qs->l1_F1, prng1); // generating l1_Q1, l1_Q2, l2_Q1, l2_Q2, l2_Q3, l2_Q5, l2_Q6
  92. obsfucate_l1_polys(Qs->l1_F1, Qs->l2_F1, N_TRIANGLE_TERMS(_V1), sk->s1);
  93. obsfucate_l1_polys(Qs->l1_F2, Qs->l2_F2, _V1 * _O1, sk->s1);
  94. // so far, the Qs contains l1_F1, l1_F2, l2_F1, l2_F2, l2_F3, l2_F5, l2_F6.
  95. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_calculate_F_from_Q(sk, Qs, sk); // calcuate the rest parts of secret key from Qs and S,T
  96. unsigned char t4[sizeof(sk->t4)];
  97. memcpy(t4, sk->t4, _V1_BYTE * _O2); // temporarily store t4
  98. memcpy(sk->t4, t2, _V1_BYTE * _O2); // restore t2
  99. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_calculate_Q_from_F_cyclic(pk, sk, sk); // calculate the rest parts of public key: l1_Q3, l1_Q5, l1_Q6, l1_Q9, l2_Q9
  100. memcpy(sk->t4, t4, _V1_BYTE * _O2); // restore t4
  101. obsfucate_l1_polys(pk->l1_Q3, Qs->l2_F3, _V1 * _O2, sk->s1);
  102. obsfucate_l1_polys(pk->l1_Q5, Qs->l2_F5, N_TRIANGLE_TERMS(_O1), sk->s1);
  103. obsfucate_l1_polys(pk->l1_Q6, Qs->l2_F6, _O1 * _O2, sk->s1);
  104. obsfucate_l1_polys(pk->l1_Q9, pk->l2_Q9, N_TRIANGLE_TERMS(_O2), sk->s1);
  105. // clean
  106. memset(&prng, 0, sizeof(prng_t));
  107. }
  108. void PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_generate_compact_keypair_cyclic(cpk_t *pk, csk_t *rsk, const unsigned char *pk_seed, const unsigned char *sk_seed) {
  109. memcpy(rsk->pk_seed, pk_seed, LEN_PKSEED);
  110. memcpy(rsk->sk_seed, sk_seed, LEN_SKSEED);
  111. sk_t sk;
  112. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_generate_keypair_cyclic(pk, &sk, pk_seed, sk_seed);
  113. }
  114. void PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_generate_secretkey_cyclic(sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed) {
  115. memcpy(sk->sk_seed, sk_seed, LEN_SKSEED);
  116. // prng for sk
  117. prng_t prng0;
  118. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_set(&prng0, sk_seed, LEN_SKSEED);
  119. generate_S_T(sk->s1, &prng0);
  120. calculate_t4(sk->t4, sk->t1, sk->t3);
  121. // prng for pk
  122. sk_t inst_Qs;
  123. sk_t *Qs = &inst_Qs;
  124. prng_t prng1;
  125. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_set(&prng1, pk_seed, LEN_PKSEED);
  126. generate_B1_B2(Qs->l1_F1, &prng1);
  127. obsfucate_l1_polys(Qs->l1_F1, Qs->l2_F1, N_TRIANGLE_TERMS(_V1), sk->s1);
  128. obsfucate_l1_polys(Qs->l1_F2, Qs->l2_F2, _V1 * _O1, sk->s1);
  129. // calcuate the parts of sk according to pk.
  130. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_calculate_F_from_Q(sk, Qs, sk);
  131. // clean prng for sk
  132. memset(&prng0, 0, sizeof(prng_t));
  133. }
  134. void PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_cpk_to_pk(pk_t *rpk, const cpk_t *cpk) {
  135. // procedure: cpk_t --> extcpk_t --> pk_t
  136. // convert from cpk_t to extcpk_t
  137. ext_cpk_t pk;
  138. // setup prng
  139. prng_t prng0;
  140. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_set(&prng0, cpk->pk_seed, LEN_SKSEED);
  141. // generating parts of key with prng
  142. generate_l1_F12(pk.l1_Q1, &prng0);
  143. // copying parts of key from input. l1_Q3, l1_Q5, l1_Q6, l1_Q9
  144. memcpy(pk.l1_Q3, cpk->l1_Q3, _O1_BYTE * (_V1 * _O2 + N_TRIANGLE_TERMS(_O1) + _O1 * _O2 + N_TRIANGLE_TERMS(_O2)));
  145. // generating parts of key with prng
  146. generate_l2_F12356(pk.l2_Q1, &prng0);
  147. // copying parts of key from input: l2_Q9
  148. memcpy(pk.l2_Q9, cpk->l2_Q9, _O2_BYTE * N_TRIANGLE_TERMS(_O2));
  149. // convert from extcpk_t to pk_t
  150. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_extcpk_to_pk(rpk, &pk);
  151. }