longfellow 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 (289) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +10 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +152 -0
  5. data/ext/longfellow/CMakeLists.txt +76 -0
  6. data/ext/longfellow/extconf.rb +77 -0
  7. data/lib/longfellow/attribute.rb +65 -0
  8. data/lib/longfellow/c.rb +105 -0
  9. data/lib/longfellow/errors.rb +78 -0
  10. data/lib/longfellow/version.rb +5 -0
  11. data/lib/longfellow/zk_spec.rb +40 -0
  12. data/lib/longfellow.rb +162 -0
  13. data/sig/longfellow.rbs +74 -0
  14. data/vendor/longfellow-zk/LICENSE +203 -0
  15. data/vendor/longfellow-zk/lib/algebra/blas.h +121 -0
  16. data/vendor/longfellow-zk/lib/algebra/bogorng.h +68 -0
  17. data/vendor/longfellow-zk/lib/algebra/compare.h +40 -0
  18. data/vendor/longfellow-zk/lib/algebra/convolution.h +219 -0
  19. data/vendor/longfellow-zk/lib/algebra/crt.cc +42 -0
  20. data/vendor/longfellow-zk/lib/algebra/crt.h +299 -0
  21. data/vendor/longfellow-zk/lib/algebra/crt_convolution.h +114 -0
  22. data/vendor/longfellow-zk/lib/algebra/crt_test.cc +371 -0
  23. data/vendor/longfellow-zk/lib/algebra/fft.h +104 -0
  24. data/vendor/longfellow-zk/lib/algebra/fft_interpolation.h +304 -0
  25. data/vendor/longfellow-zk/lib/algebra/fft_interpolation_test.cc +168 -0
  26. data/vendor/longfellow-zk/lib/algebra/fft_test.cc +257 -0
  27. data/vendor/longfellow-zk/lib/algebra/fp.h +59 -0
  28. data/vendor/longfellow-zk/lib/algebra/fp2.h +240 -0
  29. data/vendor/longfellow-zk/lib/algebra/fp24.h +342 -0
  30. data/vendor/longfellow-zk/lib/algebra/fp24_6.h +305 -0
  31. data/vendor/longfellow-zk/lib/algebra/fp24_6_test.cc +197 -0
  32. data/vendor/longfellow-zk/lib/algebra/fp2_test.cc +280 -0
  33. data/vendor/longfellow-zk/lib/algebra/fp_generic.h +533 -0
  34. data/vendor/longfellow-zk/lib/algebra/fp_p128.h +91 -0
  35. data/vendor/longfellow-zk/lib/algebra/fp_p256.h +68 -0
  36. data/vendor/longfellow-zk/lib/algebra/fp_p256k1.h +123 -0
  37. data/vendor/longfellow-zk/lib/algebra/fp_p384.h +65 -0
  38. data/vendor/longfellow-zk/lib/algebra/fp_p521.h +62 -0
  39. data/vendor/longfellow-zk/lib/algebra/fp_test.cc +522 -0
  40. data/vendor/longfellow-zk/lib/algebra/hash.h +39 -0
  41. data/vendor/longfellow-zk/lib/algebra/interpolation.h +117 -0
  42. data/vendor/longfellow-zk/lib/algebra/interpolation_test.cc +74 -0
  43. data/vendor/longfellow-zk/lib/algebra/limb.h +153 -0
  44. data/vendor/longfellow-zk/lib/algebra/limb_test.cc +75 -0
  45. data/vendor/longfellow-zk/lib/algebra/nat.cc +32 -0
  46. data/vendor/longfellow-zk/lib/algebra/nat.h +212 -0
  47. data/vendor/longfellow-zk/lib/algebra/nat_test.cc +183 -0
  48. data/vendor/longfellow-zk/lib/algebra/nussbaumer.h +400 -0
  49. data/vendor/longfellow-zk/lib/algebra/nussbaumer_test.cc +138 -0
  50. data/vendor/longfellow-zk/lib/algebra/nussbaumerfp2_test.cc +139 -0
  51. data/vendor/longfellow-zk/lib/algebra/permutations.h +79 -0
  52. data/vendor/longfellow-zk/lib/algebra/poly.h +240 -0
  53. data/vendor/longfellow-zk/lib/algebra/poly_test.cc +123 -0
  54. data/vendor/longfellow-zk/lib/algebra/reed_solomon.h +150 -0
  55. data/vendor/longfellow-zk/lib/algebra/reed_solomon_extension.h +108 -0
  56. data/vendor/longfellow-zk/lib/algebra/reed_solomon_extension_test.cc +76 -0
  57. data/vendor/longfellow-zk/lib/algebra/reed_solomon_test.cc +473 -0
  58. data/vendor/longfellow-zk/lib/algebra/rfft.h +400 -0
  59. data/vendor/longfellow-zk/lib/algebra/rfft_test.cc +102 -0
  60. data/vendor/longfellow-zk/lib/algebra/static_string.h +29 -0
  61. data/vendor/longfellow-zk/lib/algebra/sysdep.h +495 -0
  62. data/vendor/longfellow-zk/lib/algebra/sysdep_test.cc +41 -0
  63. data/vendor/longfellow-zk/lib/algebra/twiddle.h +59 -0
  64. data/vendor/longfellow-zk/lib/algebra/utility.h +86 -0
  65. data/vendor/longfellow-zk/lib/algebra/utility_test.cc +86 -0
  66. data/vendor/longfellow-zk/lib/arrays/affine.h +56 -0
  67. data/vendor/longfellow-zk/lib/arrays/affine_test.cc +220 -0
  68. data/vendor/longfellow-zk/lib/arrays/dense.h +210 -0
  69. data/vendor/longfellow-zk/lib/arrays/eq.h +75 -0
  70. data/vendor/longfellow-zk/lib/arrays/eqs.h +137 -0
  71. data/vendor/longfellow-zk/lib/arrays/eqs_test.cc +151 -0
  72. data/vendor/longfellow-zk/lib/arrays/sparse.h +192 -0
  73. data/vendor/longfellow-zk/lib/cbor/host_decoder.h +323 -0
  74. data/vendor/longfellow-zk/lib/cbor/host_decoder_test.cc +541 -0
  75. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor.h +594 -0
  76. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_byte_decoder.h +150 -0
  77. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_byte_decoder_test.cc +147 -0
  78. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_constants.h +27 -0
  79. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_pluck.h +110 -0
  80. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_pluck_test.cc +55 -0
  81. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_test.cc +174 -0
  82. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_testing.h +98 -0
  83. data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_witness.h +312 -0
  84. data/vendor/longfellow-zk/lib/circuits/cbor_parser/mso2_test.cc +662 -0
  85. data/vendor/longfellow-zk/lib/circuits/cbor_parser/mso_test.cc +485 -0
  86. data/vendor/longfellow-zk/lib/circuits/cbor_parser/scan.h +104 -0
  87. data/vendor/longfellow-zk/lib/circuits/cbor_parser/scan_test.cc +137 -0
  88. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor.h +640 -0
  89. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_byte_decoder.h +150 -0
  90. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_byte_decoder_test.cc +147 -0
  91. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_constants.h +27 -0
  92. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_testing.h +99 -0
  93. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_witness.h +319 -0
  94. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/lexer_test.cc +120 -0
  95. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/mdoc_examples_test.cc +89 -0
  96. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/parser_circuit_test.cc +506 -0
  97. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/parser_size_test.cc +79 -0
  98. data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/parser_test.cc +473 -0
  99. data/vendor/longfellow-zk/lib/circuits/compiler/canonicalization_test.cc +185 -0
  100. data/vendor/longfellow-zk/lib/circuits/compiler/circuit_dump.h +65 -0
  101. data/vendor/longfellow-zk/lib/circuits/compiler/compiler.h +471 -0
  102. data/vendor/longfellow-zk/lib/circuits/compiler/compiler_test.cc +110 -0
  103. data/vendor/longfellow-zk/lib/circuits/compiler/node.h +176 -0
  104. data/vendor/longfellow-zk/lib/circuits/compiler/pdqhash.h +127 -0
  105. data/vendor/longfellow-zk/lib/circuits/compiler/schedule.h +435 -0
  106. data/vendor/longfellow-zk/lib/circuits/ecdsa/verify_circuit.h +371 -0
  107. data/vendor/longfellow-zk/lib/circuits/ecdsa/verify_external_test.cc +246 -0
  108. data/vendor/longfellow-zk/lib/circuits/ecdsa/verify_test.cc +587 -0
  109. data/vendor/longfellow-zk/lib/circuits/ecdsa/verify_witness.h +201 -0
  110. data/vendor/longfellow-zk/lib/circuits/logic/bit_adder.h +140 -0
  111. data/vendor/longfellow-zk/lib/circuits/logic/bit_adder_test.cc +64 -0
  112. data/vendor/longfellow-zk/lib/circuits/logic/bit_plucker.h +247 -0
  113. data/vendor/longfellow-zk/lib/circuits/logic/bit_plucker_constants.h +35 -0
  114. data/vendor/longfellow-zk/lib/circuits/logic/bit_plucker_encoder.h +72 -0
  115. data/vendor/longfellow-zk/lib/circuits/logic/bit_plucker_test.cc +183 -0
  116. data/vendor/longfellow-zk/lib/circuits/logic/compiler_backend.h +62 -0
  117. data/vendor/longfellow-zk/lib/circuits/logic/counter.h +171 -0
  118. data/vendor/longfellow-zk/lib/circuits/logic/counter_test.cc +102 -0
  119. data/vendor/longfellow-zk/lib/circuits/logic/evaluation_backend.h +94 -0
  120. data/vendor/longfellow-zk/lib/circuits/logic/logic.h +1232 -0
  121. data/vendor/longfellow-zk/lib/circuits/logic/logic_circuit_test.cc +310 -0
  122. data/vendor/longfellow-zk/lib/circuits/logic/logic_test.cc +521 -0
  123. data/vendor/longfellow-zk/lib/circuits/logic/memcmp.h +68 -0
  124. data/vendor/longfellow-zk/lib/circuits/logic/memcmp_test.cc +148 -0
  125. data/vendor/longfellow-zk/lib/circuits/logic/polynomial.h +94 -0
  126. data/vendor/longfellow-zk/lib/circuits/logic/polynomial_test.cc +62 -0
  127. data/vendor/longfellow-zk/lib/circuits/logic/routing.h +445 -0
  128. data/vendor/longfellow-zk/lib/circuits/logic/routing_test.cc +241 -0
  129. data/vendor/longfellow-zk/lib/circuits/logic/unary.h +55 -0
  130. data/vendor/longfellow-zk/lib/circuits/logic/unary_plucker.h +77 -0
  131. data/vendor/longfellow-zk/lib/circuits/logic/unary_plucker_constants.h +37 -0
  132. data/vendor/longfellow-zk/lib/circuits/logic/unary_plucker_test.cc +53 -0
  133. data/vendor/longfellow-zk/lib/circuits/logic/unary_size_test.cc +69 -0
  134. data/vendor/longfellow-zk/lib/circuits/logic/unary_test.cc +62 -0
  135. data/vendor/longfellow-zk/lib/circuits/mac/mac_circuit.h +193 -0
  136. data/vendor/longfellow-zk/lib/circuits/mac/mac_circuit_test.cc +223 -0
  137. data/vendor/longfellow-zk/lib/circuits/mac/mac_reference.h +72 -0
  138. data/vendor/longfellow-zk/lib/circuits/mac/mac_witness.h +94 -0
  139. data/vendor/longfellow-zk/lib/circuits/mdoc/circuit_maker.cc +242 -0
  140. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_attribute_ids.h +311 -0
  141. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_attribute_test.cc +64 -0
  142. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_circuit_id.cc +85 -0
  143. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_constants.h +85 -0
  144. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_decompress.cc +41 -0
  145. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_decompress.h +27 -0
  146. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_examples.h +5232 -0
  147. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_generate_circuit.cc +199 -0
  148. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_hash.h +554 -0
  149. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_signature.h +143 -0
  150. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_signature_test.cc +444 -0
  151. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_test_attributes.h +157 -0
  152. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_witness.h +863 -0
  153. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_zk.cc +693 -0
  154. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_zk.h +216 -0
  155. data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_zk_test.cc +724 -0
  156. data/vendor/longfellow-zk/lib/circuits/mdoc/zk_spec.cc +100 -0
  157. data/vendor/longfellow-zk/lib/circuits/mdoc/zk_spec_test.cc +155 -0
  158. data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_circuit.h +330 -0
  159. data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_circuit_test.cc +607 -0
  160. data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_io.h +26 -0
  161. data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_witness.cc +163 -0
  162. data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_witness.h +47 -0
  163. data/vendor/longfellow-zk/lib/circuits/sha/sha256_constants.cc +34 -0
  164. data/vendor/longfellow-zk/lib/circuits/sha/sha256_constants.h +27 -0
  165. data/vendor/longfellow-zk/lib/circuits/sha/sha256_test_values.h +389 -0
  166. data/vendor/longfellow-zk/lib/circuits/tests/anoncred/ptrcred.h +171 -0
  167. data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small.h +218 -0
  168. data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small_examples.h +118 -0
  169. data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small_io.h +25 -0
  170. data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small_test.cc +208 -0
  171. data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small_witness.h +130 -0
  172. data/vendor/longfellow-zk/lib/circuits/tests/base64/decode.h +508 -0
  173. data/vendor/longfellow-zk/lib/circuits/tests/base64/decode_circuit_test.cc +95 -0
  174. data/vendor/longfellow-zk/lib/circuits/tests/base64/decode_test.cc +119 -0
  175. data/vendor/longfellow-zk/lib/circuits/tests/base64/decode_util.cc +47 -0
  176. data/vendor/longfellow-zk/lib/circuits/tests/base64/decode_util.h +29 -0
  177. data/vendor/longfellow-zk/lib/circuits/tests/ec/pk_circuit.h +231 -0
  178. data/vendor/longfellow-zk/lib/circuits/tests/ec/pk_circuit_test.cc +428 -0
  179. data/vendor/longfellow-zk/lib/circuits/tests/ec/pk_witness.h +102 -0
  180. data/vendor/longfellow-zk/lib/circuits/tests/jwt/jwt.h +190 -0
  181. data/vendor/longfellow-zk/lib/circuits/tests/jwt/jwt_constants.h +26 -0
  182. data/vendor/longfellow-zk/lib/circuits/tests/jwt/jwt_test.cc +559 -0
  183. data/vendor/longfellow-zk/lib/circuits/tests/jwt/jwt_witness.h +315 -0
  184. data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_1f.h +411 -0
  185. data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_1f_io.h +32 -0
  186. data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_1f_test.cc +364 -0
  187. data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_1f_witness.h +278 -0
  188. data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_revocation.h +146 -0
  189. data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_revocation_constants.h +25 -0
  190. data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_revocation_test.cc +315 -0
  191. data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_revocation_witness.h +136 -0
  192. data/vendor/longfellow-zk/lib/circuits/tests/pq/bitaddr/bitaddr.h +250 -0
  193. data/vendor/longfellow-zk/lib/circuits/tests/pq/bitaddr/bitaddr_test.cc +333 -0
  194. data/vendor/longfellow-zk/lib/circuits/tests/pq/bitaddr/bitaddr_witness.h +152 -0
  195. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44.h +903 -0
  196. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_circuit_test.cc +274 -0
  197. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_eval_test.cc +440 -0
  198. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_examples.cc +8851 -0
  199. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_examples.h +93 -0
  200. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_types.cc +24 -0
  201. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_types.h +118 -0
  202. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_witness.h +453 -0
  203. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_witness_test.cc +49 -0
  204. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref.cc +458 -0
  205. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref.h +150 -0
  206. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref_test.cc +398 -0
  207. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref_test_vectors.inc +3618 -0
  208. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref_test_vectors_pkdecode.inc +689 -0
  209. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref_test_vectors_sigdecode.inc +1501 -0
  210. data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/sigdecode_test_vectors.inc +540 -0
  211. data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_circuit.h +394 -0
  212. data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_circuit_test.cc +577 -0
  213. data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_constants.h +90 -0
  214. data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_witness.cc +174 -0
  215. data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_witness.h +140 -0
  216. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_circuit.h +351 -0
  217. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_circuit_test.cc +466 -0
  218. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_reference.cc +207 -0
  219. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_reference.h +59 -0
  220. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_reference_test.cc +153 -0
  221. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_round_constants.cc +39 -0
  222. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_round_constants.h +29 -0
  223. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_slicing.h +31 -0
  224. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_witness.cc +83 -0
  225. data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_witness.h +72 -0
  226. data/vendor/longfellow-zk/lib/circuits/tests/sha3/shake_test_vectors.h +477 -0
  227. data/vendor/longfellow-zk/lib/ec/elliptic_curve.h +596 -0
  228. data/vendor/longfellow-zk/lib/ec/elliptic_curve_test.cc +548 -0
  229. data/vendor/longfellow-zk/lib/ec/p256.cc +36 -0
  230. data/vendor/longfellow-zk/lib/ec/p256.h +60 -0
  231. data/vendor/longfellow-zk/lib/ec/p256k1.cc +34 -0
  232. data/vendor/longfellow-zk/lib/ec/p256k1.h +60 -0
  233. data/vendor/longfellow-zk/lib/gf2k/gf2_128.h +503 -0
  234. data/vendor/longfellow-zk/lib/gf2k/gf2_128_bench.cc +48 -0
  235. data/vendor/longfellow-zk/lib/gf2k/gf2_128_test.cc +416 -0
  236. data/vendor/longfellow-zk/lib/gf2k/gf2poly.h +74 -0
  237. data/vendor/longfellow-zk/lib/gf2k/lch14.h +242 -0
  238. data/vendor/longfellow-zk/lib/gf2k/lch14_bench.cc +75 -0
  239. data/vendor/longfellow-zk/lib/gf2k/lch14_reed_solomon.h +127 -0
  240. data/vendor/longfellow-zk/lib/gf2k/lch14_reed_solomon_test.cc +110 -0
  241. data/vendor/longfellow-zk/lib/gf2k/lch14_test.cc +246 -0
  242. data/vendor/longfellow-zk/lib/gf2k/sysdep.h +329 -0
  243. data/vendor/longfellow-zk/lib/ligero/ligero_param.h +449 -0
  244. data/vendor/longfellow-zk/lib/ligero/ligero_prover.h +354 -0
  245. data/vendor/longfellow-zk/lib/ligero/ligero_test.cc +136 -0
  246. data/vendor/longfellow-zk/lib/ligero/ligero_transcript.h +67 -0
  247. data/vendor/longfellow-zk/lib/ligero/ligero_verifier.h +272 -0
  248. data/vendor/longfellow-zk/lib/merkle/merkle_commitment.h +104 -0
  249. data/vendor/longfellow-zk/lib/merkle/merkle_tree.h +216 -0
  250. data/vendor/longfellow-zk/lib/merkle/merkle_tree_test.cc +240 -0
  251. data/vendor/longfellow-zk/lib/proto/circuit.h +354 -0
  252. data/vendor/longfellow-zk/lib/proto/circuit_test.cc +202 -0
  253. data/vendor/longfellow-zk/lib/random/random.h +119 -0
  254. data/vendor/longfellow-zk/lib/random/random_test.cc +189 -0
  255. data/vendor/longfellow-zk/lib/random/secure_random_engine.h +37 -0
  256. data/vendor/longfellow-zk/lib/random/transcript.h +193 -0
  257. data/vendor/longfellow-zk/lib/random/transcript_test.cc +344 -0
  258. data/vendor/longfellow-zk/lib/sumcheck/circuit.h +148 -0
  259. data/vendor/longfellow-zk/lib/sumcheck/circuit_id.h +71 -0
  260. data/vendor/longfellow-zk/lib/sumcheck/equad.h +126 -0
  261. data/vendor/longfellow-zk/lib/sumcheck/hquad.h +115 -0
  262. data/vendor/longfellow-zk/lib/sumcheck/prover.h +59 -0
  263. data/vendor/longfellow-zk/lib/sumcheck/prover_layers.h +362 -0
  264. data/vendor/longfellow-zk/lib/sumcheck/quad.h +227 -0
  265. data/vendor/longfellow-zk/lib/sumcheck/quad_builder.h +211 -0
  266. data/vendor/longfellow-zk/lib/sumcheck/quad_test.cc +169 -0
  267. data/vendor/longfellow-zk/lib/sumcheck/sumcheck_test.cc +324 -0
  268. data/vendor/longfellow-zk/lib/sumcheck/testing.h +69 -0
  269. data/vendor/longfellow-zk/lib/sumcheck/transcript_sumcheck.h +85 -0
  270. data/vendor/longfellow-zk/lib/sumcheck/verifier.h +84 -0
  271. data/vendor/longfellow-zk/lib/sumcheck/verifier_layers.h +221 -0
  272. data/vendor/longfellow-zk/lib/testing/test_main.cc +50 -0
  273. data/vendor/longfellow-zk/lib/util/ceildiv.h +164 -0
  274. data/vendor/longfellow-zk/lib/util/ceildiv_test.cc +152 -0
  275. data/vendor/longfellow-zk/lib/util/crc64.h +45 -0
  276. data/vendor/longfellow-zk/lib/util/crypto.cc +39 -0
  277. data/vendor/longfellow-zk/lib/util/crypto.h +108 -0
  278. data/vendor/longfellow-zk/lib/util/log.cc +110 -0
  279. data/vendor/longfellow-zk/lib/util/log.h +33 -0
  280. data/vendor/longfellow-zk/lib/util/panic.h +40 -0
  281. data/vendor/longfellow-zk/lib/util/readbuffer.h +67 -0
  282. data/vendor/longfellow-zk/lib/util/serialization.h +54 -0
  283. data/vendor/longfellow-zk/lib/zk/zk_common.h +455 -0
  284. data/vendor/longfellow-zk/lib/zk/zk_proof.h +378 -0
  285. data/vendor/longfellow-zk/lib/zk/zk_prover.h +202 -0
  286. data/vendor/longfellow-zk/lib/zk/zk_test.cc +340 -0
  287. data/vendor/longfellow-zk/lib/zk/zk_testing.h +154 -0
  288. data/vendor/longfellow-zk/lib/zk/zk_verifier.h +109 -0
  289. metadata +347 -0
