kpqc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +21 -0
  4. data/README.md +174 -0
  5. data/Rakefile +57 -0
  6. data/THIRD_PARTY_NOTICES.md +53 -0
  7. data/ext/kpqc/aimer128f/extconf.rb +4 -0
  8. data/ext/kpqc/aimer128s/extconf.rb +4 -0
  9. data/ext/kpqc/aimer192f/extconf.rb +4 -0
  10. data/ext/kpqc/aimer192s/extconf.rb +4 -0
  11. data/ext/kpqc/aimer256f/extconf.rb +4 -0
  12. data/ext/kpqc/aimer256s/extconf.rb +4 -0
  13. data/ext/kpqc/extconf_helper.rb +93 -0
  14. data/ext/kpqc/haetae2/extconf.rb +4 -0
  15. data/ext/kpqc/haetae3/extconf.rb +4 -0
  16. data/ext/kpqc/haetae5/extconf.rb +4 -0
  17. data/ext/kpqc/module.c +195 -0
  18. data/ext/kpqc/ntruplus1152/extconf.rb +4 -0
  19. data/ext/kpqc/ntruplus768/extconf.rb +4 -0
  20. data/ext/kpqc/ntruplus864/extconf.rb +4 -0
  21. data/ext/kpqc/randombytes.c +107 -0
  22. data/ext/kpqc/smaugt128/extconf.rb +4 -0
  23. data/ext/kpqc/smaugt192/extconf.rb +4 -0
  24. data/ext/kpqc/smaugt256/extconf.rb +4 -0
  25. data/ext/kpqc/timer/extconf.rb +4 -0
  26. data/kpqc.gemspec +41 -0
  27. data/lib/kpqc/aimer.rb +38 -0
  28. data/lib/kpqc/api.rb +129 -0
  29. data/lib/kpqc/haetae.rb +25 -0
  30. data/lib/kpqc/ntruplus.rb +25 -0
  31. data/lib/kpqc/smaugt.rb +29 -0
  32. data/lib/kpqc/types.rb +103 -0
  33. data/lib/kpqc/version.rb +6 -0
  34. data/lib/kpqc.rb +33 -0
  35. data/test/algorithm_test.rb +111 -0
  36. data/test/api_test.rb +52 -0
  37. data/test/interop.mjs +34 -0
  38. data/test/interop_test.rb +82 -0
  39. data/test/kat/aimer128f.rsp +10 -0
  40. data/test/kat/aimer128s.rsp +10 -0
  41. data/test/kat/aimer192f.rsp +10 -0
  42. data/test/kat/aimer192s.rsp +10 -0
  43. data/test/kat/aimer256f.rsp +10 -0
  44. data/test/kat/aimer256s.rsp +10 -0
  45. data/test/kat/haetae2.rsp +10 -0
  46. data/test/kat/haetae3.rsp +10 -0
  47. data/test/kat/haetae5.rsp +10 -0
  48. data/test/kat/ntruplus1152.rsp +8 -0
  49. data/test/kat/ntruplus768.rsp +8 -0
  50. data/test/kat/ntruplus864.rsp +8 -0
  51. data/test/kat/smaugt128.rsp +8 -0
  52. data/test/kat/smaugt192.rsp +8 -0
  53. data/test/kat/smaugt256.rsp +8 -0
  54. data/test/kat/timer.rsp +8 -0
  55. data/test/kat_drbg.rb +155 -0
  56. data/test/kat_test.rb +99 -0
  57. data/test/test_helper.rb +21 -0
  58. data/vendor/AIMer/LICENSE +21 -0
  59. data/vendor/AIMer/aim2.c +163 -0
  60. data/vendor/AIMer/aim2.h +36 -0
  61. data/vendor/AIMer/aim2_constant.h +74 -0
  62. data/vendor/AIMer/api.h +42 -0
  63. data/vendor/AIMer/common/crypto_declassify.h +7 -0
  64. data/vendor/AIMer/common/fips202.c +878 -0
  65. data/vendor/AIMer/common/fips202.h +166 -0
  66. data/vendor/AIMer/common/rng.h +56 -0
  67. data/vendor/AIMer/field.h +43 -0
  68. data/vendor/AIMer/field128.c +454 -0
  69. data/vendor/AIMer/field192.c +485 -0
  70. data/vendor/AIMer/field256.c +564 -0
  71. data/vendor/AIMer/hash.c +50 -0
  72. data/vendor/AIMer/hash.h +37 -0
  73. data/vendor/AIMer/params/params-aimer-128f.h +34 -0
  74. data/vendor/AIMer/params/params-aimer-128s.h +34 -0
  75. data/vendor/AIMer/params/params-aimer-192f.h +34 -0
  76. data/vendor/AIMer/params/params-aimer-192s.h +34 -0
  77. data/vendor/AIMer/params/params-aimer-256f.h +34 -0
  78. data/vendor/AIMer/params/params-aimer-256s.h +34 -0
  79. data/vendor/AIMer/params.h +5 -0
  80. data/vendor/AIMer/sign.c +631 -0
  81. data/vendor/AIMer/sign.h +40 -0
  82. data/vendor/AIMer/tree.c +75 -0
  83. data/vendor/AIMer/tree.h +26 -0
  84. data/vendor/HAETAE/LICENSE +22 -0
  85. data/vendor/HAETAE/include/api.h +54 -0
  86. data/vendor/HAETAE/include/common.h +12 -0
  87. data/vendor/HAETAE/include/config.h +42 -0
  88. data/vendor/HAETAE/include/decompose.h +19 -0
  89. data/vendor/HAETAE/include/encoding.h +20 -0
  90. data/vendor/HAETAE/include/fft.h +26 -0
  91. data/vendor/HAETAE/include/fips202.h +40 -0
  92. data/vendor/HAETAE/include/fixpoint.h +125 -0
  93. data/vendor/HAETAE/include/ntt.h +16 -0
  94. data/vendor/HAETAE/include/packing.h +58 -0
  95. data/vendor/HAETAE/include/params.h +117 -0
  96. data/vendor/HAETAE/include/poly.h +65 -0
  97. data/vendor/HAETAE/include/polyfix.h +65 -0
  98. data/vendor/HAETAE/include/polymat.h +32 -0
  99. data/vendor/HAETAE/include/polyvec.h +131 -0
  100. data/vendor/HAETAE/include/randombytes.h +39 -0
  101. data/vendor/HAETAE/include/rans_byte.h +335 -0
  102. data/vendor/HAETAE/include/reduce.h +31 -0
  103. data/vendor/HAETAE/include/sampler.h +23 -0
  104. data/vendor/HAETAE/include/symmetric.h +52 -0
  105. data/vendor/HAETAE/src/decompose.c +73 -0
  106. data/vendor/HAETAE/src/encoding.c +700 -0
  107. data/vendor/HAETAE/src/fft.c +235 -0
  108. data/vendor/HAETAE/src/fips202.c +745 -0
  109. data/vendor/HAETAE/src/fixpoint.c +143 -0
  110. data/vendor/HAETAE/src/ntt.c +98 -0
  111. data/vendor/HAETAE/src/packing.c +595 -0
  112. data/vendor/HAETAE/src/poly.c +371 -0
  113. data/vendor/HAETAE/src/polyfix.c +298 -0
  114. data/vendor/HAETAE/src/polymat.c +82 -0
  115. data/vendor/HAETAE/src/polyvec.c +534 -0
  116. data/vendor/HAETAE/src/reduce.c +96 -0
  117. data/vendor/HAETAE/src/sampler.c +310 -0
  118. data/vendor/HAETAE/src/sign.c +558 -0
  119. data/vendor/HAETAE/src/symmetric-shake.c +50 -0
  120. data/vendor/NTRUplus/LICENSE +21 -0
  121. data/vendor/NTRUplus/NTRU+1152/api.h +24 -0
  122. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.c +878 -0
  123. data/vendor/NTRUplus/NTRU+1152/fips202/fips202.h +166 -0
  124. data/vendor/NTRUplus/NTRU+1152/kem.c +286 -0
  125. data/vendor/NTRUplus/NTRU+1152/ntt.c +394 -0
  126. data/vendor/NTRUplus/NTRU+1152/ntt.h +16 -0
  127. data/vendor/NTRUplus/NTRU+1152/params.h +18 -0
  128. data/vendor/NTRUplus/NTRU+1152/poly.c +318 -0
  129. data/vendor/NTRUplus/NTRU+1152/poly.h +31 -0
  130. data/vendor/NTRUplus/NTRU+1152/randombytes.h +9 -0
  131. data/vendor/NTRUplus/NTRU+1152/symmetric.c +39 -0
  132. data/vendor/NTRUplus/NTRU+1152/symmetric.h +12 -0
  133. data/vendor/NTRUplus/NTRU+768/api.h +24 -0
  134. data/vendor/NTRUplus/NTRU+768/fips202/fips202.c +878 -0
  135. data/vendor/NTRUplus/NTRU+768/fips202/fips202.h +166 -0
  136. data/vendor/NTRUplus/NTRU+768/kem.c +286 -0
  137. data/vendor/NTRUplus/NTRU+768/ntt.c +379 -0
  138. data/vendor/NTRUplus/NTRU+768/ntt.h +16 -0
  139. data/vendor/NTRUplus/NTRU+768/params.h +18 -0
  140. data/vendor/NTRUplus/NTRU+768/poly.c +320 -0
  141. data/vendor/NTRUplus/NTRU+768/poly.h +31 -0
  142. data/vendor/NTRUplus/NTRU+768/randombytes.h +9 -0
  143. data/vendor/NTRUplus/NTRU+768/symmetric.c +39 -0
  144. data/vendor/NTRUplus/NTRU+768/symmetric.h +12 -0
  145. data/vendor/NTRUplus/NTRU+864/api.h +24 -0
  146. data/vendor/NTRUplus/NTRU+864/fips202/fips202.c +878 -0
  147. data/vendor/NTRUplus/NTRU+864/fips202/fips202.h +166 -0
  148. data/vendor/NTRUplus/NTRU+864/kem.c +286 -0
  149. data/vendor/NTRUplus/NTRU+864/ntt.c +383 -0
  150. data/vendor/NTRUplus/NTRU+864/ntt.h +16 -0
  151. data/vendor/NTRUplus/NTRU+864/params.h +18 -0
  152. data/vendor/NTRUplus/NTRU+864/poly.c +314 -0
  153. data/vendor/NTRUplus/NTRU+864/poly.h +31 -0
  154. data/vendor/NTRUplus/NTRU+864/randombytes.h +9 -0
  155. data/vendor/NTRUplus/NTRU+864/symmetric.c +39 -0
  156. data/vendor/NTRUplus/NTRU+864/symmetric.h +12 -0
  157. data/vendor/SMAUG-T/LICENSE +22 -0
  158. data/vendor/SMAUG-T/include/api.h +37 -0
  159. data/vendor/SMAUG-T/include/cbd.h +15 -0
  160. data/vendor/SMAUG-T/include/ciphertext.h +45 -0
  161. data/vendor/SMAUG-T/include/common.h +12 -0
  162. data/vendor/SMAUG-T/include/config.h +48 -0
  163. data/vendor/SMAUG-T/include/dg.h +28 -0
  164. data/vendor/SMAUG-T/include/fips202.h +41 -0
  165. data/vendor/SMAUG-T/include/hash.h +21 -0
  166. data/vendor/SMAUG-T/include/hwt.h +28 -0
  167. data/vendor/SMAUG-T/include/indcpa.h +33 -0
  168. data/vendor/SMAUG-T/include/key.h +34 -0
  169. data/vendor/SMAUG-T/include/pack.h +78 -0
  170. data/vendor/SMAUG-T/include/packring.h +50 -0
  171. data/vendor/SMAUG-T/include/params.h +84 -0
  172. data/vendor/SMAUG-T/include/poly.h +41 -0
  173. data/vendor/SMAUG-T/include/randombytes.h +11 -0
  174. data/vendor/SMAUG-T/include/toomcook.h +14 -0
  175. data/vendor/SMAUG-T/include/verify.h +16 -0
  176. data/vendor/SMAUG-T/src/cbd.c +159 -0
  177. data/vendor/SMAUG-T/src/ciphertext.c +95 -0
  178. data/vendor/SMAUG-T/src/dg.c +112 -0
  179. data/vendor/SMAUG-T/src/fips202.c +745 -0
  180. data/vendor/SMAUG-T/src/hash.c +15 -0
  181. data/vendor/SMAUG-T/src/hwt.c +121 -0
  182. data/vendor/SMAUG-T/src/indcpa.c +187 -0
  183. data/vendor/SMAUG-T/src/kem.c +194 -0
  184. data/vendor/SMAUG-T/src/key.c +102 -0
  185. data/vendor/SMAUG-T/src/pack.c +349 -0
  186. data/vendor/SMAUG-T/src/packring.c +503 -0
  187. data/vendor/SMAUG-T/src/poly.c +200 -0
  188. data/vendor/SMAUG-T/src/toomcook.c +256 -0
  189. data/vendor/SMAUG-T/src/verify.c +48 -0
  190. data/vendor/SOURCES.json +130 -0
  191. metadata +280 -0
