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,219 @@
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_ALGEBRA_CONVOLUTION_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CONVOLUTION_H_
17
+
18
+ #include <stddef.h>
19
+
20
+ #include <cstdint>
21
+ #include <memory>
22
+ #include <vector>
23
+
24
+ #include "algebra/blas.h"
25
+ #include "algebra/fft.h"
26
+ #include "algebra/rfft.h"
27
+
28
+ /*
29
+ All of the classes in this package compute convolutions.
30
+ That is, given inputs arrays of field elements x, y, with |x|=n, |y|=m,
31
+ these methods compute the first m entries of
32
+
33
+ z[k] = \sum_{i=0}^{n-1} x[i] y[k-i]
34
+
35
+ SlowConvolution uses an O(n*m) method for testing validation.
36
+
37
+ FFTConvolution and FFTExtConvolution first pad y to length n and use advanced
38
+ FFT algorithms to compute the same in O(nlogn) time.
39
+
40
+ The const Field& objects that are passed have lifetimes that exceed the call
41
+ durations and can be safely passed by const reference.
42
+ */
43
+
44
+ namespace proofs {
45
+
46
+ // Returns the smallest power of 2 that is at least n.
47
+ static size_t choose_padding(const size_t n) {
48
+ size_t p = 1;
49
+ while (p < n) {
50
+ p *= 2;
51
+ }
52
+ return p;
53
+ }
54
+
55
+ template <class Field>
56
+ class FFTConvolution {
57
+ using Elt = typename Field::Elt;
58
+
59
+ public:
60
+ FFTConvolution(size_t n, size_t m, const Field& f, const Elt omega,
61
+ uint64_t omega_order, const Elt y[/*m*/])
62
+ : f_(f),
63
+ omega_(omega),
64
+ omega_order_(omega_order),
65
+ n_(n),
66
+ m_(m),
67
+ padding_(choose_padding(m)),
68
+ y_fft_(padding_, f_.zero()) {
69
+ Blas<Field>::copy(m, &y_fft_[0], 1, y, 1);
70
+ FFT<Field>::fftf(&y_fft_[0], padding_, omega_, omega_order_, f_);
71
+
72
+ // Pre-scale Y by 1/N to compensate for the scaling in FFTB(FFTF(.))
73
+ Blas<Field>::scale(padding_, &y_fft_[0], 1,
74
+ f_.invertf(f_.of_scalar(padding_)), f_);
75
+ }
76
+
77
+ // Computes (first m entries of) convolution of x with y, outputs in z:
78
+ // z[k] = \sum_{i=0}^{n-1} x[i] y[k-i].
79
+ // Note that y has already been FFT'd and divided by padding_ in constructor
80
+ void convolution(const Elt x[/*n_*/], Elt z[/*m_*/]) const {
81
+ std::vector<Elt> x_fft(padding_, f_.zero());
82
+ Blas<Field>::copy(n_, &x_fft[0], 1, x, 1);
83
+ FFT<Field>::fftf(&x_fft[0], padding_, omega_, omega_order_, f_);
84
+ // Pointwise multiplication.
85
+ for (size_t i = 0; i < padding_; ++i) {
86
+ f_.mul(x_fft[i], y_fft_[i]);
87
+ }
88
+ // Backward fft.
89
+ FFT<Field>::fftb(&x_fft[0], padding_, omega_, omega_order_, f_);
90
+ Blas<Field>::copy(m_, z, 1, &x_fft[0], 1);
91
+ }
92
+
93
+ private:
94
+ const Field& f_;
95
+ const Elt omega_;
96
+ const uint64_t omega_order_;
97
+
98
+ // n is the number of points input
99
+ size_t n_;
100
+ size_t m_; // total number of points output (points in + new points out)
101
+ size_t padding_;
102
+
103
+ // fft(y[i]) / padding
104
+ // padded with zeroes to the next power of 2 at least m.
105
+ std::vector<Elt> y_fft_;
106
+ };
107
+
108
+ template <class Field>
109
+ class FFTConvolutionFactory {
110
+ using Elt = typename Field::Elt;
111
+
112
+ public:
113
+ using Convolver = FFTConvolution<Field>;
114
+ FFTConvolutionFactory(const Field& f, const Elt omega, uint64_t omega_order)
115
+ : f_(f), omega_(omega), omega_order_(omega_order) {}
116
+
117
+ std::unique_ptr<const Convolver> make(size_t n, size_t m,
118
+ const Elt y[/*m*/]) const {
119
+ return std::make_unique<const Convolver>(n, m, f_, omega_, omega_order_, y);
120
+ }
121
+
122
+ private:
123
+ const Field& f_;
124
+ const Elt omega_;
125
+ const uint64_t omega_order_;
126
+ };
127
+
128
+ template <class Field, class FieldExt>
129
+ class FFTExtConvolution {
130
+ using Elt = typename Field::Elt;
131
+ using EltExt = typename FieldExt::Elt;
132
+
133
+ public:
134
+ FFTExtConvolution(size_t n, size_t m, const Field& f, const FieldExt& f_ext,
135
+ const EltExt omega, uint64_t omega_order,
136
+ const Elt y[/*m*/])
137
+ : f_(f),
138
+ f_ext_(f_ext),
139
+ omega_(omega),
140
+ omega_order_(omega_order),
141
+ n_(n),
142
+ m_(m),
143
+ padding_(choose_padding(m)),
144
+ y_fft_(padding_, f_.zero()) {
145
+ Blas<Field>::copy(m, &y_fft_[0], 1, y, 1);
146
+ RFFT<FieldExt>::r2hc(&y_fft_[0], padding_, omega_, omega_order_, f_ext_);
147
+
148
+ // Pre-scale Y by 1/N to compensate for the scaling in HC2R(R2HC(.))
149
+ Blas<Field>::scale(padding_, &y_fft_[0], 1,
150
+ f_.invertf(f_.of_scalar(padding_)), f_);
151
+ }
152
+
153
+ // Computes (first m entries of) convolution of x with y, stores in z:
154
+ // z[k] = \sum_{i=0}^{n-1} x[i] y[k-i].
155
+ // Note that y has already been FFT'd and divided by padding_ in constructor
156
+ void convolution(const Elt x[/*n_*/], Elt z[/*m_*/]) const {
157
+ std::vector<Elt> x_fft(padding_, f_.zero());
158
+ Blas<Field>::copy(n_, &x_fft[0], 1, x, 1);
159
+ RFFT<FieldExt>::r2hc(&x_fft[0], padding_, omega_, omega_order_, f_ext_);
160
+
161
+ // Pointwise multiplication
162
+ {
163
+ size_t i;
164
+ f_.mul(x_fft[0], y_fft_[0]); // DC is real
165
+ for (i = 1; i + i < padding_; ++i) {
166
+ RFFT<FieldExt>::cmul(&x_fft[i], &x_fft[padding_ - i], y_fft_[i],
167
+ y_fft_[padding_ - i], f_);
168
+ }
169
+ f_.mul(x_fft[i], y_fft_[i]); // Nyquist is real
170
+ }
171
+
172
+ // Backward FFT.
173
+ RFFT<FieldExt>::hc2r(&x_fft[0], padding_, omega_, omega_order_, f_ext_);
174
+ Blas<Field>::copy(m_, z, 1, &x_fft[0], 1);
175
+ }
176
+
177
+ private:
178
+ const Field& f_;
179
+ const FieldExt& f_ext_;
180
+ const EltExt omega_;
181
+ const uint64_t omega_order_;
182
+
183
+ // n is the number of points input in x
184
+ size_t n_;
185
+ size_t m_; // total number of points output in convolution
186
+ size_t padding_;
187
+
188
+ // fft(y[i]) / padding
189
+ // padded with zeroes to the next power of 2 at least m.
190
+ std::vector<Elt> y_fft_;
191
+ };
192
+
193
+ template <class Field, class FieldExt>
194
+ class FFTExtConvolutionFactory {
195
+ using Elt = typename Field::Elt;
196
+ using EltExt = typename FieldExt::Elt;
197
+
198
+ public:
199
+ using Convolver = FFTExtConvolution<Field, FieldExt>;
200
+
201
+ FFTExtConvolutionFactory(const Field& f, const FieldExt& f_ext,
202
+ const EltExt omega, uint64_t omega_order)
203
+ : f_(f), f_ext_(f_ext), omega_(omega), omega_order_(omega_order) {}
204
+
205
+ std::unique_ptr<const Convolver> make(size_t n, size_t m,
206
+ const Elt y[/*m*/]) const {
207
+ return std::make_unique<const Convolver>(n, m, f_, f_ext_, omega_,
208
+ omega_order_, y);
209
+ }
210
+
211
+ private:
212
+ const Field& f_;
213
+ const FieldExt& f_ext_;
214
+ const EltExt omega_;
215
+ const uint64_t omega_order_;
216
+ };
217
+ } // namespace proofs
218
+
219
+ #endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CONVOLUTION_H_
@@ -0,0 +1,42 @@
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 "algebra/crt.h"
16
+
17
+ #include <cstdint>
18
+
19
+ namespace proofs {
20
+ namespace crt {
21
+
22
+ // ==========================================
23
+ // 17 primes for a CRT representation that can support p521.
24
+ // 9 or 13 can be used for smaller fields. Primes are in sorted order.
25
+ const uint64_t kPrimes17[kBasisSize] = {
26
+ 18446744072195407873ull, 18446744072237350913ull, 18446744072245739521ull,
27
+ 18446744072325431297ull, 18446744072589672449ull, 18446744072623226881ull,
28
+ 18446744072790999041ull, 18446744073113960449ull, 18446744073290121217ull,
29
+ 18446744073327869953ull, 18446744073332064257ull, 18446744073344647169ull,
30
+ 18446744073420144641ull, 18446744073457893377ull, 18446744073516613633ull,
31
+ 18446744073520807937ull, 18446744073692774401ull};
32
+
33
+ const uint64_t kOmega17[kBasisSize] = {
34
+ 436037131817ull, 2773676930123ull, 2768111518080ull, 34106487772798ull,
35
+ 1302264167001ull, 5572414085664ull, 4170236488818ull, 10930506752996ull,
36
+ 13447610733542ull, 366878793395ull, 10535270759408ull, 2630106726088ull,
37
+ 2766923619799ull, 6957320847870ull, 10540913985379ull, 15095618916269ull,
38
+ 3150424293220ull,
39
+ };
40
+
41
+ } // namespace crt
42
+ } // namespace proofs
@@ -0,0 +1,299 @@
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_ALGEBRA_CRT_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CRT_H_
17
+
18
+ #include <cstddef>
19
+ #include <cstdint>
20
+ #include <memory>
21
+
22
+ #include "algebra/fp.h"
23
+ #include "algebra/nat.h"
24
+ #include "util/panic.h"
25
+
26
+ // The idea behind this class is to mimic the Field interface for F_p with
27
+ // an underlying CRT implementation over a basis of primes. Then a
28
+ // convolution template can be instantiated with this class instead of an
29
+ // F_p field, and this convolution can be used by ReedSolomon.
30
+
31
+ namespace proofs {
32
+
33
+ // Every prime field of 1-64b word has the same type, but are different classes.
34
+ using BaseField = Fp<1, false>;
35
+ using BaseNat = typename BaseField::N;
36
+ using BaseElt = typename BaseField::Elt;
37
+
38
+ // constants
39
+ namespace crt {
40
+ static constexpr size_t kBasisSize = 17;
41
+ static constexpr uint64_t kOmegaOrder = 1ull << 22;
42
+
43
+ extern const uint64_t kPrimes17[kBasisSize];
44
+ extern const uint64_t kOmega17[kBasisSize];
45
+ } // namespace crt
46
+
47
+ // ==========================================
48
+
49
+ // Fp_crt implementation of field Field. This implementation works as long
50
+ // as the sequence of field operations that are performed on elements before
51
+ // the from_crt method is called can be range-bounded by the max value that can
52
+ // be represented using the CRT basis formed by the first VS primes defined in
53
+ // kBasis.
54
+ // The initialize of this class computes the auxiliary information needed to
55
+ // efficiently move into and out of the CRT representation. Therefore, this
56
+ // class can be instantiated once and used for many convolutions/etc.
57
+ template <size_t VS, class Field>
58
+ class CRT {
59
+ static constexpr size_t kWField = Field::kU64;
60
+
61
+ public:
62
+ static constexpr size_t kVS = VS;
63
+ const Field& f_;
64
+
65
+ struct Elt {
66
+ BaseElt r[VS];
67
+ bool operator==(const Elt& y) const {
68
+ bool res = true;
69
+ for (size_t i = 0; i < VS; ++i) {
70
+ res = res && (r[i] == y.r[i]);
71
+ }
72
+ return res;
73
+ }
74
+ bool operator!=(const Elt& y) const { return !operator==(y); }
75
+ };
76
+
77
+ explicit CRT(const Field& f) : f_(f) {
78
+ check(VS <= crt::kBasisSize, "VS <= crt::kBasisSize");
79
+
80
+ for (size_t b = 0; b < VS; ++b) {
81
+ bf_[b] = std::make_unique<BaseField>(BaseNat(crt::kPrimes17[b]));
82
+ }
83
+
84
+ for (size_t b = 0; b < VS; ++b) {
85
+ k_[0].r[b] = bf_[b]->zero();
86
+ k_[1].r[b] = bf_[b]->one();
87
+ k_[2].r[b] = bf_[b]->two();
88
+ reduce_scale_[b] = bf_[b]->template reduce_scale<kWField>();
89
+ }
90
+
91
+ if (VS == 1) {
92
+ // ignore the Garner reduction constants, and do not
93
+ // require the field to support dot products.
94
+ } else {
95
+ // Standard CRT integer conversion requires computing a dot-product
96
+ // between the CRT representation and a vector of constants. The
97
+ // reconstruction pre-processing is to compute:
98
+ // 1. Compute P_i = prod_{j neq i} prime_j and
99
+ // P = prod_{j} prime_j
100
+ // 2. Compute inv_i such that inv_i * P_i = 1 mod prime_i
101
+ // The online reconstruction step is then:
102
+ // a. v = (sum_{i} r_i * recon_i) (mod P)) mod f_p
103
+ // for (size_t i = 0; i < VS; ++i) {
104
+ // recon_[i] = ring_.of_string(kRecon[i]);
105
+ // }
106
+ // However, we use the Garner method which requires more pre-processed
107
+ // elements, but produces a result that is guaranteed to be in [0,m] and
108
+ // does so using smaller operations.
109
+
110
+ // garner_[i] are terms prod p_k in CRT formula, prepared for
111
+ // optimized FMA operations by 64-bit scalar vi[i] in to_field.
112
+ for (size_t i = 0; i < VS; ++i) {
113
+ auto g = f.one();
114
+ for (size_t j = 0; j < i; ++j) {
115
+ Nat<1> n(crt::kPrimes17[j]);
116
+ f.mul(g, f.reduce(n));
117
+ }
118
+ garner_[i] = f.prescale_for_dot(g);
119
+ }
120
+
121
+ // Initialize Garner constants Cij.
122
+ for (size_t i = 0; i < VS; ++i) {
123
+ for (size_t j = 0; j < i; ++j) {
124
+ cij_[i][j] = bf_[i]->invertf(bf_[i]->of_scalar(crt::kPrimes17[j]));
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ CRT(const CRT&) = delete;
131
+ CRT& operator=(const CRT&) = delete;
132
+
133
+ Elt to_crt(const typename Field::Elt& e) const {
134
+ Elt r;
135
+ auto n = f_.from_montgomery(e);
136
+ for (size_t b = 0; b < VS; ++b) {
137
+ r.r[b] = bf_[b]->reduce(n, reduce_scale_[b]);
138
+ }
139
+ return r;
140
+ }
141
+
142
+ // The standard CRT reconstruction algorithm to convert
143
+ // from the CRT representation to the BigRing representation involves
144
+ // several operations between "ring-element"-sized values and prime-element
145
+ // sized values. This method is slower, and it produces a result that must
146
+ // also be reduced modulo the ring.
147
+ //
148
+ // result = (sum_{i} x_i * recon_i) (mod P_))
149
+ // CRTRing::Elt from_crt(const Elt& x) const {
150
+ // typename CRTRing::Elt r = ring_.zero();
151
+ // for (size_t i = 0; i < VS; ++i) {
152
+ // Nat<1> xi = kBasis[i].from_montgomery(x.r[i]);
153
+ // ring_.add(r, ring_.mulf(recon_[i], ring_.of_scalar(xi.limb_[0])));
154
+ // }
155
+ // return r;
156
+ // }
157
+ // BM_FromCRT 2.482µ ± ∞ ¹
158
+ // BM_FromCRT 22.08k ± ∞ ¹ (instructions)
159
+ // Instead, we use Garner's method, which can also reduce the returned value
160
+ // by the Field modulus in the same step. This method is roughly 4x faster.
161
+ //
162
+ // BM_ToField 729.6n ± ∞ ¹
163
+ // BM_ToField 6.282k ± ∞ ¹ (instructions)
164
+ //
165
+ // The Garner CRT reconstruction produces a result that lies in 0..m, and
166
+ // only uses single-word arithmetic to produce the intermediate values
167
+ // v1..vn.
168
+ // If the eventual goal is to reconstruct an element in Fp, then the last
169
+ // reconstruction step can be done in Fp, thereby requiring no arithmetic
170
+ // in the Bigring.
171
+ typename Field::Elt to_field(const Elt& x) const {
172
+ if (VS == 1) {
173
+ return f_.reduce(bf_[0]->from_montgomery(x.r[0]));
174
+ } else {
175
+ // Let cij be s.t. c_ij.pi = 1 mod pj
176
+ // v1 = x1
177
+ // v2 = (x2 - v1).c12 mod p2
178
+ // v3 = ((x3 - v1).c13 - v2).c23 mod p3
179
+ // v4 = (((x4 - v1).c14 - v2).c24 - v3).c34 mod p4
180
+ // ...
181
+ // u = vr.p_{r-1}p_{r-2}...p_1 + ... + v4.p3.p2.p1 + v3.p2.p1 + ... + v1
182
+ // Because the goal is to compute u mod F_p, it suffices to maintain
183
+ // each of the p_{r-j}...p1 products modulo F_p.
184
+ BaseNat vi[VS];
185
+ // This inner loop breaks our field abstraction. Instead of maintaining
186
+ // vi in Montgomery form, it is kept as a natural in [0,p-1].
187
+ // The F.sub method works in this form, and because cij_ is in
188
+ // Montgomery form, the last mul operation returns a result that is also
189
+ // "natural." This maneuver saves an of_scalar and a from_montgomery
190
+ // call in the inner-loop.
191
+ for (size_t j = 0; j < VS; ++j) {
192
+ vi[j] = bf_[j]->from_montgomery(x.r[j]);
193
+ }
194
+
195
+ // Change the order of operations to exploit data (in)dependencies. The
196
+ // subtractions and mults can all issue in parallel.
197
+ for (size_t j = 1; j < VS; ++j) {
198
+ for (size_t i = j; i < VS; ++i) {
199
+ const BaseField* Fi = bf_[i].get();
200
+ Fi->sub(vi[i], vi[j - 1]);
201
+ Fi->mul(vi[i], cij_[i][j - 1]);
202
+ }
203
+ }
204
+
205
+ return f_.dot(VS, vi, garner_);
206
+ }
207
+ }
208
+
209
+ // Returns a root of unity consisting of a root of unity of the same degree
210
+ // for each base prime.
211
+ Elt omega() const {
212
+ Elt r;
213
+ for (size_t b = 0; b < VS; ++b) {
214
+ r.r[b] = bf_[b]->of_scalar(crt::kOmega17[b]);
215
+ }
216
+ return r;
217
+ }
218
+ uint64_t omega_order() const { return crt::kOmegaOrder; }
219
+
220
+ // x += y
221
+ void add(Elt& x, const Elt& y) const {
222
+ for (size_t i = 0; i < VS; ++i) {
223
+ bf_[i]->add(x.r[i], y.r[i]);
224
+ }
225
+ }
226
+ // x -= y
227
+ void sub(Elt& x, const Elt& y) const {
228
+ for (size_t i = 0; i < VS; ++i) {
229
+ bf_[i]->sub(x.r[i], y.r[i]);
230
+ }
231
+ }
232
+
233
+ // x *= y, Montgomery
234
+ void mul(Elt& x, const Elt& y) const {
235
+ for (size_t i = 0; i < VS; ++i) {
236
+ bf_[i]->mul(x.r[i], y.r[i]);
237
+ }
238
+ }
239
+
240
+ void neg(Elt& x) const {
241
+ for (size_t i = 0; i < VS; ++i) {
242
+ bf_[i]->neg(x.r[i]);
243
+ }
244
+ }
245
+
246
+ void invert(Elt& x) const {
247
+ for (size_t i = 0; i < VS; ++i) {
248
+ check(x.r[i] != bf_[i]->zero(), "Non-invertible element");
249
+ bf_[i]->invert(x.r[i]);
250
+ }
251
+ }
252
+
253
+ // functional interface
254
+ Elt addf(Elt a, const Elt& y) const {
255
+ add(a, y);
256
+ return a;
257
+ }
258
+ Elt subf(Elt a, const Elt& y) const {
259
+ sub(a, y);
260
+ return a;
261
+ }
262
+ Elt mulf(Elt a, const Elt& y) const {
263
+ mul(a, y);
264
+ return a;
265
+ }
266
+ Elt negf(Elt a) const {
267
+ neg(a);
268
+ return a;
269
+ }
270
+
271
+ Elt invertf(Elt a) const {
272
+ invert(a);
273
+ return a;
274
+ }
275
+
276
+ const Elt& zero() const { return k_[0]; }
277
+ const Elt& one() const { return k_[1]; }
278
+ const Elt& two() const { return k_[2]; }
279
+
280
+ private:
281
+ std::unique_ptr<BaseField> bf_[VS];
282
+ Elt k_[3]; // small constants
283
+ BaseField::template ScaleElt<kWField> reduce_scale_[VS];
284
+ typename Field::NatScaledForDot garner_[VS];
285
+ BaseElt cij_[VS][VS];
286
+ };
287
+
288
+ template <class Field>
289
+ using CRT256 = CRT<9, Field>;
290
+
291
+ template <class Field>
292
+ using CRT384 = CRT<13, Field>;
293
+
294
+ template <class Field>
295
+ using CRT521 = CRT<17, Field>;
296
+
297
+ } // namespace proofs
298
+
299
+ #endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CRT_H_
@@ -0,0 +1,114 @@
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_ALGEBRA_CRT_CONVOLUTION_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CRT_CONVOLUTION_H_
17
+
18
+ #include <stddef.h>
19
+
20
+ #include <cstdint>
21
+ #include <memory>
22
+ #include <vector>
23
+
24
+ #include "algebra/convolution.h"
25
+ #include "algebra/fft.h"
26
+
27
+ namespace proofs {
28
+
29
+ // Uses a fixed basis of primes to compute a convolution for 64--521 bit values.
30
+ // The CRT class must use the same Field in its definition.
31
+ template <class CRT, class Field>
32
+ class CRTConvolution {
33
+ using Elt = typename Field::Elt;
34
+ using CRTElt = typename CRT::Elt;
35
+
36
+ public:
37
+ CRT crt_;
38
+
39
+ CRTConvolution(size_t n, size_t m, const Field& f, const Elt y[/*m*/])
40
+ : crt_(f),
41
+ f_(f),
42
+ n_(n),
43
+ m_(m),
44
+ padding_(choose_padding(m)),
45
+ y_fft_(padding_, crt_.zero()),
46
+ omega_order_(crt_.omega_order()),
47
+ omega_(crt_.omega()) {
48
+ // Pre-compute the y coefficients in crt form.
49
+ // Pre-scale Y by 1/N to compensate for the scaling in FFTB(FFTF(.))
50
+ auto pni = crt_.invertf(crt_.to_crt(f.of_scalar(padding_)));
51
+ for (size_t i = 0; i < m; ++i) {
52
+ y_fft_[i] = crt_.mulf(pni, crt_.to_crt(y[i]));
53
+ }
54
+
55
+ FFT<CRT>::fftf(&y_fft_[0], padding_, omega_, omega_order_, crt_);
56
+ }
57
+
58
+ // Computes (first m entries of) convolution of x with y, outputs in z:
59
+ // z[k] = \sum_{i=0}^{n-1} x[i] y[k-i].
60
+ // Note that y has already been FFT'd and divided by padding_ in constructor
61
+ void convolution(const Elt x[/*n_*/], Elt z[/*m_*/]) const {
62
+ std::vector<CRTElt> x_fft(padding_, crt_.zero());
63
+ for (size_t i = 0; i < n_; ++i) {
64
+ x_fft[i] = crt_.to_crt(x[i]);
65
+ }
66
+
67
+ FFT<CRT>::fftf(&x_fft[0], padding_, omega_, omega_order_, crt_);
68
+
69
+ // Pointwise multiplication.
70
+ for (size_t i = 0; i < padding_; ++i) {
71
+ crt_.mul(x_fft[i], y_fft_[i]);
72
+ }
73
+
74
+ // Backward fft.
75
+ FFT<CRT>::fftb(&x_fft[0], padding_, omega_, omega_order_, crt_);
76
+
77
+ // Convert back to field form
78
+ for (size_t i = 0; i < m_; ++i) {
79
+ z[i] = crt_.to_field(x_fft[i]);
80
+ }
81
+ }
82
+
83
+ private:
84
+ const Field& f_;
85
+
86
+ // n is the number of points input
87
+ size_t n_;
88
+ size_t m_; // total number of points output (points in + new points out)
89
+ size_t padding_;
90
+ std::vector<CRTElt> y_fft_;
91
+ uint64_t omega_order_;
92
+ CRTElt omega_;
93
+ };
94
+
95
+ template <class CRT, class Field>
96
+ class CrtConvolutionFactory {
97
+ using Elt = typename Field::Elt;
98
+
99
+ public:
100
+ using Convolver = CRTConvolution<CRT, Field>;
101
+ explicit CrtConvolutionFactory(const Field& f) : f_(f) {}
102
+
103
+ std::unique_ptr<const Convolver> make(size_t n, size_t m,
104
+ const Elt y[/*m*/]) const {
105
+ return std::make_unique<const Convolver>(n, m, f_, y);
106
+ }
107
+
108
+ private:
109
+ const Field& f_;
110
+ };
111
+
112
+ } // namespace proofs
113
+
114
+ #endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CRT_CONVOLUTION_H_