@@ -0,0 +1,49 @@
1
+ // Copyright 2026 Google LLC.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "circuits/tests/pq/ml_dsa/ml_dsa_44_witness.h"
16
+
17
+ #include <cstdint>
18
+
19
+ #include "circuits/tests/pq/ml_dsa/ml_dsa_44_types.h"
20
+ #include "gtest/gtest.h"
21
+
22
+ namespace proofs {
23
+ namespace {
24
+
25
+ TEST(MlDsa44WitnessTest, SymmetricReduce) {
26
+ // Case 1: delta < Q/2, positive
27
+ EXPECT_EQ(ml_dsa_44_witness::SymmetricReduce(100), 100);
28
+
29
+ // Case 2: delta = 0
30
+ EXPECT_EQ(ml_dsa_44_witness::SymmetricReduce(0), 0);
31
+
32
+ // Case 3: delta > Q/2 (e.g. Q-1)
33
+ // This triggers the delta -= Q branch
34
+ int64_t q = static_cast<int64_t>(ml_dsa::Q);
35
+ EXPECT_EQ(ml_dsa_44_witness::SymmetricReduce(q - 1), -1);
36
+
37
+ // Case 4: delta near Q/2
38
+ EXPECT_EQ(ml_dsa_44_witness::SymmetricReduce(q / 2), q / 2);
39
+ EXPECT_EQ(ml_dsa_44_witness::SymmetricReduce(q / 2 + 1), q / 2 + 1 - q);
40
+
41
+ // Case 5: delta is negative but > -Q/2
42
+ EXPECT_EQ(ml_dsa_44_witness::SymmetricReduce(-100), -100);
43
+
44
+ // Case 6: delta is exactly -Q/2
45
+ EXPECT_EQ(ml_dsa_44_witness::SymmetricReduce(-q / 2), -q / 2);
46
+ }
47
+
48
+ } // namespace
49
+ } // namespace proofs
@@ -0,0 +1,458 @@
1
+ // Copyright 2026 Google LLC.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "circuits/tests/pq/ml_dsa/ml_dsa_ref.h"
16
+
17
+ #include <algorithm>
18
+ #include <array>
19
+ #include <cstddef>
20
+ #include <cstdint>
21
+ #include <optional>
22
+ #include <utility>
23
+ #include <vector>
24
+
25
+ #include "circuits/tests/pq/ml_dsa/ml_dsa_44_types.h"
26
+ #include "circuits/tests/sha3/sha3_reference.h"
27
+ #include "util/panic.h"
28
+
29
+ namespace proofs {
30
+ namespace ml_dsa {
31
+
32
+ // Defined as SHAKE128(str, 8 * len) bits
33
+ void G(const std::vector<uint8_t>& in, size_t len, std::vector<uint8_t>& out) {
34
+ out.resize(len);
35
+ Sha3Reference::shake128Hash(in.data(), in.size(), out.data(), len);
36
+ }
37
+
38
+ Rq mulf(Rq a, const Rq& b) {
39
+ for (int i = 0; i < 256; ++i) {
40
+ a[i] = Fq.mulf(a[i], b[i]);
41
+ }
42
+ return a;
43
+ }
44
+
45
+ Rq addf(Rq a, const Rq& b) {
46
+ for (int i = 0; i < 256; ++i) {
47
+ a[i] = Fq.addf(a[i], b[i]);
48
+ }
49
+ return a;
50
+ }
51
+
52
+ Rq subf(Rq a, const Rq& b) {
53
+ for (int i = 0; i < 256; ++i) {
54
+ a[i] = Fq.subf(a[i], b[i]);
55
+ }
56
+ return a;
57
+ }
58
+
59
+ Rq scalef(Rq a, const Elt& s) {
60
+ for (int i = 0; i < 256; ++i) {
61
+ a[i] = Fq.mulf(a[i], s);
62
+ }
63
+ return a;
64
+ }
65
+
66
+ // Algorithm 41 NTT(𝑤)
67
+ void Ntt(Rq& a) {
68
+ const auto& zetas = kZetas;
69
+ int k = 1;
70
+ for (int len = 128; len >= 1; len >>= 1) {
71
+ for (int start = 0; start < 256; start += 2 * len) {
72
+ Elt zeta = Fq.of_scalar(zetas[k++]);
73
+ for (int j = start; j < start + len; ++j) {
74
+ Elt t = Fq.mulf(zeta, a[j + len]);
75
+ a[j + len] = Fq.subf(a[j], t);
76
+ a[j] = Fq.addf(a[j], t);
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ // Algorithm 42 NTT−1(𝑤)̂
83
+ // Computes the inverse of the NTT.
84
+ void InvNtt(Rq& a) {
85
+ const auto& zetas = kZetas;
86
+ int k = 255;
87
+ for (int len = 1; len < 256; len <<= 1) {
88
+ for (int start = 0; start < 256; start += 2 * len) {
89
+ Elt zeta = Fq.negf(Fq.of_scalar(zetas[k--]));
90
+ for (int j = start; j < start + len; ++j) {
91
+ Elt t = a[j];
92
+ a[j] = Fq.addf(t, a[j + len]);
93
+ a[j + len] = Fq.mulf(Fq.subf(t, a[j + len]), zeta);
94
+ }
95
+ }
96
+ }
97
+ // Multiply by 256^-1
98
+ Elt f = Fq.of_scalar(8347681); // 256^-1 mod 8380417
99
+ for (int i = 0; i < 256; ++i) {
100
+ a[i] = Fq.mulf(a[i], f);
101
+ }
102
+ }
103
+
104
+ Rq RejNTTPoly(const std::vector<uint8_t>& rho, size_t num_blocks) {
105
+ std::vector<uint8_t> out;
106
+ // G is SHAKE128, which has a block size of 168 bytes
107
+ size_t extract_len = num_blocks * 168;
108
+ G(rho, extract_len, out);
109
+
110
+ Rq a;
111
+ size_t j = 0;
112
+ for (size_t i = 0; i + 2 < out.size() && j < 256; i += 3) {
113
+ uint8_t buf[8] = {0};
114
+ buf[0] = out[i];
115
+ buf[1] = out[i + 1];
116
+ buf[2] = out[i + 2] & 0x7F;
117
+ auto maybe_z = Fq.of_bytes_field(buf);
118
+ if (maybe_z.has_value()) {
119
+ a[j] = maybe_z.value();
120
+ j++;
121
+ }
122
+ }
123
+ check(j >= 256, "Failed to sample polynomial");
124
+ return a;
125
+ }
126
+
127
+ // Algorithm 29 SampleInBall(rho)
128
+ // Samples a polynomial c in R with coefficients from {-1, 0, 1} and Hamming
129
+ // weight tau.
130
+ Rq SampleInBall(const std::array<uint8_t, 32>& rho) {
131
+ std::array<uint8_t, 136> out;
132
+ std::vector<uint8_t> rho_vec(rho.begin(), rho.end());
133
+ H(rho_vec, out);
134
+
135
+ Rq c;
136
+ for (size_t k = 0; k < N; ++k) {
137
+ c[k] = Fq.zero();
138
+ }
139
+
140
+ size_t out_idx = 8;
141
+ for (size_t i = 256 - TAU; i < 256; ++i) {
142
+ uint8_t j;
143
+ do {
144
+ check(out_idx < out.size(),
145
+ "SampleInBall: Not enough pseudorandom bytes");
146
+ j = out[out_idx++];
147
+ } while (j > i);
148
+
149
+ c[i] = c[j];
150
+
151
+ size_t bit_idx = i + TAU - 256;
152
+ size_t byte_idx = bit_idx / 8;
153
+ size_t bit_shift = bit_idx % 8;
154
+ uint8_t bit = (out[byte_idx] >> bit_shift) & 1;
155
+
156
+ if (bit == 1) {
157
+ c[j] = Fq.mone();
158
+ } else {
159
+ c[j] = Fq.one();
160
+ }
161
+ }
162
+ return c;
163
+ }
164
+
165
+ // Algorithm 32 ExpandA(rho)
166
+ // Samples a K x L matrix A_hat of elements of T_q.
167
+ // Input: A seed rho (32 bytes).
168
+ // Output: Matrix A_hat in (T_q)^(K x L).
169
+ MatrixA ExpandA(const std::vector<uint8_t>& rho) {
170
+ MatrixA A_hat;
171
+ for (uint8_t r = 0; r < K; ++r) {
172
+ for (uint8_t s = 0; s < L; ++s) {
173
+ std::vector<uint8_t> rho_prime = rho;
174
+ // IntegerToBytes(s, 1) || IntegerToBytes(r, 1)
175
+ // Little-endian
176
+ rho_prime.push_back(s);
177
+ rho_prime.push_back(r);
178
+ // Samples a polynomial in T_q. Using 5 blocks (168 * 5 = 840 bytes)
179
+ // should be overwhelmingly sufficient for rejection sampling 256
180
+ // coefficients.
181
+ A_hat[r][s] = RejNTTPoly(rho_prime, 5);
182
+ }
183
+ }
184
+ return A_hat;
185
+ }
186
+
187
+ std::pair<int32_t, int32_t> Decompose(int32_t r) {
188
+ // Handle the case that r < 0 or r > q by
189
+ // normalizing r_plus in the range [0, q-1].
190
+ int32_t r_plus = r % ml_dsa::Q;
191
+ if (r_plus < 0) {
192
+ r_plus += ml_dsa::Q;
193
+ }
194
+
195
+ constexpr int32_t alpha = 2 * GAMMA_2;
196
+ constexpr int32_t half_alpha = alpha / 2;
197
+ int32_t r0 = r_plus % alpha;
198
+ if (r0 > half_alpha) {
199
+ r0 -= alpha;
200
+ }
201
+
202
+ int32_t r1;
203
+ if (r_plus - r0 == ml_dsa::Q - 1) {
204
+ r1 = 0;
205
+ r0 = r0 - 1;
206
+ } else {
207
+ r1 = (r_plus - r0) / alpha;
208
+ }
209
+ return {r1, r0};
210
+ }
211
+
212
+ uint32_t UseHint(bool h, int32_t r) {
213
+ constexpr int32_t m = (ml_dsa::Q - 1) / (2 * GAMMA_2);
214
+ auto [r1, r0] = Decompose(r);
215
+
216
+ if (h && r0 > 0) {
217
+ return (r1 + 1) % m;
218
+ }
219
+ if (h && r0 <= 0) {
220
+ int32_t res = (r1 - 1) % m;
221
+ if (res < 0) res += m;
222
+ return res;
223
+ }
224
+ return r1;
225
+ }
226
+
227
+ // Algorithm 19 BitUnpack(v, a, b)
228
+ // a = gamma1 - 1, b = gamma1
229
+ // gamma1 = 131072
230
+ // c = bitlen(a+b) = bitlen(262143) = 18.
231
+ std::optional<Rq> BitUnpack(const std::vector<uint8_t>& v, uint32_t a,
232
+ uint32_t b) {
233
+ Rq w;
234
+ uint32_t c = 18; // Only supporting the ML-DSA-44 specific c
235
+ if (v.size() != 32 * c) return std::nullopt;
236
+
237
+ // Reversing the BitPack procedure
238
+ // Extract 18 bits at a time
239
+ for (size_t i = 0; i < N; ++i) {
240
+ size_t bit_offset = i * c;
241
+ size_t byte_offset = bit_offset / 8;
242
+ size_t shift = bit_offset % 8;
243
+
244
+ uint32_t val = 0;
245
+ // We need 18 bits. This will touch at most 4 bytes.
246
+ for (size_t k = 0; k < 4 && byte_offset + k < v.size(); ++k) {
247
+ val |= (static_cast<uint32_t>(v[byte_offset + k]) << (8 * k));
248
+ }
249
+
250
+ val >>= shift;
251
+ val &= ((1 << c) - 1); // Mask out 18 bits
252
+
253
+ // w_i = b - val
254
+ int32_t wi = b - val;
255
+ // Map to [0, q-1]
256
+ if (wi < 0) {
257
+ wi += ml_dsa::Q;
258
+ }
259
+ w[i] = Fq.of_scalar(wi);
260
+ }
261
+ return w;
262
+ }
263
+
264
+ // Algorithm 21 HintBitUnpack(y)
265
+ std::optional<std::array<std::array<bool, N>, K>> HintBitUnpack(
266
+ const std::vector<uint8_t>& y) {
267
+ std::array<std::array<bool, N>, K> h = {};
268
+ for (size_t i = 0; i < K; ++i) {
269
+ for (size_t j = 0; j < N; ++j) {
270
+ h[i][j] = false;
271
+ }
272
+ }
273
+
274
+ size_t index = 0;
275
+ for (size_t i = 0; i < K; ++i) {
276
+ int limit = y[OMEGA + i];
277
+ if (limit < index || limit > OMEGA) return std::nullopt;
278
+
279
+ int last = -1;
280
+ while (index < limit) {
281
+ int byte = y[index++];
282
+ if (last > 0 && byte <= last) {
283
+ return std::nullopt;
284
+ }
285
+ last = byte;
286
+ h[i][byte] = true;
287
+ }
288
+ }
289
+ for (; index < OMEGA; ++index) {
290
+ if (y[index] != 0) {
291
+ return std::nullopt;
292
+ }
293
+ }
294
+
295
+ return h;
296
+ }
297
+
298
+ // Algorithm 27 sigDecode(sigma)
299
+ std::optional<Signature> sigDecode(const std::vector<uint8_t>& sigma) {
300
+ Signature sig;
301
+
302
+ size_t expected_size = C_TILDE_BYTES + L * 32 * 18 + OMEGA + K;
303
+ if (sigma.size() < expected_size) return std::nullopt;
304
+
305
+ size_t offset = 0;
306
+
307
+ // 1. Extract c_tilde
308
+ std::copy(sigma.begin() + offset, sigma.begin() + offset + C_TILDE_BYTES,
309
+ sig.c_tilde.begin());
310
+ offset += C_TILDE_BYTES;
311
+
312
+ // 2. Extract z_i
313
+ // gamma1 = 131072, a = gamma1 - 1, b = gamma1. c = 18.
314
+ size_t z_bytes = 32 * 18;
315
+ for (size_t i = 0; i < L; ++i) {
316
+ std::vector<uint8_t> v(sigma.begin() + offset,
317
+ sigma.begin() + offset + z_bytes);
318
+ auto maybe_z = BitUnpack(v, GAMMA_1 - 1, GAMMA_1);
319
+ if (!maybe_z.has_value()) return std::nullopt;
320
+ sig.z[i] = maybe_z.value();
321
+ offset += z_bytes;
322
+ }
323
+
324
+ // 3. Extract h
325
+ std::vector<uint8_t> y(sigma.begin() + offset,
326
+ sigma.begin() + offset + OMEGA + K);
327
+ auto maybe_h = HintBitUnpack(y);
328
+ if (!maybe_h.has_value()) return std::nullopt;
329
+ sig.h = maybe_h.value();
330
+ offset += OMEGA + K;
331
+
332
+ return sig;
333
+ }
334
+
335
+ // Algorithm 18 SimpleBitUnpack(v, b)
336
+ // Extracts coefficients from a byte array. For ML-DSA-44 b = 1023 (10 bits).
337
+ Rq SimpleBitUnpack(const std::vector<uint8_t>& v, uint32_t b) {
338
+ Rq w;
339
+ uint32_t c = 10; // Only supporting ML-DSA-44 specific c
340
+ check(v.size() == 32 * c, "SimpleBitUnpack input size mismatch");
341
+
342
+ // Extract 10 bits at a time
343
+ for (size_t i = 0; i < N; ++i) {
344
+ size_t bit_offset = i * c;
345
+ size_t byte_offset = bit_offset / 8;
346
+ size_t shift = bit_offset % 8;
347
+
348
+ uint32_t val = 0;
349
+ // We need 10 bits. This will touch at most 2 bytes.
350
+ for (size_t k = 0; k < 2 && byte_offset + k < v.size(); ++k) {
351
+ val |= (static_cast<uint32_t>(v[byte_offset + k]) << (8 * k));
352
+ }
353
+
354
+ val >>= shift;
355
+ val &= ((1 << c) - 1); // Mask out 10 bits
356
+
357
+ w[i] = Fq.of_scalar(val);
358
+ }
359
+ return w;
360
+ }
361
+
362
+ // Algorithm 23 pkDecode(pk)
363
+ // Reverses the procedure pkEncode, expanding rho to a_hat and unpacking t1.
364
+ PublicKey pkDecode(const std::vector<uint8_t>& pk) {
365
+ PublicKey pub_key;
366
+
367
+ // pk is 32 + 32 * K * c bytes where c = 10 for ML-DSA-44
368
+ size_t expected_size = 32 + 32 * K * 10;
369
+ check(pk.size() >= expected_size, "pkDecode public key too short");
370
+
371
+ size_t offset = 0;
372
+
373
+ // 1. Extract rho
374
+ std::vector<uint8_t> rho(pk.begin() + offset, pk.begin() + offset + 32);
375
+ offset += 32;
376
+
377
+ // 2. Expand a_hat from rho
378
+ pub_key.a_hat = ExpandA(rho);
379
+
380
+ // 3. Extract t1
381
+ size_t t1_bytes = 32 * 10;
382
+ for (size_t i = 0; i < K; ++i) {
383
+ std::vector<uint8_t> v(pk.begin() + offset, pk.begin() + offset + t1_bytes);
384
+ pub_key.t1[i] = SimpleBitUnpack(v, 1023);
385
+ offset += t1_bytes;
386
+ }
387
+
388
+ // 4. Compute tr = SHAKE256(pk, 64)
389
+ H(pk, pub_key.tr);
390
+
391
+ return pub_key;
392
+ }
393
+
394
+ // Algorithm 18 SimpleBitPack(w, b)
395
+ std::vector<uint8_t> SimpleBitPack(const Rq& w, uint32_t b) {
396
+ // Determine bitlen
397
+ uint32_t bitlen = 0;
398
+ uint32_t val = b;
399
+ while (val > 0) {
400
+ bitlen++;
401
+ val >>= 1;
402
+ }
403
+ if (b == 0) bitlen = 1;
404
+
405
+ // Total bits = 256 * bitlen
406
+ // Total bytes = ceil(Total bits / 8)
407
+ size_t total_bits = 256 * bitlen;
408
+ size_t total_bytes = (total_bits + 7) / 8;
409
+ std::vector<uint8_t> z(total_bytes, 0);
410
+
411
+ size_t current_bit = 0;
412
+ for (size_t i = 0; i < N; ++i) {
413
+ // Assuming w[i] is already reduced and positive.
414
+ // Use Fq.from_montgomery(w[i]) to get canonical representation.
415
+ uint64_t wi_long = Fq.from_montgomery(w[i]).limb_[0];
416
+ uint32_t wi = static_cast<uint32_t>(wi_long);
417
+
418
+ // Should verify wi <= b, but input assumes it is.
419
+
420
+ for (size_t k = 0; k < bitlen; ++k) {
421
+ if ((wi >> k) & 1) {
422
+ size_t byte_idx = current_bit / 8;
423
+ size_t bit_idx = current_bit % 8;
424
+ z[byte_idx] |= (1 << bit_idx);
425
+ }
426
+ current_bit++;
427
+ }
428
+ }
429
+ return z;
430
+ }
431
+
432
+ std::array<uint8_t, K * 192> w1Encode(const std::array<Rq, K>& w1) {
433
+ std::array<uint8_t, K * 192> w1_tilde;
434
+ // (q-1)/(2*gamma2) - 1 = 8380416 / 190464 - 1 = 43
435
+ constexpr uint32_t b = 43;
436
+
437
+ size_t offset = 0;
438
+ for (size_t i = 0; i < K; ++i) {
439
+ std::vector<uint8_t> packed = SimpleBitPack(w1[i], b);
440
+ std::copy(packed.begin(), packed.end(), w1_tilde.begin() + offset);
441
+ offset += packed.size();
442
+ }
443
+ return w1_tilde;
444
+ }
445
+
446
+ std::vector<uint8_t> preprocess_message(const std::vector<uint8_t>& msg,
447
+ const std::vector<uint8_t>& ctx) {
448
+ std::vector<uint8_t> res;
449
+ res.reserve(2 + ctx.size() + msg.size());
450
+ res.push_back(0);
451
+ res.push_back(ctx.size());
452
+ res.insert(res.end(), ctx.begin(), ctx.end());
453
+ res.insert(res.end(), msg.begin(), msg.end());
454
+ return res;
455
+ }
456
+
457
+ } // namespace ml_dsa
458
+ } // namespace proofs
@@ -0,0 +1,150 @@
1
+ // Copyright 2026 Google LLC.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_TESTS_PQ_ML_DSA_ML_DSA_REF_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_TESTS_PQ_ML_DSA_ML_DSA_REF_H_
17
+
18
+ #include <array>
19
+ #include <cstddef>
20
+ #include <cstdint>
21
+ #include <optional>
22
+ #include <utility>
23
+ #include <vector>
24
+
25
+ #include "circuits/tests/pq/ml_dsa/ml_dsa_44_types.h"
26
+ #include "circuits/tests/sha3/sha3_reference.h"
27
+
28
+ // ----------------------------------------------------------------------------
29
+ //
30
+ // !!!!! DO NOT USE IN PRODUCTION !!!!!
31
+ //
32
+ // This ML-DSA circuit is an experimental implementation for research purposes.
33
+ // It has not been fully vetted and is not recommended for production use cases
34
+ // at this time.
35
+ //
36
+ // ML-DSA is specified in
37
+ //
38
+ // FIPS 204
39
+ // Federal Information Processing Standards Publication
40
+ // Module-Lattice-Based Digital
41
+ // Signature Standard
42
+ // https://csrc.nist.gov/pubs/fips/204/final
43
+ //
44
+ // ----------------------------------------------------------------------------
45
+
46
+ namespace proofs {
47
+ namespace ml_dsa {
48
+
49
+ // Defined as SHAKE256(str, 8 * len) bits
50
+ template <size_t N>
51
+ void H(const std::vector<uint8_t>& in, std::array<uint8_t, N>& out) {
52
+ Sha3Reference::shake256Hash(in.data(), in.size(), out.data(), out.size());
53
+ }
54
+
55
+ // Defined as SHAKE128(str, 8 * len) bits
56
+ void G(const std::vector<uint8_t>& in, size_t len, std::vector<uint8_t>& out);
57
+
58
+ Rq mulf(Rq a, const Rq& b);
59
+ Rq addf(Rq a, const Rq& b);
60
+ Rq subf(Rq a, const Rq& b);
61
+ Rq scalef(Rq a, const Elt& s);
62
+
63
+ // Inplace versions of
64
+ // Algorithm 41 NTT(𝑤)
65
+ // Algorithm 42 NTT−1(𝑤)̂
66
+ void Ntt(Rq& a);
67
+ void InvNtt(Rq& a);
68
+
69
+ // Algorithm 30 RejNTTPoly(𝜌)
70
+ // Samples a polynomial in T_q.
71
+ Rq RejNTTPoly(const std::vector<uint8_t>& rho, size_t num_blocks);
72
+
73
+ // Algorithm 29 SampleInBall(rho)
74
+ // Samples a polynomial c in R with coefficients from {-1, 0, 1} and Hamming
75
+ // weight tau.
76
+ Rq SampleInBall(const std::array<uint8_t, 32>& rho);
77
+
78
+ // Algorithm 32 ExpandA(rho)
79
+ // Samples a K x L matrix A_hat of elements of T_q.
80
+ // Input: A seed rho (32 bytes).
81
+ // Output: Matrix A_hat in (T_q)^(K x L).
82
+ MatrixA ExpandA(const std::vector<uint8_t>& rho);
83
+
84
+ // Algorithm 36 Decompose(r)
85
+ // Decomposes r into (r1, r0) such that r = r1*(2*gamma2) + r0 mod q
86
+ std::pair<int32_t, int32_t> Decompose(int32_t r);
87
+
88
+ // Algorithm 40 UseHint(h, r)
89
+ // Returns the high bits of r adjusted according to hint h.
90
+ // Input: Boolean h, r in Z_q.
91
+ // Output: r1 in Z with 0 <= r1 <= (q-1)/(2*gamma2).
92
+ uint32_t UseHint(bool h, int32_t r);
93
+
94
+ // Algorithm 19 BitUnpack(v, a, b)
95
+ // Reverses the procedure BitPack. For ML-DSA-44, used for unpacking z with b =
96
+ // gamma1
97
+ std::optional<Rq> BitUnpack(const std::vector<uint8_t>& v, uint32_t a,
98
+ uint32_t b);
99
+
100
+ // Algorithm 21 HintBitUnpack(y)
101
+ // Reverses the procedure HintBitPack.
102
+ std::optional<std::array<std::array<bool, N>, K>> HintBitUnpack(
103
+ const std::vector<uint8_t>& y);
104
+
105
+ // Struct to hold expanded ML-DSA-44 public key elements
106
+ struct PublicKey {
107
+ MatrixA a_hat;
108
+ std::array<Rq, K> t1;
109
+ std::array<uint8_t, 64> tr;
110
+ };
111
+
112
+ // Struct to hold ML-DSA-44 signature elements
113
+ struct Signature {
114
+ std::array<uint8_t, 32> c_tilde;
115
+ std::array<Rq, L> z;
116
+ std::array<std::array<bool, N>, K> h;
117
+ };
118
+
119
+ // Algorithm 27 sigDecode(sigma)
120
+ // Reverses the procedure sigEncode.
121
+ std::optional<Signature> sigDecode(const std::vector<uint8_t>& sigma);
122
+
123
+ // Algorithm 18 SimpleBitUnpack(v, b)
124
+ // Extracts coefficients from a byte array. For ML-DSA-44 b = 1023 (10 bits).
125
+ Rq SimpleBitUnpack(const std::vector<uint8_t>& v, uint32_t b);
126
+
127
+ // Algorithm 23 pkDecode(pk)
128
+ // Reverses the procedure pkEncode, expanding rho to a_hat and unpacking t1.
129
+ PublicKey pkDecode(const std::vector<uint8_t>& pk);
130
+
131
+ // Algorithm 18 SimpleBitPack(w, b)
132
+ // Packs coefficients into a byte array. For ML-DSA-44 w1Encode, b = 43 (6
133
+ // bits).
134
+ std::vector<uint8_t> SimpleBitPack(const Rq& w, uint32_t b);
135
+
136
+ // Algorithm 28 w1Encode(w1)
137
+ // Encodes a polynomial vector w1 into a byte string.
138
+ // Input: w1 in R_q^k with coefficients in [0, (q-1)/(2*gamma2) - 1].
139
+ // Output: A byte string representation w1_tilde.
140
+ std::array<uint8_t, K * 192> w1Encode(const std::array<Rq, K>& w1);
141
+
142
+ // Preprocesses the message by binding the context to it:
143
+ // M' = 0x00 || |ctx| || ctx || msg
144
+ std::vector<uint8_t> preprocess_message(const std::vector<uint8_t>& msg,
145
+ const std::vector<uint8_t>& ctx);
146
+
147
+ } // namespace ml_dsa
148
+ } // namespace proofs
149
+
150
+ #endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_TESTS_PQ_ML_DSA_ML_DSA_REF_H_