@@ -0,0 +1,595 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "packing.h"
4
+ #include "encoding.h"
5
+ #include "params.h"
6
+ #include "poly.h"
7
+ #include "polymat.h"
8
+ #include "polyvec.h"
9
+
10
+ #include <string.h>
11
+
12
+ /*************************************************
13
+ * Name: pack_vk
14
+ *
15
+ * Description: Bit-pack public key vk = (seed, b).
16
+ *
17
+ * Arguments: - uint8_t vk[]: output byte array
18
+ * - const polyveck *b: polynomial vector of length HAETAE_K
19
+ * containg b
20
+ * - const uint8_t seed[]: seed for A'
21
+ *
22
+ * Specification: Implements Algorithm 21, PackVK.
23
+ **************************************************/
24
+ void pack_vk(uint8_t vk[HAETAE_CRYPTO_PUBLICKEYBYTES], polyveck *b,
25
+ const uint8_t seed[HAETAE_SEEDBYTES]) {
26
+ unsigned int i;
27
+
28
+ memcpy(vk, seed, HAETAE_SEEDBYTES);
29
+
30
+ vk += HAETAE_SEEDBYTES;
31
+ for (i = 0; i < HAETAE_K; ++i) {
32
+ pack_poly_q(vk + i * HAETAE_POLYQ_PACKEDBYTES, &b->vec[i]);
33
+ }
34
+ }
35
+
36
+ /*************************************************
37
+ * Name: unpack_vk
38
+ *
39
+ * Description: Unpack public key vk = (seed, b).
40
+ *
41
+ * Arguments: - uint8_t seed[]: seed for A'
42
+ * - polyveck *b: polynomial vector of length HAETAE_K containg b
43
+ * - const uint8_t vk[]: output byte array
44
+ *
45
+ * Specification: Implements Algorithm 22, UnpackVK.
46
+ **************************************************/
47
+ void unpack_vk(polyvecl A[HAETAE_K],
48
+ const uint8_t vk[HAETAE_CRYPTO_PUBLICKEYBYTES]) {
49
+ unsigned int i;
50
+ polyveck b;
51
+ uint8_t seed[HAETAE_SEEDBYTES];
52
+ memcpy(seed, vk, HAETAE_SEEDBYTES);
53
+
54
+ vk += HAETAE_SEEDBYTES;
55
+ for (i = 0; i < HAETAE_K; ++i) {
56
+ unpack_poly_q(&b.vec[i], vk + i * HAETAE_POLYQ_PACKEDBYTES);
57
+ }
58
+ // A' = PRG(rhoprime)
59
+ polymatkl_expand_matA(A, seed);
60
+ polymatkl_double(A);
61
+ #if (HAETAE_MODE == HAETAE_MODE2) || (HAETAE_MODE == HAETAE_MODE3)
62
+ polyveck a;
63
+ polyveck_expand_vecA(&a, seed);
64
+ // first column of A = 2(a-b1*2^d)
65
+ polyveck_double(&b);
66
+ polyveck_sub(&b, &a, &b);
67
+ polyveck_double(&b);
68
+ polyveck_ntt(&b);
69
+ #endif
70
+ // append b into A
71
+ for (i = 0; i < HAETAE_K; ++i) {
72
+ A[i].vec[0] = b.vec[i];
73
+ }
74
+ }
75
+
76
+ /*************************************************
77
+ * Name: pack_sk
78
+ *
79
+ * Description: Bit-pack secret key sk = (vk, s).
80
+ *
81
+ * Arguments: - uint8_t sk[]: output byte array
82
+ * - const uint8_t vk[PUBLICKEYBYTES]: packed vk
83
+ * - const polyvecl *s0: polyvecl pointer containing s0 (encoding
84
+ * starting at offset 1)
85
+ * - const polyveck *s1: polyveck pointer containing s1
86
+ *
87
+ * Specification: Implements Algorithm 23, PackSK.
88
+ **************************************************/
89
+ void pack_sk(uint8_t sk[HAETAE_CRYPTO_SECRETKEYBYTES],
90
+ const uint8_t vk[HAETAE_CRYPTO_PUBLICKEYBYTES], const polyvecm *s0,
91
+ const polyveck *s1, const uint8_t key[HAETAE_SEEDBYTES]) {
92
+ unsigned int i;
93
+ memcpy(sk, vk, HAETAE_CRYPTO_PUBLICKEYBYTES);
94
+
95
+ sk += HAETAE_CRYPTO_PUBLICKEYBYTES;
96
+ for (i = 0; i < HAETAE_M; ++i)
97
+ pack_poly_eta(sk + i * HAETAE_POLYETA_PACKEDBYTES, &s0->vec[i]);
98
+
99
+ sk += (HAETAE_L - 1) * HAETAE_POLYETA_PACKEDBYTES;
100
+ #if (HAETAE_MODE == HAETAE_MODE2) || (HAETAE_MODE == HAETAE_MODE3)
101
+ for (i = 0; i < HAETAE_K; ++i)
102
+ pack_poly2_eta(sk + i * HAETAE_POLY2ETA_PACKEDBYTES, &s1->vec[i]);
103
+ sk += HAETAE_K * HAETAE_POLY2ETA_PACKEDBYTES;
104
+ #elif HAETAE_MODE == HAETAE_MODE5
105
+ for (i = 0; i < HAETAE_K; ++i)
106
+ pack_poly_eta(sk + i * HAETAE_POLYETA_PACKEDBYTES, &s1->vec[i]);
107
+ sk += HAETAE_K * HAETAE_POLYETA_PACKEDBYTES;
108
+ #else
109
+ #error "Not yet implemented."
110
+ #endif
111
+ memcpy(sk, key, HAETAE_SEEDBYTES);
112
+ }
113
+
114
+ /*************************************************
115
+ * Name: unpack_sk
116
+ *
117
+ * Description: Unpack secret key sk = (A, s).
118
+ *
119
+ * Arguments: - polyvecl A[HAETAE_K]: output polyvecl array for A
120
+ * - polyvecl s0: output polyvecl pointer for s0
121
+ * - polyveck s1: output polyveck pointer for s1
122
+ * - const uint8_t sk[]: byte array containing bit-packed sk
123
+ *
124
+ * Specification: Implements Algorithm 24, UnpackSK.
125
+ **************************************************/
126
+ void unpack_sk(polyvecl A[HAETAE_K], polyvecm *s0, polyveck *s1, uint8_t *key,
127
+ const uint8_t sk[HAETAE_CRYPTO_SECRETKEYBYTES]) {
128
+ unsigned int i;
129
+ unpack_vk(A, sk);
130
+
131
+ sk += HAETAE_CRYPTO_PUBLICKEYBYTES;
132
+ for (i = 0; i < HAETAE_M; ++i)
133
+ unpack_poly_eta(&s0->vec[i], sk + i * HAETAE_POLYETA_PACKEDBYTES);
134
+
135
+ sk += HAETAE_M * HAETAE_POLYETA_PACKEDBYTES;
136
+ #if (HAETAE_MODE == HAETAE_MODE2) || (HAETAE_MODE == HAETAE_MODE3)
137
+ for (i = 0; i < HAETAE_K; ++i)
138
+ unpack_poly2_eta(&s1->vec[i], sk + i * HAETAE_POLY2ETA_PACKEDBYTES);
139
+
140
+ sk += HAETAE_K * HAETAE_POLY2ETA_PACKEDBYTES;
141
+ #elif HAETAE_MODE == HAETAE_MODE5
142
+ for (i = 0; i < HAETAE_K; ++i)
143
+ unpack_poly_eta(&s1->vec[i], sk + i * HAETAE_POLYETA_PACKEDBYTES);
144
+
145
+ sk += HAETAE_K * HAETAE_POLYETA_PACKEDBYTES;
146
+ #endif
147
+ memcpy(key, sk, HAETAE_SEEDBYTES);
148
+ }
149
+
150
+ /*************************************************
151
+ * Name: pack_sig
152
+ *
153
+ * Description: Bit-pack signature sig = (c, LB(z1), len(x), len(y), x =
154
+ * Enc(HB(z1)), y = Enc(h)), Zeropadding.
155
+ *
156
+ * Arguments: - uint8_t sig[]: output byte array
157
+ * - const poly *c: pointer to challenge polynomial
158
+ * - const polyvecl *lowbits_z1: pointer to vector LowBits(z1) of
159
+ * length L
160
+ * - const polyvecl *highbits_z1: pointer to vector HighBits(z1) of
161
+ * length L
162
+ * - const polyveck *h: pointer t vector h of length HAETAE_K
163
+ * Returns 1 in case the signature packing failed; otherwise 0.
164
+ *
165
+ * Specification: Implements Algorithm 25, PackSig.
166
+ **************************************************/
167
+ int pack_sig(uint8_t sig[HAETAE_CRYPTO_BYTES], const poly *c,
168
+ const polyvecl *lowbits_z1, const polyvecl *highbits_z1,
169
+ const polyveck *h) {
170
+
171
+ uint8_t encoded_h[HAETAE_N * HAETAE_K];
172
+ uint8_t encoded_hb_z1[HAETAE_N * HAETAE_L];
173
+ uint16_t size_enc_h, size_enc_hb_z1;
174
+ uint8_t offset_enc_h, offset_enc_hb_z1;
175
+
176
+ // init/padding with zeros:
177
+ memset(sig, 0, HAETAE_CRYPTO_BYTES);
178
+
179
+ // encode challenge
180
+ for (size_t i = 0; i < HAETAE_N; i++) {
181
+ sig[i / 8] |= c->coeffs[i] << (i % 8);
182
+ }
183
+ sig += HAETAE_N / 8;
184
+
185
+ for (int i = 0; i < HAETAE_L; ++i)
186
+ poly_decomposed_pack(sig + HAETAE_N * i, &lowbits_z1->vec[i]);
187
+ sig += HAETAE_L * HAETAE_N;
188
+
189
+ size_enc_hb_z1 = encode_hb_z1(encoded_hb_z1, &highbits_z1->vec[0].coeffs[0]);
190
+ size_enc_h = encode_h(encoded_h, &h->vec[0].coeffs[0]);
191
+
192
+ if (size_enc_h == 0 || size_enc_hb_z1 == 0) {
193
+ return 1; // encoding failed
194
+ }
195
+
196
+ // The size of the encoded h and HB(z1) does not always fit in one byte,
197
+ // thus we output a one byte offset to a fixed baseline
198
+ if (size_enc_h < HAETAE_BASE_ENC_H ||
199
+ size_enc_hb_z1 < HAETAE_BASE_ENC_HB_Z1 ||
200
+ size_enc_h > HAETAE_BASE_ENC_H + 255 ||
201
+ size_enc_hb_z1 > HAETAE_BASE_ENC_HB_Z1 + 255) {
202
+ return 1; // encoding size offset out of range
203
+ }
204
+
205
+ offset_enc_hb_z1 = size_enc_hb_z1 - HAETAE_BASE_ENC_HB_Z1;
206
+ offset_enc_h = size_enc_h - HAETAE_BASE_ENC_H;
207
+
208
+ if (HAETAE_SEEDBYTES + HAETAE_L * HAETAE_N + 2 + size_enc_hb_z1 + size_enc_h >
209
+ HAETAE_CRYPTO_BYTES) {
210
+ return 1; // signature too big
211
+ }
212
+
213
+ sig[0] = offset_enc_hb_z1;
214
+ sig[1] = offset_enc_h;
215
+ sig += 2;
216
+
217
+ memcpy(sig, encoded_hb_z1, size_enc_hb_z1);
218
+ sig += size_enc_hb_z1;
219
+
220
+ memcpy(sig, encoded_h, size_enc_h);
221
+
222
+ return 0;
223
+ }
224
+
225
+ /*************************************************
226
+ * Name: unpack_sig
227
+ *
228
+ * Description: Unpack signature sig = (c, LB(z1), len(x), len(y), x =
229
+ * Enc(HB(z1)), y = Enc(h)), Zeropadding.
230
+ *
231
+ * Arguments: - poly *c: pointer to challenge polynomial
232
+ * - polyvecl *lowbits_z1: pointer to output vector LowBits(z1)
233
+ * - polyvecl *highbits_z1: pointer to output vector HighBits(z1)
234
+ * - polyveck *h: pointer to output vector h
235
+ * - const uint8_t sig[]: byte array containing
236
+ * bit-packed signature
237
+ *
238
+ * Returns 1 in case of malformed signature; otherwise 0.
239
+ *
240
+ * Specification: Implements Algorithm 26, UnpackSig.
241
+ **************************************************/
242
+ int unpack_sig(poly *c, polyvecl *lowbits_z1, polyvecl *highbits_z1,
243
+ polyveck *h, const uint8_t sig[HAETAE_CRYPTO_BYTES]) {
244
+
245
+ unsigned int i;
246
+ uint16_t size_enc_hb_z1, size_enc_h;
247
+
248
+ for (i = 0; i < HAETAE_N; i++) {
249
+ c->coeffs[i] = (sig[i / 8] >> (i % 8)) & 1;
250
+ }
251
+ sig += HAETAE_N / 8;
252
+
253
+ for (i = 0; i < HAETAE_L; ++i)
254
+ poly_decomposed_unpack(&lowbits_z1->vec[i], sig + HAETAE_N * i);
255
+ sig += HAETAE_L * HAETAE_N;
256
+
257
+ size_enc_hb_z1 = (uint16_t)sig[0] + HAETAE_BASE_ENC_HB_Z1;
258
+ size_enc_h = (uint16_t)sig[1] + HAETAE_BASE_ENC_H;
259
+ sig += 2;
260
+
261
+ if (HAETAE_CRYPTO_BYTES < (2 + HAETAE_L * HAETAE_N + HAETAE_SEEDBYTES +
262
+ size_enc_h + size_enc_hb_z1))
263
+ return 1; // invalid size_enc_h and/or size_enc_hb_z1
264
+
265
+ if (decode_hb_z1(&highbits_z1->vec[0].coeffs[0], sig, size_enc_hb_z1)) {
266
+ return 1; // decoding failed
267
+ }
268
+
269
+ sig += size_enc_hb_z1;
270
+
271
+ if (decode_h(&h->vec[0].coeffs[0], sig, size_enc_h)) {
272
+ return 1; // decoding failed
273
+ }
274
+
275
+ sig += size_enc_h;
276
+
277
+ for (int i = 0;
278
+ i < HAETAE_CRYPTO_BYTES - (HAETAE_SEEDBYTES + HAETAE_L * HAETAE_N + 2 +
279
+ size_enc_hb_z1 + size_enc_h);
280
+ i++)
281
+ if (sig[i] != 0)
282
+ return 1; // verify zero padding
283
+
284
+ return 0;
285
+ }
286
+
287
+ /*************************************************
288
+ * Name: pack_poly_q
289
+ *
290
+ * Description: Bit-pack polynomial with coefficients in [0, HAETAE_Q - 1].
291
+ *
292
+ * Arguments: - uint8_t *r: pointer to output byte array with at least
293
+ * HAETAE_POLYQ_PACKEDBYTES bytes
294
+ * - const poly *a: pointer to input polynomial
295
+ *
296
+ * Specification: Implements Algorithm 27, PackPolyQ.
297
+ **************************************************/
298
+ void pack_poly_q(uint8_t *r, const poly *a) {
299
+ unsigned int i;
300
+ #if (HAETAE_MODE == HAETAE_MODE2) || (HAETAE_MODE == HAETAE_MODE3)
301
+ int b_idx = 0, d_idx = 0;
302
+
303
+ for (i = 0; i < (HAETAE_N >> 3); ++i) {
304
+ b_idx = 15 * i;
305
+ d_idx = 8 * i;
306
+
307
+ r[b_idx] = (a->coeffs[d_idx] & 0xff);
308
+ r[b_idx + 1] =
309
+ ((a->coeffs[d_idx] >> 8) & 0x7f) | ((a->coeffs[d_idx + 1] & 0x1) << 7);
310
+ r[b_idx + 2] = ((a->coeffs[d_idx + 1] >> 1) & 0xff);
311
+ r[b_idx + 3] = ((a->coeffs[d_idx + 1] >> 9) & 0x3f) |
312
+ ((a->coeffs[d_idx + 2] & 0x3) << 6);
313
+ r[b_idx + 4] = ((a->coeffs[d_idx + 2] >> 2) & 0xff);
314
+ r[b_idx + 5] = ((a->coeffs[d_idx + 2] >> 10) & 0x1f) |
315
+ ((a->coeffs[d_idx + 3] & 0x7) << 5);
316
+ r[b_idx + 6] = ((a->coeffs[d_idx + 3] >> 3) & 0xff);
317
+ r[b_idx + 7] = ((a->coeffs[d_idx + 3] >> 11) & 0xf) |
318
+ ((a->coeffs[d_idx + 4] & 0xf) << 4);
319
+ r[b_idx + 8] = ((a->coeffs[d_idx + 4] >> 4) & 0xff);
320
+ r[b_idx + 9] = ((a->coeffs[d_idx + 4] >> 12) & 0x7) |
321
+ ((a->coeffs[d_idx + 5] & 0x1f) << 3);
322
+ r[b_idx + 10] = ((a->coeffs[d_idx + 5] >> 5) & 0xff);
323
+ r[b_idx + 11] = ((a->coeffs[d_idx + 5] >> 13) & 0x3) |
324
+ ((a->coeffs[d_idx + 6] & 0x3f) << 2);
325
+ r[b_idx + 12] = ((a->coeffs[d_idx + 6] >> 6) & 0xff);
326
+ r[b_idx + 13] = ((a->coeffs[d_idx + 6] >> 14) & 0x1) |
327
+ (a->coeffs[d_idx + 7] & 0x7f) << 1;
328
+ r[b_idx + 14] = ((a->coeffs[d_idx + 7] >> 7) & 0xff);
329
+ }
330
+ #elif HAETAE_MODE == HAETAE_MODE5
331
+ for (i = 0; i < HAETAE_N / 1; ++i) {
332
+ r[2 * i + 0] = a->coeffs[1 * i + 0] >> 0;
333
+ r[2 * i + 1] = a->coeffs[1 * i + 0] >> 8;
334
+ }
335
+ #endif
336
+ }
337
+
338
+ /*************************************************
339
+ * Name: unpack_poly_q
340
+ *
341
+ * Description: Unpack polynomial with coefficients in [0, HAETAE_Q - 1].
342
+ *
343
+ * Arguments: - poly *r: pointer to output polynomial
344
+ * - const uint8_t *a: byte array with bit-packed polynomial
345
+ *
346
+ * Specification: Implements Algorithm 28, UnpackPolyQ.
347
+ **************************************************/
348
+ void unpack_poly_q(poly *r, const uint8_t *a) {
349
+ unsigned int i;
350
+ #if (HAETAE_MODE == HAETAE_MODE2) || (HAETAE_MODE == HAETAE_MODE3)
351
+ int b_idx = 0, d_idx = 0;
352
+
353
+ for (i = 0; i < (HAETAE_N >> 3); ++i) {
354
+ b_idx = 15 * i;
355
+ d_idx = 8 * i;
356
+
357
+ r->coeffs[d_idx] = (a[b_idx] & 0xff) | ((a[b_idx + 1] & 0x7f) << 8);
358
+ r->coeffs[d_idx + 1] = ((a[b_idx + 1] >> 7) & 0x1) |
359
+ ((a[b_idx + 2] & 0xff) << 1) |
360
+ ((a[b_idx + 3] & 0x3f) << 9);
361
+ r->coeffs[d_idx + 2] = ((a[b_idx + 3] >> 6) & 0x3) |
362
+ ((a[b_idx + 4] & 0xff) << 2) |
363
+ ((a[b_idx + 5] & 0x1f) << 10);
364
+ r->coeffs[d_idx + 3] = ((a[b_idx + 5] >> 5) & 0x7) |
365
+ ((a[b_idx + 6] & 0xff) << 3) |
366
+ ((a[b_idx + 7] & 0xf) << 11);
367
+ r->coeffs[d_idx + 4] = ((a[b_idx + 7] >> 4) & 0xf) |
368
+ ((a[b_idx + 8] & 0xff) << 4) |
369
+ ((a[b_idx + 9] & 0x7) << 12);
370
+ r->coeffs[d_idx + 5] = ((a[b_idx + 9] >> 3) & 0x1f) |
371
+ ((a[b_idx + 10] & 0xff) << 5) |
372
+ ((a[b_idx + 11] & 0x3) << 13);
373
+ r->coeffs[d_idx + 6] = ((a[b_idx + 11] >> 2) & 0x3f) |
374
+ ((a[b_idx + 12] & 0xff) << 6) |
375
+ ((a[b_idx + 13] & 0x1) << 14);
376
+ r->coeffs[d_idx + 7] =
377
+ ((a[b_idx + 13] >> 1) & 0x7f) | ((a[b_idx + 14] & 0xff) << 7);
378
+ }
379
+
380
+ #elif HAETAE_MODE == HAETAE_MODE5
381
+ for (i = 0; i < HAETAE_N / 1; ++i) {
382
+ r->coeffs[1 * i + 0] = a[2 * i + 0] >> 0;
383
+ r->coeffs[1 * i + 0] |= (uint16_t)a[2 * i + 1] << 8;
384
+ r->coeffs[1 * i + 0] &= 0xffff;
385
+ }
386
+ #endif
387
+ }
388
+
389
+ /*************************************************
390
+ * Name: pack_polyeta
391
+ *
392
+ * Description: Bit-pack polynomial with coefficients in [-ETA,ETA].
393
+ *
394
+ * Arguments: - uint8_t *r: pointer to output byte array with at least
395
+ * HAETAE_POLYETA_PACKEDBYTES bytes
396
+ * - const poly *a: pointer to input polynomial
397
+ *
398
+ * Specification: Implements Algorithm 29, PackPolyEta.
399
+ **************************************************/
400
+ void pack_poly_eta(uint8_t *r, const poly *a) {
401
+ unsigned int i;
402
+ uint8_t t[8];
403
+
404
+ for (i = 0; i < HAETAE_N / 4; ++i) {
405
+ t[0] = HAETAE_ETA - a->coeffs[4 * i + 0];
406
+ t[1] = HAETAE_ETA - a->coeffs[4 * i + 1];
407
+ t[2] = HAETAE_ETA - a->coeffs[4 * i + 2];
408
+ t[3] = HAETAE_ETA - a->coeffs[4 * i + 3];
409
+ r[i] = t[0] >> 0;
410
+ r[i] |= t[1] << 2;
411
+ r[i] |= t[2] << 4;
412
+ r[i] |= t[3] << 6;
413
+ }
414
+ }
415
+
416
+ /*************************************************
417
+ * Name: unpack_poly_eta
418
+ *
419
+ * Description: Unpack polynomial with coefficients in [-ETA,ETA].
420
+ *
421
+ * Arguments: - poly *r: pointer to output polynomial
422
+ * - const uint8_t *a: byte array with bit-packed polynomial
423
+ *
424
+ * Specification: Implements Algorithm 30, UnpackPolyEta.
425
+ **************************************************/
426
+ void unpack_poly_eta(poly *r, const uint8_t *a) {
427
+ unsigned int i;
428
+ for (i = 0; i < HAETAE_N / 4; ++i) {
429
+ r->coeffs[4 * i + 0] = a[i] >> 0;
430
+ r->coeffs[4 * i + 0] &= 0x3;
431
+
432
+ r->coeffs[4 * i + 1] = a[i] >> 2;
433
+ r->coeffs[4 * i + 1] &= 0x3;
434
+
435
+ r->coeffs[4 * i + 2] = a[i] >> 4;
436
+ r->coeffs[4 * i + 2] &= 0x3;
437
+
438
+ r->coeffs[4 * i + 3] = a[i] >> 6;
439
+ r->coeffs[4 * i + 3] &= 0x3;
440
+
441
+ r->coeffs[4 * i + 0] = HAETAE_ETA - r->coeffs[4 * i + 0];
442
+ r->coeffs[4 * i + 1] = HAETAE_ETA - r->coeffs[4 * i + 1];
443
+ r->coeffs[4 * i + 2] = HAETAE_ETA - r->coeffs[4 * i + 2];
444
+ r->coeffs[4 * i + 3] = HAETAE_ETA - r->coeffs[4 * i + 3];
445
+ }
446
+ }
447
+
448
+ /*************************************************
449
+ * Name: pack_poly2eta
450
+ *
451
+ * Description: Bit-pack polynomial with coefficients in [-ETA-1,ETA+1].
452
+ *
453
+ * Arguments: - uint8_t *r: pointer to output byte array with at least
454
+ * HAETAE_POLYETA_PACKEDBYTES bytes
455
+ * - const poly *a: pointer to input polynomial
456
+ *
457
+ * Specification: Implements Algorithm 31, PackPoly2Eta.
458
+ **************************************************/
459
+ void pack_poly2_eta(uint8_t *r, const poly *a) {
460
+ unsigned int i;
461
+ uint8_t t[8];
462
+ for (i = 0; i < HAETAE_N / 8; ++i) {
463
+ t[0] = 2 * HAETAE_ETA - a->coeffs[8 * i + 0];
464
+ t[1] = 2 * HAETAE_ETA - a->coeffs[8 * i + 1];
465
+ t[2] = 2 * HAETAE_ETA - a->coeffs[8 * i + 2];
466
+ t[3] = 2 * HAETAE_ETA - a->coeffs[8 * i + 3];
467
+ t[4] = 2 * HAETAE_ETA - a->coeffs[8 * i + 4];
468
+ t[5] = 2 * HAETAE_ETA - a->coeffs[8 * i + 5];
469
+ t[6] = 2 * HAETAE_ETA - a->coeffs[8 * i + 6];
470
+ t[7] = 2 * HAETAE_ETA - a->coeffs[8 * i + 7];
471
+
472
+ r[3 * i + 0] = (t[0] >> 0) | (t[1] << 3) | (t[2] << 6);
473
+ r[3 * i + 1] = (t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7);
474
+ r[3 * i + 2] = (t[5] >> 1) | (t[6] << 2) | (t[7] << 5);
475
+ }
476
+ }
477
+
478
+ /*************************************************
479
+ * Name: unpack_poly2eta
480
+ *
481
+ * Description: Unpack polynomial with coefficients in [-ETA-1,ETA+1].
482
+ *
483
+ * Arguments: - poly *r: pointer to output polynomial
484
+ * - const uint8_t *a: byte array with bit-packed polynomial
485
+ *
486
+ * Specification: Implements Algorithm 32, UnpackPoly2Eta.
487
+ **************************************************/
488
+ void unpack_poly2_eta(poly *r, const uint8_t *a) {
489
+ unsigned int i;
490
+ for (i = 0; i < HAETAE_N / 8; ++i) {
491
+ r->coeffs[8 * i + 0] = (a[3 * i + 0] >> 0) & 7;
492
+ r->coeffs[8 * i + 1] = (a[3 * i + 0] >> 3) & 7;
493
+ r->coeffs[8 * i + 2] = ((a[3 * i + 0] >> 6) | (a[3 * i + 1] << 2)) & 7;
494
+ r->coeffs[8 * i + 3] = (a[3 * i + 1] >> 1) & 7;
495
+ r->coeffs[8 * i + 4] = (a[3 * i + 1] >> 4) & 7;
496
+ r->coeffs[8 * i + 5] = ((a[3 * i + 1] >> 7) | (a[3 * i + 2] << 1)) & 7;
497
+ r->coeffs[8 * i + 6] = (a[3 * i + 2] >> 2) & 7;
498
+ r->coeffs[8 * i + 7] = (a[3 * i + 2] >> 5) & 7;
499
+
500
+ r->coeffs[8 * i + 0] = 2 * HAETAE_ETA - r->coeffs[8 * i + 0];
501
+ r->coeffs[8 * i + 1] = 2 * HAETAE_ETA - r->coeffs[8 * i + 1];
502
+ r->coeffs[8 * i + 2] = 2 * HAETAE_ETA - r->coeffs[8 * i + 2];
503
+ r->coeffs[8 * i + 3] = 2 * HAETAE_ETA - r->coeffs[8 * i + 3];
504
+ r->coeffs[8 * i + 4] = 2 * HAETAE_ETA - r->coeffs[8 * i + 4];
505
+ r->coeffs[8 * i + 5] = 2 * HAETAE_ETA - r->coeffs[8 * i + 5];
506
+ r->coeffs[8 * i + 6] = 2 * HAETAE_ETA - r->coeffs[8 * i + 6];
507
+ r->coeffs[8 * i + 7] = 2 * HAETAE_ETA - r->coeffs[8 * i + 7];
508
+ }
509
+ }
510
+
511
+ /*************************************************
512
+ * Name: pack_vec_highbits
513
+ *
514
+ * Description: pack highbits of a vector of polynomials
515
+ *
516
+ * Arguments: - uint8_t *buf: pointer to output bytes array
517
+ * - const polyveck *v: a vector of polynomials
518
+ *
519
+ * Specification: Implements Algorithm 33, PackVecHighBits.
520
+ **************************************************/
521
+ void pack_vec_highbits(uint8_t *buf, const polyveck *v) {
522
+ unsigned int i;
523
+ for (i = 0; i < HAETAE_K; i++) {
524
+ pack_poly_highbits(buf + i * HAETAE_POLY_HIGHBITS_PACKEDBYTES, &v->vec[i]);
525
+ }
526
+ }
527
+
528
+ /*************************************************
529
+ * Name: pack_poly_highbits
530
+ *
531
+ * Description: pack highbits of a polynomial
532
+ *
533
+ * Arguments: - uint8_t *buf: pointer to output bytes array
534
+ * - const poly *v: a polynomial
535
+ *
536
+ * Specification: Implements Algorithm 34, PackPolyHighBits.
537
+ **************************************************/
538
+ void pack_poly_highbits(uint8_t *buf, const poly *a) {
539
+ unsigned int i;
540
+ #if (HAETAE_MODE == HAETAE_MODE2) || (HAETAE_MODE == HAETAE_MODE3)
541
+ for (i = 0; i < HAETAE_N; i++) {
542
+ // if ((uint32_t)a->coeffs[i] > 0xFF) {
543
+ // printf("1byte overflow: i=%d coeff=%08X\n", i, a->coeffs[i]);
544
+ // }
545
+ buf[i] = (uint8_t)a->coeffs[i];
546
+ }
547
+ #elif HAETAE_MODE == HAETAE_MODE5
548
+ for (i = 0; i < HAETAE_N / 8; i++) {
549
+ buf[9 * i + 0] = a->coeffs[8 * i + 0] & 0xff;
550
+
551
+ buf[9 * i + 1] = (a->coeffs[8 * i + 0] >> 8) & 0x01;
552
+ buf[9 * i + 1] |= (a->coeffs[8 * i + 1] << 1) & 0xff;
553
+
554
+ buf[9 * i + 2] = (a->coeffs[8 * i + 1] >> 7) & 0x03;
555
+ buf[9 * i + 2] |= (a->coeffs[8 * i + 2] << 2) & 0xff;
556
+
557
+ buf[9 * i + 3] = (a->coeffs[8 * i + 2] >> 6) & 0x07;
558
+ buf[9 * i + 3] |= (a->coeffs[8 * i + 3] << 3) & 0xff;
559
+
560
+ buf[9 * i + 4] = (a->coeffs[8 * i + 3] >> 5) & 0x0f;
561
+ buf[9 * i + 4] |= (a->coeffs[8 * i + 4] << 4) & 0xff;
562
+
563
+ buf[9 * i + 5] = (a->coeffs[8 * i + 4] >> 4) & 0x1f;
564
+ buf[9 * i + 5] |= (a->coeffs[8 * i + 5] << 5) & 0xff;
565
+
566
+ buf[9 * i + 6] = (a->coeffs[8 * i + 5] >> 3) & 0x3f;
567
+ buf[9 * i + 6] |= (a->coeffs[8 * i + 6] << 6) & 0xff;
568
+
569
+ buf[9 * i + 7] = (a->coeffs[8 * i + 6] >> 2) & 0x7f;
570
+ buf[9 * i + 7] |= (a->coeffs[8 * i + 7] << 7) & 0xff;
571
+
572
+ buf[9 * i + 8] = (a->coeffs[8 * i + 7] >> 1) & 0xff;
573
+ }
574
+ #endif
575
+ }
576
+
577
+ /*************************************************
578
+ * Name: pack_poly_lsb
579
+ *
580
+ * Description: pack lsb of a polynomial
581
+ *
582
+ * Arguments: - uint8_t *buf: pointer to output bytes array
583
+ * - const poly *a: a polynomial
584
+ *
585
+ * Specification: Implements Algorithm 35, PackPolyLsb.
586
+ **************************************************/
587
+ void pack_poly_lsb(uint8_t *buf, const poly *a) {
588
+ unsigned int i;
589
+ for (i = 0; i < HAETAE_N; i++) {
590
+ if ((i % 8) == 0) {
591
+ buf[i / 8] = 0;
592
+ }
593
+ buf[i / 8] |= (a->coeffs[i] & 1) << (i % 8);
594
+ }
595
+ }