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,15 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "hash.h"
4
+ #include "fips202.h"
5
+
6
+ void shake256_absorb_twice_squeeze(uint8_t *out, size_t outlen,
7
+ const uint8_t *in1, size_t inlen1,
8
+ const uint8_t *in2, size_t inlen2) {
9
+ keccak_state state;
10
+ shake256_init(&state);
11
+ shake256_absorb(&state, in1, inlen1);
12
+ shake256_absorb(&state, in2, inlen2);
13
+ shake256_finalize(&state);
14
+ shake256_squeeze(out, outlen, &state);
15
+ }
@@ -0,0 +1,121 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "hwt.h"
4
+ #include "fips202.h"
5
+
6
+ /*************************************************
7
+ * Name: load16_littleendian
8
+ *
9
+ * Description: load 2 bytes into a 16-bit integer
10
+ * in little-endian order
11
+ *
12
+ * Arguments: - uint16_t *out: pointer to output int16_t array
13
+ * - size_t outlen: output length
14
+ * - const uint8_t *in: pointer to input byte array
15
+ **************************************************/
16
+ #define load16_littleendian SMAUGT_NAMESPACE(load16_littleendian)
17
+ static void load16_littleendian(uint16_t *out, size_t outlen,
18
+ const uint8_t *in) {
19
+ size_t pos = 0;
20
+ for (size_t i = 0; i < outlen; ++i) {
21
+ out[i] = ((uint16_t)(in[pos])) | ((uint16_t)(in[pos + 1]) << 8);
22
+ pos += 2;
23
+ }
24
+ }
25
+
26
+ // referenced
27
+ // Décio Luiz Gazzoni Filho and Tomás S. R. Silva and Julio López
28
+ // “Efficient isochronous fixed-weight sampling with applications to {NTRU},” in
29
+ // Cryptology {ePrint} Archive, Paper 2024/548. 2024,
30
+ // url: eprint.iacr.org/2024/548.
31
+ /*************************************************
32
+ * Name: rej_sample_mod
33
+ *
34
+ * Description: Sample array of random integers such that res[i] is in the range
35
+ * [0, SMAUGT_N - i] for 0 <= i < SMAUGT_N
36
+ *
37
+ * Arguments: - uint8_t si[SMAUGT_N]: pointer to ouptput polynomial r(x),
38
+ * assumed to be already initialized
39
+ * - const uint16_t *seed: pointer to input seed (of length
40
+ * SMAUGT_HWTSEEDBYTES/2)
41
+ *
42
+ * Specification: Implements Algorithm 4, RejSampleMod.
43
+ **************************************************/
44
+ #define rej_sample_mod SMAUGT_NAMESPACE(rej_sample_mod)
45
+ static int rej_sample_mod(int16_t si[SMAUGT_N], const uint16_t *rand) {
46
+ unsigned int i, j = SMAUGT_N;
47
+ uint32_t m;
48
+ uint16_t s, t, l;
49
+
50
+ for (i = 0; i < SMAUGT_N; i++) {
51
+ s = SMAUGT_N - i;
52
+ t = 65536 % s;
53
+
54
+ m = (uint32_t)rand[i] * s;
55
+ l = m;
56
+
57
+ while (l < t) {
58
+ if (j >= (SMAUGT_HWTSEEDBYTES / 2))
59
+ return -1; // all randomness used
60
+ m = (uint32_t)rand[j++] * s;
61
+ l = m;
62
+ }
63
+
64
+ si[i] = m >> 16;
65
+ }
66
+
67
+ return 0;
68
+ }
69
+
70
+ /*************************************************
71
+ * Name: hwt
72
+ *
73
+ * Description: Hamming weight sampling deterministically to generate sparse
74
+ * polynomial r(x) from a seed. shake256 is the Extendable-Output
75
+ * Function from the SHA-3 family.
76
+ *
77
+ * Arguments: - int16_t *res: pointer to ouptput polynomial r(x)
78
+ * (of length SMAUGT_N), assumed to be already initialized
79
+ * - const uint8_t *seed: pointer to input seed (of length
80
+ * SMAUGT_CRYPTO_BYTES + 2)
81
+ *
82
+ * Specification: Implements Algorithm 3, HWT.
83
+ **************************************************/
84
+ int hwt(int16_t *res, const uint8_t *seed) {
85
+ unsigned int i;
86
+ int16_t si[SMAUGT_N] = {0};
87
+ uint16_t rand[SMAUGT_HWTSEEDBYTES / 2] = {0};
88
+ uint8_t sign[SMAUGT_N / 4] = {0};
89
+ uint8_t buf[SMAUGT_HWTSEEDBYTES] = {0};
90
+
91
+ keccak_state state;
92
+ shake256_init(&state);
93
+ shake256_absorb_once(&state, seed, SMAUGT_CRYPTO_BYTES + 2);
94
+
95
+ // only executed once with overwhelming probability:
96
+ shake256_squeeze(buf, SMAUGT_HWTSEEDBYTES, &state);
97
+ load16_littleendian(rand, SMAUGT_HWTSEEDBYTES / 2, buf);
98
+ if (rej_sample_mod(si, rand)) {
99
+ return -1;
100
+ }
101
+
102
+ shake256_squeeze(sign, SMAUGT_N / 4, &state);
103
+
104
+ int16_t t0;
105
+ int16_t c0 = SMAUGT_N - SMAUGT_HS;
106
+ for (i = 0; i < SMAUGT_N; i++) {
107
+ t0 = (si[i] - c0) >> 15;
108
+ c0 += t0;
109
+ res[i] = 1 + t0;
110
+ // Convert to ternary
111
+ // index of sign: (i / 16 / 8) * 16 + (i % 16)
112
+ // shift size : (i / 16) % 8
113
+ res[i] =
114
+ (-res[i]) &
115
+ ((((sign[(((i >> 4) >> 3) << 4) + (i & 0x0F)] >> ((i >> 4) & 0x07))
116
+ << 1) &
117
+ 0x02) -
118
+ 1);
119
+ }
120
+ return 0;
121
+ }
@@ -0,0 +1,187 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "indcpa.h"
4
+ #include "cbd.h"
5
+ #include "fips202.h"
6
+ #include "pack.h"
7
+ #include "randombytes.h"
8
+ #include "verify.h"
9
+
10
+ #include <string.h>
11
+
12
+ /*************************************************
13
+ * Name: expand_r
14
+ *
15
+ * Description: Deterministically generate a vector of sparse polynomial r(x)
16
+ * from a seed.
17
+ *
18
+ * Arguments: - polyvec *r: pointer to ouptput vector r
19
+ * - uint8_t *seed: pointer to input seed (of length
20
+ * SMAUGT_DELTA_BYTES)
21
+ *
22
+ * Specification: Implements Algorithm 5, ExpandR.
23
+ **************************************************/
24
+ void expand_r(polyvec *r, const uint8_t *seed) {
25
+ unsigned int i;
26
+ uint8_t buf[SMAUGT_CBDSEED_BYTES] = {0};
27
+
28
+ for (i = 0; i < SMAUGT_K; ++i) {
29
+ uint8_t extseed[SMAUGT_DELTA_BYTES + 1];
30
+ memcpy(extseed, seed, SMAUGT_DELTA_BYTES);
31
+ extseed[SMAUGT_DELTA_BYTES] = i;
32
+
33
+ shake256(buf, SMAUGT_CBDSEED_BYTES, extseed, SMAUGT_DELTA_BYTES + 1);
34
+ sp_cbd(&r->vec[i], buf);
35
+ }
36
+ }
37
+
38
+ /*************************************************
39
+ * Name: indcpa_keypair
40
+ *
41
+ * Description: Generates a public key and a private key deterministically
42
+ * from the given randomness seed.
43
+ * Key generation function of the CPA-secure Module-Lizard
44
+ * public-key encryption scheme.
45
+ *
46
+ * Arguments: - uint8_t pk[SMAUGT_PUBLICKEY_BYTES]: pointer to output public
47
+ * key
48
+ * - uint8_t sk[SMAUGT_PKE_SECRETKEY_BYTES]: pointer to output
49
+ * private key
50
+ * - uint8_t seed[SMAUGT_CRYPTO_BYTES]: pointer to input seed
51
+ *
52
+ * Specification: Implements Algorithm 25, SMAUGT-T.PKE.KeyGen.
53
+ **************************************************/
54
+ void indcpa_keypair(uint8_t pk[SMAUGT_PUBLICKEY_BYTES],
55
+ uint8_t sk[SMAUGT_PKE_SECRETKEY_BYTES],
56
+ const uint8_t seed[SMAUGT_CRYPTO_BYTES]) {
57
+ public_key pk_tmp;
58
+ secret_key sk_tmp;
59
+ memset(&pk_tmp, 0, sizeof(public_key));
60
+ memset(&sk_tmp, 0, sizeof(secret_key));
61
+
62
+ uint8_t extseed[SMAUGT_CRYPTO_BYTES + SMAUGT_PKSEED_BYTES] = {0};
63
+ #if SMAUGT_CRYPTO_BYTES + SMAUGT_PKSEED_BYTES != 64
64
+ #error \
65
+ "This implementation assumes SMAUGT_CRYPTO_BYTES + SMAUGT_PKSEED_BYTES to be 64"
66
+ #endif
67
+ sha3_512(extseed, seed, SMAUGT_CRYPTO_BYTES);
68
+
69
+ expand_s(&sk_tmp, extseed);
70
+
71
+ memcpy(&pk_tmp.seed, extseed + SMAUGT_CRYPTO_BYTES, SMAUGT_PKSEED_BYTES);
72
+ gen_pub_key(&pk_tmp, &sk_tmp, extseed);
73
+
74
+ memset(pk, 0, SMAUGT_PUBLICKEY_BYTES);
75
+ memset(sk, 0, SMAUGT_PKE_SECRETKEY_BYTES);
76
+ pack_enck(pk, &pk_tmp);
77
+ pack_deck(sk, &sk_tmp);
78
+ }
79
+
80
+ /*************************************************
81
+ * Name: indcpa_enc
82
+ *
83
+ * Description: Generates the ciphertext ctxt deterministically
84
+ * by encrypting the given message mu
85
+ * with the provided public key pk and the given randomness seed.
86
+ * Encryption function of the CPA-secure Module-Lizard public-key
87
+ * encryption scheme.
88
+ *
89
+ * Arguments: - uint8_t ctxt[SMAUGT_CIPHERTEXT_BYTES]: pointer to output
90
+ * ciphertext
91
+ * - const uint8_t pk[SMAUGT_PUBLICKEY_BYTES]: pointer to input
92
+ * public key
93
+ * - const uint8_t mu[SMAUGT_MSG_BYTES]: pointer to input plaintext
94
+ * message
95
+ * - const uint8_t seed[SMAUGT_DELTA_BYTES]: pointer to input seed
96
+ *
97
+ * Specification: Implements Algorithm 26, SMAUGT-T.PKE.Enc.
98
+ **************************************************/
99
+ void indcpa_enc(uint8_t ctxt[SMAUGT_CIPHERTEXT_BYTES],
100
+ const uint8_t pk[SMAUGT_PUBLICKEY_BYTES],
101
+ const uint8_t mu[SMAUGT_MSG_BYTES],
102
+ const uint8_t seed[SMAUGT_DELTA_BYTES]) {
103
+
104
+ uint8_t seed_r[SMAUGT_DELTA_BYTES] = {0};
105
+ public_key pk_tmp;
106
+ unpack_enck(&pk_tmp, pk);
107
+
108
+ // Compute a vector r = hwt(delta, H'(pk))
109
+ polyvec r;
110
+ memset(&r, 0, sizeof(polyvec));
111
+
112
+ if (seed == NULL)
113
+ { if (randombytes(seed_r, SMAUGT_DELTA_BYTES) != 0) return; }
114
+ else
115
+ cmov(seed_r, seed, SMAUGT_DELTA_BYTES, 1);
116
+ expand_r(&r, seed_r);
117
+
118
+ // Compute c1(x), c2(x)
119
+ ciphertext ctxt_tmp;
120
+ memset(&ctxt_tmp, 0, sizeof(ciphertext));
121
+ computeC1(&(ctxt_tmp.c1), pk_tmp.A, &r);
122
+ computeC2(&(ctxt_tmp.c2), mu, &pk_tmp.b, &r);
123
+
124
+ pack_ct(ctxt, &ctxt_tmp);
125
+ }
126
+
127
+ /*************************************************
128
+ * Name: indcpa_dec
129
+ *
130
+ * Description: Generates the plaintext message mu deterministically
131
+ * by decrypting the given ciphertext ctxt with the provided
132
+ * private key sk. Decryption function of the CPA-secure
133
+ * Module-Lizard public-key encryption scheme.
134
+ *
135
+ * Arguments: - uint8_t mu[SMAUGT_MSG_BYTES]: pointer to output plaintext
136
+ * message
137
+ * - const uint8_t sk[SMAUGT_PKE_SECRETKEY_BYTES]: pointer to input
138
+ * private key
139
+ * - const uint8_t ctxt[SMAUGT_CIPHERTEXT_BYTES]: pointer to input
140
+ * ciphertext
141
+ *
142
+ * Specification: Implements Algorithm 28, SMAUGT-T.PKE.Dec.
143
+ **************************************************/
144
+ void indcpa_dec(uint8_t mu[SMAUGT_MSG_BYTES],
145
+ const uint8_t sk[SMAUGT_PKE_SECRETKEY_BYTES],
146
+ const uint8_t ctxt[SMAUGT_CIPHERTEXT_BYTES]) {
147
+ poly delta;
148
+ polyvec c1;
149
+
150
+ secret_key sk_tmp;
151
+ memset(&sk_tmp, 0, sizeof(secret_key));
152
+ unpack_deck(&sk_tmp, sk);
153
+
154
+ ciphertext ctxt_tmp;
155
+ unpack_ct(&ctxt_tmp, ctxt);
156
+
157
+ unsigned int i, j;
158
+ c1 = ctxt_tmp.c1;
159
+ delta = ctxt_tmp.c2;
160
+ for (i = 0; i < SMAUGT_N; ++i)
161
+ delta.coeffs[i] <<= SMAUGT_MODULUS_16_LOG_P_PRIME;
162
+ for (i = 0; i < SMAUGT_K; ++i)
163
+ for (j = 0; j < SMAUGT_N; ++j)
164
+ c1.vec[i].coeffs[j] <<= SMAUGT_MODULUS_16_LOG_P;
165
+
166
+ // Compute delta = (delta + c1^T * s)
167
+ vec_vec_mult_add(&delta, &c1, &sk_tmp, SMAUGT_MODULUS_16_LOG_P);
168
+
169
+ #if SMAUGT_MODE == SMAUGT_MODET
170
+ d2_dcd(mu, &delta); // EDIT TiMER
171
+ #else
172
+ // Compute delta = 2/p * delta
173
+ for (i = 0; i < SMAUGT_N; ++i) {
174
+ delta.coeffs[i] += SMAUGT_DEC_ADD;
175
+ delta.coeffs[i] >>= SMAUGT_MODULUS_16_LOG_T;
176
+ delta.coeffs[i] &= 0x01;
177
+ }
178
+
179
+ // Set delta
180
+ memset(mu, 0, SMAUGT_MSG_BYTES);
181
+ for (i = 0; i < SMAUGT_MSG_BYTES; ++i) {
182
+ for (j = 0; j < 8; ++j) {
183
+ mu[i] ^= ((uint8_t)(delta.coeffs[8 * i + j]) << j);
184
+ }
185
+ }
186
+ #endif
187
+ }
@@ -0,0 +1,194 @@
1
+ /* kpqc-py: propagate OS entropy failures (2026-09-06). */
2
+ // SPDX-License-Identifier: MIT
3
+
4
+ #include "api.h"
5
+ #include "fips202.h"
6
+ #include "hash.h"
7
+ #include "indcpa.h"
8
+ #include "randombytes.h"
9
+ #include "verify.h"
10
+ #include <string.h>
11
+
12
+ /*************************************************
13
+ * Name: crypto_kem_keypair_internal
14
+ *
15
+ * Description: Generates a public key pk and a private key sk deterministically
16
+ * from the given randomness (i.e., d and seed)
17
+ * for the CCA-secure Module-Lizard key encapsulation mechanism.
18
+ *
19
+ * Arguments: - uint8_t *pk: pointer to output public key
20
+ * - uint8_t *sk: pointer to output private key
21
+ * - uint8_t *d: pointer to input d (of length
22
+ * SMAUGT_T_BYTES)
23
+ * - uint8_t *seed: pointer to input seed (of length
24
+ * SMAUGT_CRYPTO_BYTES)
25
+ *
26
+ * Return: 0 on success, 1 on failure
27
+ *
28
+ * Specification: Implements Algorithm 33, SMAUG-T.KEM.EncapInternal.
29
+ **************************************************/
30
+ int crypto_kem_keypair_internal(uint8_t *pk, uint8_t *sk,
31
+ uint8_t d[SMAUGT_T_BYTES],
32
+ uint8_t seed[SMAUGT_CRYPTO_BYTES]) {
33
+ int ret = 0;
34
+ indcpa_keypair(pk, sk, seed);
35
+ memcpy(sk + SMAUGT_PKE_SECRETKEY_BYTES, d, SMAUGT_T_BYTES);
36
+ memcpy(sk + SMAUGT_PKE_SECRETKEY_BYTES + SMAUGT_T_BYTES, pk,
37
+ SMAUGT_PUBLICKEY_BYTES);
38
+
39
+ return ret;
40
+ }
41
+
42
+ /*************************************************
43
+ * Name: crypto_kem_keypair
44
+ *
45
+ * Description: Generates a public key pk and a private key sk probabilistically
46
+ * by internally sampling the required randomness (i.e., d and
47
+ * seed) for the CCA-secure Module-Lizard key encapsulation mechanism.
48
+ *
49
+ * Arguments: - uint8_t *pk: pointer to output public key
50
+ * - uint8_t *sk: pointer to output private key
51
+ *
52
+ * Return: 0 on success, 1 on failure
53
+ *
54
+ * Specification: Implements Algorithm 30, SMAUG-T.KEM.KeyGen.
55
+ **************************************************/
56
+ int crypto_kem_keypair(uint8_t *pk, uint8_t *sk) {
57
+ int ret = 0;
58
+ uint8_t d[SMAUGT_T_BYTES] = {0};
59
+ uint8_t seed[SMAUGT_CRYPTO_BYTES] = {0};
60
+
61
+ if (randombytes(d, SMAUGT_T_BYTES) != 0) return -1;
62
+ if (randombytes(seed, SMAUGT_CRYPTO_BYTES) != 0) return -1;
63
+
64
+ ret = crypto_kem_keypair_internal(pk, sk, d, seed);
65
+
66
+ return ret;
67
+ }
68
+
69
+ /*************************************************
70
+ * Name: crypto_kem_enc_internal
71
+ *
72
+ * Description: Generates a shared secret ss and an associated ciphertext ctxt
73
+ * deterministically for the given message mu using the provided public key pk.
74
+ *
75
+ * Arguments: - uint8_t *ctxt: pointer to output ciphertext
76
+ * - uint8_t *ss: pointer to output shared secret
77
+ * (of length SMAUGT_CRYPTO_BYTES)
78
+ * - uint8_t *pk: pointer to input public key
79
+ * - uint8_t *mu: pointer to input message (of length
80
+ * SMAUGT_DELTA_BYTES)
81
+ *
82
+ * Return: 0 on success, 1 on failure
83
+ *
84
+ * Specification: Implements Algorithm 34, SMAUG-T.KEM.EncapInternal.
85
+ **************************************************/
86
+ int crypto_kem_enc_internal(uint8_t *ctxt, uint8_t *ss, const uint8_t *pk,
87
+ const uint8_t *mu) {
88
+ int ret = 0;
89
+ uint8_t seed_r[SMAUGT_DELTA_BYTES + SMAUGT_CRYPTO_BYTES] = {0};
90
+ hash_h(seed_r, pk, SMAUGT_PUBLICKEY_BYTES);
91
+ hash_g(seed_r, SMAUGT_DELTA_BYTES + SMAUGT_CRYPTO_BYTES, mu,
92
+ SMAUGT_MSG_BYTES, seed_r, SHA3_256_HashSize);
93
+
94
+ memset(ss, 0, SMAUGT_CRYPTO_BYTES);
95
+ indcpa_enc(ctxt, pk, mu, seed_r);
96
+ cmov(ss, seed_r + SMAUGT_DELTA_BYTES, SMAUGT_CRYPTO_BYTES, 1);
97
+ return ret;
98
+ }
99
+
100
+ /*************************************************
101
+ * Name: crypto_kem_enc
102
+ *
103
+ * Description: Generates a shared secret ss and an associated ciphertext ctxt
104
+ * probabilistically by internally sampling the required randomness (i.e., mu)
105
+ * for the given public key.
106
+ *
107
+ * Arguments: - uint8_t *ctxt: pointer to output ciphertext
108
+ * - uint8_t *ss: pointer to output shared secret
109
+ * (of length SMAUGT_CRYPTO_BYTES)
110
+ * - uint8_t *pk: pointer to input public key
111
+ *
112
+ * Return: 0 on success, 1 on failure
113
+ *
114
+ * Specification: Implements Algorithm 31, SMAUG-T.KEM.Encap.
115
+ **************************************************/
116
+ int crypto_kem_enc(uint8_t *ctxt, uint8_t *ss, const uint8_t *pk) {
117
+ int ret = 0;
118
+ uint8_t mu[SMAUGT_MSG_BYTES] = {0}; // shared secret and seed
119
+ if (randombytes(mu, SMAUGT_MSG_BYTES) != 0) return -1;
120
+
121
+ ret = crypto_kem_enc_internal(ctxt, ss, pk, mu);
122
+
123
+ return ret;
124
+ }
125
+
126
+ /*************************************************
127
+ * Name: crypto_kem_dec_internal
128
+ *
129
+ * Description: Produces a shared secret ss deterministically
130
+ * for the given ciphertext ctxt using the provided private key sk.
131
+ *
132
+ * Arguments: - uint8_t *ss: pointer to output shared secret
133
+ * (of length SMAUGT_CRYPTO_BYTES)
134
+ * - uint8_t *sk: pointer to input private key
135
+ * - uint8_t *ctxt: pointer to input ciphertext
136
+ *
137
+ * Return: 0 on success, 1 on failure
138
+ *
139
+ * Specification: Implements Algorithm 35, SMAUG-T.KEM.DecapInternal.
140
+ **************************************************/
141
+ int crypto_kem_dec_internal(uint8_t *ss, const uint8_t *ctxt,
142
+ const uint8_t *sk) {
143
+ int ret = 0;
144
+ uint8_t mu[SMAUGT_MSG_BYTES] = {0};
145
+ uint8_t buf[SMAUGT_DELTA_BYTES + SMAUGT_CRYPTO_BYTES] = {
146
+ 0}; // shared secret and seed
147
+ uint8_t buf_tmp[SMAUGT_DELTA_BYTES + SMAUGT_CRYPTO_BYTES] = {0};
148
+ uint8_t hash_res[SHA3_256_HashSize] = {0};
149
+ const uint8_t *pk = sk + SMAUGT_PKE_SECRETKEY_BYTES + SMAUGT_T_BYTES;
150
+
151
+ indcpa_dec(mu, sk, ctxt);
152
+ hash_h(hash_res, pk, SMAUGT_PUBLICKEY_BYTES);
153
+ hash_g(buf, SMAUGT_DELTA_BYTES + SMAUGT_CRYPTO_BYTES, mu, SMAUGT_MSG_BYTES,
154
+ hash_res, SHA3_256_HashSize);
155
+
156
+ uint8_t ctxt_temp[SMAUGT_CIPHERTEXT_BYTES] = {0};
157
+ indcpa_enc(ctxt_temp, pk, mu, buf);
158
+
159
+ int fail = verify(ctxt, ctxt_temp, SMAUGT_CIPHERTEXT_BYTES);
160
+
161
+ hash_h(hash_res, ctxt, SMAUGT_CIPHERTEXT_BYTES);
162
+ hash_g(buf_tmp, SMAUGT_DELTA_BYTES + SMAUGT_CRYPTO_BYTES,
163
+ sk + SMAUGT_PKE_SECRETKEY_BYTES, SMAUGT_T_BYTES, hash_res,
164
+ SHA3_256_HashSize);
165
+
166
+ memset(ss, 0, SMAUGT_CRYPTO_BYTES);
167
+ cmov(buf + SMAUGT_DELTA_BYTES, buf_tmp + SMAUGT_DELTA_BYTES,
168
+ SMAUGT_CRYPTO_BYTES, fail);
169
+ cmov(ss, buf + SMAUGT_DELTA_BYTES, SMAUGT_CRYPTO_BYTES, 1);
170
+
171
+ return ret;
172
+ }
173
+
174
+ /*************************************************
175
+ * Name: crypto_kem_dec
176
+ *
177
+ * Description: Produces a shared secret ss deterministically
178
+ * for the given ciphertext ctxt using the provided private key sk.
179
+ *
180
+ * Arguments: - uint8_t *ss: pointer to output shared secret (of length
181
+ * SMAUGT_CRYPTO_BYTES). On failure, ss will contain a
182
+ * pseudo-random value.
183
+ * - uint8_t *sk: pointer to input private key
184
+ * - uint8_t *ctxt: pointer to input ciphertext
185
+ *
186
+ * Return: 0 on success, 1 on failure
187
+ *
188
+ * Specification: Implements Algorithm 32, SMAUG-T.KEM.Decap.
189
+ **************************************************/
190
+ int crypto_kem_dec(uint8_t *ss, const uint8_t *ctxt, const uint8_t *sk) {
191
+ int ret = 0;
192
+ ret = crypto_kem_dec_internal(ss, ctxt, sk);
193
+ return ret;
194
+ }
@@ -0,0 +1,102 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ #include "key.h"
4
+ #include "dg.h"
5
+ #include "fips202.h"
6
+ #include "hwt.h"
7
+ #include "pack.h"
8
+ #include "poly.h"
9
+
10
+ #include <string.h>
11
+
12
+ /*************************************************
13
+ * Name: expand_A
14
+ *
15
+ * Description: Deterministically generate public matrix A from a seed.
16
+ * Entries of the A are polynomials that look uniformly random.
17
+ *
18
+ * Arguments: - polyvec A[SMAUGT_K]: pointer to output matrix A
19
+ * - const uint8_t seed[SMAUGT_PKSEED_BYTES]: pointer to input seed
20
+ *
21
+ * Specification: Implements Algorithm 1, ExpandA.
22
+ **************************************************/
23
+ void expand_A(polyvec A[SMAUGT_K], const uint8_t seed[SMAUGT_PKSEED_BYTES]) {
24
+ unsigned int i, j;
25
+ uint8_t buf[SMAUGT_PKPOLY_BYTES] = {0}, extseed[SMAUGT_PKSEED_BYTES + 2];
26
+ memcpy(extseed, seed, SMAUGT_PKSEED_BYTES);
27
+ for (i = 0; i < SMAUGT_K; i++) {
28
+ for (j = 0; j < SMAUGT_K; j++) {
29
+ extseed[32] = i;
30
+ extseed[33] = j;
31
+ shake128(buf, SMAUGT_PKPOLY_BYTES, extseed,
32
+ SMAUGT_PKSEED_BYTES + 2);
33
+ unpack_ring(&A[i].vec[j], buf);
34
+ }
35
+ }
36
+ }
37
+
38
+ /*************************************************
39
+ * Name: expand_b
40
+ *
41
+ * Description: Generate public vector b from a matrix A, vector s and noise e.
42
+ * Random noise e is generated by Gaussian sampling.
43
+ *
44
+ * Arguments: - polyvec *b: pointer to output vector b
45
+ * - const polyvec A[SMAUGT_K]: pointer to input matrix A
46
+ * - const polyvec *s: pointer to input vector s
47
+ * - const uint8_t e_seed[SMAUGT_CRYPTO_BYTES]: pointer to input
48
+ * seed of error
49
+ **************************************************/
50
+ void expand_b(polyvec *b, const polyvec A[SMAUGT_K], const polyvec *s,
51
+ const uint8_t e_seed[SMAUGT_CRYPTO_BYTES]) {
52
+ // b = e
53
+ d_gaussian(b, e_seed);
54
+
55
+ // b = -a * s + e
56
+ matrix_vec_mult_sub(b, A, s);
57
+ }
58
+
59
+ /*************************************************
60
+ * Name: expand_s
61
+ *
62
+ * Description: Generate a vector of secret sparse polynomial s(x) from a seed.
63
+ *
64
+ * Arguments: - secret_key *sk: pointer to output private key
65
+ * - const uint8_t seed[SMAUGT_CRYPTO_BYTES]: pointer to input seed
66
+ * of s(x)
67
+ *
68
+ * Specification: Implements Algorithm 2, ExpandS.
69
+ **************************************************/
70
+ void expand_s(secret_key *sk, const uint8_t seed[SMAUGT_CRYPTO_BYTES]) {
71
+ unsigned int i, j;
72
+ uint8_t extseed[SMAUGT_CRYPTO_BYTES + 2] = {0};
73
+ memcpy(extseed, seed, SMAUGT_CRYPTO_BYTES);
74
+
75
+ for (i = 0; i < SMAUGT_K; ++i) {
76
+ extseed[SMAUGT_CRYPTO_BYTES] = i * SMAUGT_K;
77
+ j = 0;
78
+ do {
79
+ extseed[SMAUGT_CRYPTO_BYTES + 1] = j;
80
+ j += 1;
81
+ } while (hwt(sk->vec[i].coeffs, extseed));
82
+ }
83
+ }
84
+
85
+ /*************************************************
86
+ * Name: genPubkey
87
+ *
88
+ * Description: Generate public key correspending to private key.
89
+ *
90
+ * Arguments: - public_key *pk: pointer to output public key
91
+ * - const secret_key *sk: pointer to input private key
92
+ * - const uint8_t err_seed[SMAUGT_CRYPTO_BYTES]: pointer to input
93
+ * seed of error
94
+ **************************************************/
95
+ void gen_pub_key(public_key *pk, const secret_key *sk,
96
+ const uint8_t err_seed[SMAUGT_CRYPTO_BYTES]) {
97
+ expand_A(pk->A, pk->seed);
98
+
99
+ memset(&(pk->b), 0, sizeof(uint16_t) * SMAUGT_N * SMAUGT_K);
100
+ // Initialized at addGaussian, Unnecessary
101
+ expand_b(&(pk->b), pk->A, sk, err_seed);
102
+ }