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,400 @@
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_RFFT_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_RFFT_H_
17
+
18
+ #include <stddef.h>
19
+ #include <stdint.h>
20
+
21
+ #include "algebra/permutations.h"
22
+ #include "algebra/twiddle.h"
23
+ #include "util/panic.h"
24
+
25
+ namespace proofs {
26
+
27
+ // Real FFT and its inverse.
28
+ //
29
+ // The FFT F[j] of a real input R[k] is complex and
30
+ // conjugate-symmetric: F[j] = conj(F[n - j]).
31
+ //
32
+ // Following the FFTW conventions, to avoid doubling the
33
+ // storage, we store F[j] as a "half-complex" array HC[j] of elements
34
+ // in the base field.
35
+ //
36
+ // HC[j] = (2j <= n) ? real(F[j]) : imag(F[n - j])
37
+ //
38
+ // Thus we have two kinds of transforms: R2HC (real to
39
+ // half-complex) and HC2R (half-complex to real).
40
+ //
41
+ // Again following the FFTW conventions, we say that
42
+ // the R2HC transform is "forward" (minus sign in the exponent)
43
+ // and the HC2R sign is "backward" (plus sign in the exponent).
44
+ // See fft.h for a definition of forward and backward.
45
+
46
+ template <class FieldExt>
47
+ class RFFT {
48
+ using Field = typename FieldExt::BaseField;
49
+ using RElt = typename Field::Elt;
50
+ using CElt = typename FieldExt::Elt;
51
+
52
+ // The machinery in this file only works if the root is
53
+ // on the unit circle, because we multiply by the conjugate
54
+ // instead of by the inverse.
55
+ static void validate_root(const CElt& omega, const FieldExt& C) {
56
+ check(C.mulf(omega, C.conjf(omega)) == C.one(),
57
+ "root of unity not on the unit circle");
58
+ }
59
+
60
+ // The machinery in this file only works if omega^{n/4} == (0, 1)
61
+ // (== C.i()) as opposed to the conjugate (0, -1). There is nothing
62
+ // wrong with C.conj(C.i()), but we hardcode the positive sign
63
+ // in all the radix-4 butterflies.
64
+ static void validate_I(const CElt& ii, const FieldExt& C) {
65
+ check(ii == C.i(), "wrong sign for i(), need the conjugate root");
66
+ }
67
+
68
+ // ------------------------------------------------------------
69
+ // Main algorithm starts here.
70
+ //
71
+ // The overall algorithm is a radix-4 Cooley-Tukey FFT. Generally
72
+ // speaking, Cooley-Tukey decomposes a problem of size N into R
73
+ // subproblems of size N/R and N/R subproblems of size R, where R is
74
+ // called the "radix". For quadratic field extensions, R=4 is
75
+ // better than R=2 because one can hardcode a size-4 FFT requiring
76
+ // no multiplications, as multiplying by the fourth root of unity I
77
+ // is free. This is true as long as I^2 = -1, which we assume.
78
+ //
79
+ // The main complexity of the code is due to the fact that the input
80
+ // is in the base field of the quadratic extension (henceforth we
81
+ // say that the input is "real"). Under this assumption, the output
82
+ // C is in the extension field ("complex"), but it is conjugate
83
+ // symmetric C[n-i] = conj(C[j]), so it has only n degrees of
84
+ // freedom and not 2n. Note that C[0] is real and, for even n,
85
+ // C[n/2] is also real.
86
+ //
87
+ // One neat way to store a conjugate-symmetric array C[] into a real
88
+ // array A[] is to say that A[j] = real(C[j]) for 2*j<=n, and A[j] =
89
+ // imag(C[j]) otherwise. See H. Sorensen, D. Jones, M. Heideman,
90
+ // and C. Burrus: "Real-valued fast Fourier transform algorithms"
91
+ // IEEE Transactions on Acoustics, Speech, and Signal Processing,
92
+ // Volume: 35, Issue: 6, June 1987. This idea is closely related to
93
+ // the storage layout in the Fast Discrete Hartley Transform.
94
+ // Following the terminology of the GNU Scientific Library, later
95
+ // also adopted by FFTW, we call this format the "half-complex"
96
+ // storage. Even though the implementation in file works only for N
97
+ // = 2^k, the half-complex format works for all N. For even n, a
98
+ // half-complex array contains n/2+1 real elements and n/2-1
99
+ // imaginary elements. This asymmetry requires special handling of
100
+ // the two excess real elements.
101
+ //
102
+ // Because the real input and the half-complex output have different
103
+ // types, we need to distinguish the real->half-complex transform
104
+ // from the half-complex->real transform. We now focus on the
105
+ // real->half-complex transform, with the understanding that the
106
+ // half-complex->real is the same process run backwards.
107
+ //
108
+ // Letting n = 2^k, each radix-4 step reduces k by 2. If k is odd,
109
+ // we must perform a radix-2 step somewhere, one can execute the
110
+ // radix-2 step at an arbitrary butterfly level in the algorithm.
111
+ // We choose to place the radix-2 step in the first butterfly level,
112
+ // which has no twiddle factors. To this end, r2hcI_2() implements
113
+ // a real->half-complex FFT of size 2, and r2hcI_4() implements a
114
+ // real->half-complex FFT of size 4.
115
+ //
116
+ // The remaining radix-4 butterflies are implemented in hc2hcf_4(),
117
+ // which is an ordinary decimation-in-time Cooley-Tukey butterfly
118
+ // hardcoding the fourth root of unity I (as opposed to -I).
119
+ // (Decimation-in-time means that the butterfly applies the twiddle
120
+ // factors first and then it applies the transform.)
121
+ //
122
+ // However, because of the two excess real elements in a
123
+ // half-complex array, hc2hcf_4() alone is not sufficient. The
124
+ // first butterfly of each level always has real inputs and no
125
+ // twiddle factors, and it can therefore be covered by r2hcI_4().
126
+ // The last bufferfly of each level also has real inputs with
127
+ // twiddle factors w_8^j, where w_8 is an eighth root of unity.
128
+ // This is occasionally called a type-II Fourier transform, by
129
+ // analogy with the so-called type-II Discrete Cosine Transform.
130
+ // r2hcII_4() hardcodes this latter case.
131
+ //
132
+ // For the complex FFT, both the decimation-in-time and
133
+ // decimation-in-frequency variants are possible. For
134
+ // real->half-complex, it seems like decimation-in-time is the only
135
+ // possibility.
136
+ // ------------------------------------------------------------
137
+ static void r2hcI_2(RElt* A, size_t s, const Field& R) {
138
+ RElt t = A[s];
139
+ A[s] = A[0];
140
+ R.add(A[0], t);
141
+ R.sub(A[s], t);
142
+ }
143
+
144
+ static void r2hcI_4(RElt* A, size_t s, const Field& R) {
145
+ RElt x0 = A[0];
146
+ RElt x1 = A[s];
147
+ RElt z0 = R.addf(x0, x1);
148
+ RElt x2 = A[2 * s];
149
+ RElt x3 = A[3 * s];
150
+ RElt z1 = R.addf(x2, x3);
151
+ A[0] = R.addf(z0, z1);
152
+ A[2 * s] = R.subf(z0, z1);
153
+ A[s] = R.subf(x0, x1);
154
+ A[3 * s] = R.subf(x3, x2);
155
+ }
156
+
157
+ // j = m/2 butterfly in the main loop, where w8^2 = I
158
+ static void r2hcII_4(RElt* A, size_t s, const CElt& w8, const Field& R) {
159
+ RElt x2 = A[2 * s];
160
+ RElt x3 = A[3 * s];
161
+ RElt z0 = R.addf(x2, x3);
162
+ RElt z1 = R.subf(x2, x3);
163
+ R.mul(z0, w8.im);
164
+ R.mul(z1, w8.re);
165
+ RElt x0 = A[0];
166
+ RElt x1 = A[s];
167
+ A[0] = R.addf(x0, z1);
168
+ A[s] = R.subf(x0, z1);
169
+ A[2 * s] = R.subf(x1, z0);
170
+ A[3 * s] = R.addf(x1, z0);
171
+ R.neg(A[3 * s]);
172
+ }
173
+
174
+ static void hc2hcf_4(RElt* Ar, RElt* Ai, size_t s, const CElt& tw1,
175
+ const CElt& tw2, const CElt& tw3, const Field& R) {
176
+ cmulj(&Ar[s], &Ai[s], tw2.re, tw2.im, R);
177
+ RElt y0r = R.addf(Ar[0], Ar[s]);
178
+ RElt y0i = R.addf(Ai[0], Ai[s]);
179
+ RElt y1r = R.subf(Ar[0], Ar[s]);
180
+ RElt y1i = R.subf(Ai[0], Ai[s]);
181
+ cmulj(&Ar[2 * s], &Ai[2 * s], tw1.re, tw1.im, R);
182
+ cmulj(&Ar[3 * s], &Ai[3 * s], tw3.re, tw3.im, R);
183
+ RElt y2r = R.addf(Ar[3 * s], Ar[2 * s]);
184
+ RElt y3r = R.subf(Ar[3 * s], Ar[2 * s]);
185
+ RElt y2i = R.addf(Ai[2 * s], Ai[3 * s]);
186
+ RElt y3i = R.subf(Ai[2 * s], Ai[3 * s]);
187
+ Ar[0] = R.addf(y0r, y2r);
188
+ Ai[s] = R.subf(y0r, y2r);
189
+ Ar[s] = R.addf(y1r, y3i);
190
+ Ai[0] = R.subf(y1r, y3i);
191
+ Ai[3 * s] = R.addf(y2i, y0i);
192
+ Ar[2 * s] = R.subf(y2i, y0i);
193
+ Ai[2 * s] = R.addf(y3r, y1i);
194
+ Ar[3 * s] = R.subf(y3r, y1i);
195
+ }
196
+
197
+ //------------------------------------------------------------
198
+ // Backward butterflies.
199
+ //
200
+ // "Backward" means sign +1 in the exponent of the twiddle
201
+ // factors.
202
+ //
203
+ // hc2rI_{2,4}: half-complex->real backward transform.
204
+ //
205
+ // hc2rIII_4: half-complex->real backward transform with w_8^j
206
+ // twiddle factors. This is sometimes called a type-III FFT with
207
+ // the understanding that the inverse of a type-II FFT is a
208
+ // type-III. The terminology is what it is.
209
+ //
210
+ // hc2hcb_4(): the main complex->complex backward butterfly. The
211
+ // backward algorithm is decimation-in-frequency, which means that
212
+ // the twiddle factors are applied at the end of the butterfly.
213
+ // ------------------------------------------------------------
214
+ static void hc2rI_2(RElt* A, size_t s, const Field& R) {
215
+ RElt t = A[s];
216
+ A[s] = A[0];
217
+ R.add(A[0], t);
218
+ R.sub(A[s], t);
219
+ }
220
+
221
+ static void hc2rI_4(RElt* A, size_t s, const Field& R) {
222
+ RElt y0 = R.addf(A[0], A[2 * s]);
223
+ RElt y1 = R.subf(A[0], A[2 * s]);
224
+ RElt y2 = R.addf(A[s], A[s]);
225
+ RElt y3 = R.addf(A[3 * s], A[3 * s]);
226
+ A[0] = R.addf(y0, y2);
227
+ A[s] = R.subf(y0, y2);
228
+ A[2 * s] = R.subf(y1, y3);
229
+ A[3 * s] = R.addf(y1, y3);
230
+ }
231
+
232
+ static void hc2rIII_4(RElt* A, size_t s, const CElt& w8, const Field& R) {
233
+ RElt x0 = R.addf(A[0], A[0]);
234
+ RElt x1 = R.addf(A[s], A[s]);
235
+ RElt x2 = R.addf(A[2 * s], A[2 * s]);
236
+ RElt x3 = R.addf(A[3 * s], A[3 * s]);
237
+ A[0] = R.addf(x0, x1);
238
+ A[s] = R.subf(x2, x3);
239
+ RElt z0 = R.subf(x0, x1);
240
+ R.mul(z0, w8.re);
241
+ RElt z1 = R.addf(x3, x2);
242
+ R.mul(z1, w8.im);
243
+ A[2 * s] = R.subf(z0, z1);
244
+ A[3 * s] = R.addf(z0, z1);
245
+ R.neg(A[3 * s]);
246
+ }
247
+
248
+ static void hc2hcb_4(RElt* Ar, RElt* Ai, size_t s, const CElt& tw1,
249
+ const CElt& tw2, const CElt& tw3, const Field& R) {
250
+ RElt z0 = R.addf(Ar[0], Ai[s]);
251
+ RElt z1 = R.subf(Ar[0], Ai[s]);
252
+ RElt z2 = R.addf(Ar[s], Ai[0]);
253
+ RElt z3 = R.subf(Ar[s], Ai[0]);
254
+ RElt z4 = R.addf(Ai[3 * s], Ar[2 * s]);
255
+ RElt z5 = R.subf(Ai[3 * s], Ar[2 * s]);
256
+ RElt z6 = R.addf(Ai[2 * s], Ar[3 * s]);
257
+ RElt z7 = R.subf(Ai[2 * s], Ar[3 * s]);
258
+ Ar[0] = R.addf(z0, z2);
259
+ Ai[0] = R.addf(z5, z7);
260
+ Ar[s] = R.subf(z0, z2);
261
+ Ai[s] = R.subf(z5, z7);
262
+ cmul(&Ar[s], &Ai[s], tw2.re, tw2.im, R);
263
+ Ar[2 * s] = R.subf(z1, z6);
264
+ Ai[2 * s] = R.addf(z4, z3);
265
+ cmul(&Ar[2 * s], &Ai[2 * s], tw1.re, tw1.im, R);
266
+ Ar[3 * s] = R.addf(z1, z6);
267
+ Ai[3 * s] = R.subf(z4, z3);
268
+ cmul(&Ar[3 * s], &Ai[3 * s], tw3.re, tw3.im, R);
269
+ }
270
+
271
+ public:
272
+ // Forward real to half-complex in-place transform.
273
+ // N (the length of A) must be a power of 2
274
+ static void r2hc(RElt A[/*n*/], size_t n, const CElt& omega,
275
+ uint64_t omega_order, const FieldExt& C) {
276
+ const Field& R = C.base_field();
277
+ validate_root(omega, C);
278
+
279
+ if (n == 2) {
280
+ r2hcI_2(A, 1, R);
281
+ } else if (n >= 4) {
282
+ CElt omega_n = Twiddle<FieldExt>::reroot(omega, omega_order, n, C);
283
+ Twiddle<FieldExt> roots(n, omega_n, C);
284
+ validate_I(roots.w_[n / 4], C);
285
+
286
+ Permutations<RElt>::bitrev(A, n);
287
+
288
+ size_t m = n;
289
+ while (m > 4) {
290
+ m /= 4;
291
+ }
292
+
293
+ if (m == 2) {
294
+ for (size_t k = 0; k < n; k += 2) {
295
+ r2hcI_2(&A[k], 1, R);
296
+ }
297
+ } else {
298
+ // m == 4
299
+ for (size_t k = 0; k < n; k += 4) {
300
+ r2hcI_4(&A[k], 1, R);
301
+ }
302
+ }
303
+
304
+ for (; m < n; m = 4 * m) {
305
+ size_t ws = n / (4 * m);
306
+ for (size_t k = 0; k < n; k += 4 * m) {
307
+ size_t j;
308
+ r2hcI_4(&A[k], m, R); // j==0
309
+
310
+ for (j = 1; j + j < m; ++j) {
311
+ hc2hcf_4(&A[k + j], &A[k + m - j], m, roots.w_[j * ws],
312
+ roots.w_[2 * j * ws], roots.w_[3 * j * ws], R);
313
+ }
314
+
315
+ r2hcII_4(&A[k + j], m, roots.w_[j * ws], R); // j==m/2
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+ // Backward half-complex to real in-place transform.
322
+ static void hc2r(RElt A[/*n*/], size_t n, const CElt& omega,
323
+ uint64_t omega_order, const FieldExt& C) {
324
+ const Field& R = C.base_field();
325
+ validate_root(omega, C);
326
+
327
+ if (n == 2) {
328
+ hc2rI_2(A, 1, R);
329
+ } else if (n >= 4) {
330
+ CElt omega_n = Twiddle<FieldExt>::reroot(omega, omega_order, n, C);
331
+ Twiddle<FieldExt> roots(n, omega_n, C);
332
+ validate_I(roots.w_[n / 4], C);
333
+
334
+ size_t m = n;
335
+
336
+ while (m > 4) {
337
+ m /= 4;
338
+ size_t ws = n / (4 * m);
339
+ for (size_t k = 0; k < n; k += 4 * m) {
340
+ size_t j;
341
+ hc2rI_4(&A[k], m, R); // j==0
342
+
343
+ for (j = 1; j + j < m; ++j) {
344
+ hc2hcb_4(&A[k + j], &A[k + m - j], m, roots.w_[j * ws],
345
+ roots.w_[2 * j * ws], roots.w_[3 * j * ws], R);
346
+ }
347
+
348
+ hc2rIII_4(&A[k + j], m, roots.w_[j * ws], R); // j==m/2
349
+ }
350
+ }
351
+
352
+ if (m == 2) {
353
+ for (size_t k = 0; k < n; k += 2) {
354
+ hc2rI_2(&A[k], 1, R);
355
+ }
356
+ } else {
357
+ // m == 4
358
+ for (size_t k = 0; k < n; k += 4) {
359
+ hc2rI_4(&A[k], 1, R);
360
+ }
361
+ }
362
+
363
+ Permutations<RElt>::bitrev(A, n);
364
+ }
365
+ }
366
+
367
+ // X *= B
368
+ static void cmul(RElt* xr, RElt* xi, const RElt& br, const RElt& bi,
369
+ const Field& R) {
370
+ // Karatsuba 3 mul + 5 add
371
+ RElt p0 = R.mulf(*xr, br);
372
+ RElt p1 = R.mulf(*xi, bi);
373
+ RElt a01 = R.addf(*xr, *xi);
374
+ RElt b01 = R.addf(br, bi);
375
+ *xr = R.subf(p0, p1);
376
+ R.mul(a01, b01);
377
+ R.sub(a01, p0);
378
+ R.sub(a01, p1);
379
+ *xi = a01;
380
+ }
381
+
382
+ // *X *= conj(B)
383
+ static void cmulj(RElt* xr, RElt* xi, const RElt& br, const RElt& bi,
384
+ const Field& R) {
385
+ // Karatsuba 3 mul + 5 add
386
+ RElt p0 = R.mulf(*xr, br);
387
+ RElt p1 = R.mulf(*xi, bi);
388
+ RElt a01 = R.addf(*xr, *xi);
389
+ RElt b01 = R.subf(br, bi);
390
+ *xr = R.addf(p0, p1);
391
+ R.mul(a01, b01);
392
+ R.sub(a01, p0);
393
+ R.add(a01, p1);
394
+ *xi = a01;
395
+ }
396
+ };
397
+
398
+ } // namespace proofs
399
+
400
+ #endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_RFFT_H_
@@ -0,0 +1,102 @@
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
+
16
+ #include "algebra/rfft.h"
17
+
18
+ #include <stddef.h>
19
+
20
+ #include <cstdint>
21
+ #include <vector>
22
+
23
+ #include "algebra/fft.h"
24
+ #include "algebra/fp2.h"
25
+ #include "algebra/fp_p256.h"
26
+ #include "gtest/gtest.h"
27
+
28
+ namespace proofs {
29
+ namespace {
30
+ TEST(RFFTTest, Simple) {
31
+ using BaseField = Fp256<>;
32
+ using BaseElt = BaseField::Elt;
33
+ using ExtField = Fp2<BaseField>;
34
+ using ExtElt = ExtField::Elt;
35
+
36
+ const BaseField F0; // base field
37
+ const ExtField F_ext(F0); // p^2 field extension
38
+
39
+ ExtElt omega0 = F_ext.of_string(
40
+ "112649224146410281873500457609690258373018840430489408729223714171582664"
41
+ "680802",
42
+ "840879943585409076957404614278186605601821689971823787493130182544504602"
43
+ "12908");
44
+ uint64_t omega_order = 1ull << 31;
45
+
46
+ // Try various roots of unity while maintaining the invariant that
47
+ // omega^{n/4} = I. The goal of this exercise is to make sure that
48
+ // the rfft does not depend on a specific 8-th root of unity.
49
+ //
50
+ // The actual root of unity used in the FFT is (omega^r) for r =
51
+ // omega_order / n, and omega^{r*n/4} = I (as opposed to -I) holds.
52
+ // Thus (omega^{1+4*j})^{r*n/4} = I also holds for all j, but the
53
+ // 8-th roots are different. Since there are only two eight roots
54
+ // of unity under the constraint, two iterations are sufficient.
55
+ //
56
+ ExtElt omega = omega0;
57
+ for (size_t iter = 0; iter < 2; ++iter) {
58
+ ExtElt one = F_ext.mulf(omega, F_ext.conjf(omega));
59
+ EXPECT_EQ(one, F_ext.one());
60
+
61
+ for (size_t n = 1; n < 1024; n *= 2) {
62
+ std::vector<BaseElt> AR0(n);
63
+ std::vector<BaseElt> AR1(n);
64
+ std::vector<ExtElt> AC(n);
65
+
66
+ // Arbitrary coefficients in base field. Keep three copies.
67
+ for (size_t i = 0; i < n; ++i) {
68
+ AR0[i] = F0.of_scalar(i * i * i + (i & 0xF) + (i ^ (i << 2)));
69
+ AR1[i] = AR0[i];
70
+ AC[i] = ExtElt{AR0[i]};
71
+ }
72
+
73
+ // compare RFFT against FFT
74
+ FFT<ExtField>::fftb(&AC[0], n, omega, omega_order, F_ext);
75
+ RFFT<ExtField>::r2hc(&AR0[0], n, omega, omega_order, F_ext);
76
+
77
+ for (size_t i = 0; i < n; ++i) {
78
+ if (i + i <= n) {
79
+ EXPECT_EQ(AR0[i], AC[i].re);
80
+ } else {
81
+ EXPECT_EQ(AR0[i], AC[i].im);
82
+ }
83
+ }
84
+
85
+ // invert and compare against AR1
86
+ RFFT<ExtField>::hc2r(&AR0[0], n, omega, omega_order, F_ext);
87
+ BaseElt scale = F0.of_scalar(n);
88
+ for (size_t i = 0; i < n; ++i) {
89
+ EXPECT_EQ(AR0[i], F0.mulf(scale, AR1[i]));
90
+ }
91
+ }
92
+
93
+ // advance root of unity
94
+ F_ext.mul(omega, omega0);
95
+ F_ext.mul(omega, omega0);
96
+ F_ext.mul(omega, omega0);
97
+ F_ext.mul(omega, omega0);
98
+ }
99
+ }
100
+
101
+ } // namespace
102
+ } // namespace proofs
@@ -0,0 +1,29 @@
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_STATIC_STRING_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_STATIC_STRING_H_
17
+
18
+ #include <cstddef>
19
+
20
+ // utility class to wrap pointers to compile-time
21
+ // constant strings
22
+ struct StaticString {
23
+ template <size_t N>
24
+ explicit StaticString(const char (&s)[N]) : as_pointer(s) {}
25
+
26
+ const char* as_pointer;
27
+ };
28
+
29
+ #endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_STATIC_STRING_H_