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,211 @@
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_SUMCHECK_QUAD_BUILDER_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_SUMCHECK_QUAD_BUILDER_H_
17
+
18
+ #include <stddef.h>
19
+
20
+ #include <cstdint>
21
+ #include <memory>
22
+ #include <unordered_map>
23
+ #include <vector>
24
+
25
+ #include "algebra/hash.h"
26
+ #include "sumcheck/equad.h"
27
+ #include "sumcheck/quad.h"
28
+ #include "util/panic.h"
29
+
30
+ // Helper functions for building quads. They should be used only
31
+ // by tests and the compiler, but not by the prover and verifier.
32
+ namespace proofs {
33
+
34
+ // helper class for builting the kvec_ vector
35
+ template <class Field>
36
+ class KvecBuilder {
37
+ using Elt = typename Field::Elt;
38
+ using kvec_t = std::vector<Elt>;
39
+
40
+ // Class that defines the hash function for Elt.
41
+ class EltHash {
42
+ public:
43
+ const Field& f_;
44
+ explicit EltHash(const Field& f) : f_(f) {}
45
+ size_t operator()(const Elt& k) const { return elt_hash(k, f_); }
46
+ };
47
+
48
+ public:
49
+ explicit KvecBuilder(const Field& f)
50
+ : table_(10, EltHash(f)), kvec_(std::make_shared<kvec_t>()) {}
51
+
52
+ size_t kstore(const Elt& k) {
53
+ auto [it, inserted] = table_.try_emplace(k, 0);
54
+ if (inserted) {
55
+ it->second = kvec_->size();
56
+ kvec_->push_back(k);
57
+ }
58
+ return it->second;
59
+ }
60
+
61
+ size_t kload(const Elt& k) const {
62
+ if (auto search = table_.find(k); search != table_.end()) {
63
+ return search->second;
64
+ }
65
+ check(false, "kload() failed");
66
+ return 0;
67
+ }
68
+
69
+ std::shared_ptr<kvec_t> kvec() { return kvec_; }
70
+
71
+ private:
72
+ std::unordered_map<Elt, size_t, EltHash> table_;
73
+ std::shared_ptr<kvec_t> kvec_;
74
+ };
75
+
76
+ // hasher for delta_corner
77
+ template <class Field>
78
+ struct delta_corner_hash {
79
+ using delta_corner = typename Quad<Field>::delta_corner;
80
+ static uint64_t hash_combine(uint64_t seed, uint64_t v) {
81
+ return (seed * 0x100000001b3ull) ^ v;
82
+ }
83
+ uint64_t operator()(const delta_corner& d) const {
84
+ uint64_t h = 0xcbf29ce484222325ull;
85
+ h = hash_combine(h, static_cast<uint32_t>(d.dg));
86
+ h = hash_combine(h, static_cast<uint32_t>(d.dh[0]));
87
+ h = hash_combine(h, static_cast<uint32_t>(d.dh[1]));
88
+ h = hash_combine(h, d.vi);
89
+ return h;
90
+ }
91
+ };
92
+
93
+ // helper class for building the delta_table_ vector
94
+ template <class Field>
95
+ class DeltaTableBuilder {
96
+ using quad_corner_t = typename Quad<Field>::quad_corner_t;
97
+ using delta_corner = typename Quad<Field>::delta_corner;
98
+ using delta_table_t = typename Quad<Field>::delta_table_t;
99
+
100
+ public:
101
+ DeltaTableBuilder() : delta_table_(std::make_shared<delta_table_t>()) {}
102
+
103
+ uint32_t dedup(quad_corner_t dg, quad_corner_t dh0, quad_corner_t dh1,
104
+ uint32_t vi) {
105
+ delta_corner d{dg, {dh0, dh1}, vi};
106
+ auto [it, inserted] = delta_map_.try_emplace(d, delta_table_->size());
107
+ if (inserted) {
108
+ delta_table_->push_back(d);
109
+ }
110
+ return it->second;
111
+ }
112
+
113
+ std::shared_ptr<delta_table_t> delta_table() { return delta_table_; }
114
+
115
+ private:
116
+ std::shared_ptr<delta_table_t> delta_table_;
117
+ std::unordered_map<delta_corner, uint32_t, delta_corner_hash<Field>>
118
+ delta_map_;
119
+ };
120
+
121
+ // ApproximateDeltaTableBuilder is like DeltaTableBuilder, but with a two-way
122
+ // set-associative cache instead of an exact hash table. We prefer quick lookup
123
+ // at the cost of missing some deduplications.
124
+ template <class Field>
125
+ class ApproximateDeltaTableBuilder {
126
+ using quad_corner_t = typename Quad<Field>::quad_corner_t;
127
+ using delta_corner = typename Quad<Field>::delta_corner;
128
+ using delta_table_t = typename Quad<Field>::delta_table_t;
129
+
130
+ public:
131
+ explicit ApproximateDeltaTableBuilder(size_t cache_size)
132
+ : delta_table_(std::make_shared<delta_table_t>()), cache_(cache_size) {}
133
+
134
+ uint32_t dedup(quad_corner_t dg, quad_corner_t dh0, quad_corner_t dh1,
135
+ uint32_t vi) {
136
+ delta_corner d{dg, {dh0, dh1}, vi};
137
+ size_t h = delta_corner_hash<Field>{}(d);
138
+ size_t idx = static_cast<size_t>(h % cache_.size());
139
+ CacheEntry& ent = cache_[idx];
140
+ if (ent.slots[0].valid && ent.slots[0].d == d) {
141
+ return ent.slots[0].index;
142
+ }
143
+ if (ent.slots[1].valid && ent.slots[1].d == d) {
144
+ // Maintain the LRU property that slot[0] is the most recently used.
145
+ std::swap(ent.slots[0], ent.slots[1]);
146
+ return ent.slots[0].index;
147
+ }
148
+
149
+ uint32_t index = delta_table_->size();
150
+ delta_table_->push_back(d);
151
+ // LRU eviction.
152
+ ent.slots[1] = ent.slots[0];
153
+ ent.slots[0] = {d, index, true};
154
+ return index;
155
+ }
156
+
157
+ std::shared_ptr<delta_table_t> delta_table() { return delta_table_; }
158
+
159
+ private:
160
+ struct Slot {
161
+ delta_corner d;
162
+ uint32_t index;
163
+ bool valid = false;
164
+ };
165
+
166
+ struct CacheEntry {
167
+ Slot slots[2];
168
+ };
169
+
170
+ std::shared_ptr<delta_table_t> delta_table_;
171
+ std::vector<CacheEntry> cache_;
172
+ };
173
+
174
+ template <class Field>
175
+ class QuadBuilder {
176
+ using Elt = typename Field::Elt;
177
+ using ecorner = typename EQuad<Field>::ecorner;
178
+ using index_t = typename EQuad<Field>::index_t;
179
+
180
+ public:
181
+ // Convert an EQuad into a Quad by collecting all constants in the
182
+ // EQuad. A more refined approach would collect all constants
183
+ // in all layers.
184
+ static std::unique_ptr<Quad<Field>> compress(const EQuad<Field>* EQUAD,
185
+ const Field& f) {
186
+ KvecBuilder<Field> kb(f);
187
+ // collect all constants
188
+ for (index_t i = 0; i < EQUAD->n_; ++i) {
189
+ (void)kb.kstore(EQUAD->ec_[i].v);
190
+ }
191
+
192
+ DeltaTableBuilder<Field> db;
193
+ auto q =
194
+ std::make_unique<Quad<Field>>(EQUAD->n_, kb.kvec(), db.delta_table());
195
+ using QuadCorner = typename Quad<Field>::quad_corner_t;
196
+ QuadCorner prev_g(0), prev_h0(0), prev_h1(0);
197
+ for (index_t i = 0; i < EQUAD->n_; ++i) {
198
+ const ecorner& eqi = EQUAD->ec_[i];
199
+ q->assign(i,
200
+ db.dedup(eqi.g - prev_g, eqi.h[0] - prev_h0, eqi.h[1] - prev_h1,
201
+ static_cast<uint32_t>(kb.kload(eqi.v))));
202
+ prev_g = eqi.g;
203
+ prev_h0 = eqi.h[0];
204
+ prev_h1 = eqi.h[1];
205
+ }
206
+ return q;
207
+ }
208
+ };
209
+ } // namespace proofs
210
+
211
+ #endif // PRIVACY_PROOFS_ZK_LIB_SUMCHECK_QUAD_BUILDER_H_
@@ -0,0 +1,169 @@
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 "sumcheck/quad.h"
16
+
17
+ #include <stddef.h>
18
+
19
+ #include <memory>
20
+ #include <utility>
21
+ #include <vector>
22
+
23
+ #include "algebra/bogorng.h"
24
+ #include "algebra/fp.h"
25
+ #include "arrays/affine.h"
26
+ #include "arrays/sparse.h"
27
+ #include "sumcheck/equad.h"
28
+ #include "sumcheck/hquad.h"
29
+ #include "sumcheck/quad_builder.h"
30
+ #include "gtest/gtest.h"
31
+
32
+ namespace proofs {
33
+ namespace {
34
+ typedef Fp<1> Field;
35
+ static const Field F("18446744073709551557");
36
+ typedef Field::Elt Elt;
37
+ Bogorng<Field> rng(&F);
38
+ typedef EQuad<Field>::quad_corner_t quad_corner_t;
39
+ typedef EQuad<Field>::index_t index_t;
40
+
41
+ class RandomSlice {
42
+ public:
43
+ std::vector<Elt> r_;
44
+ explicit RandomSlice(size_t n) : r_(n) {
45
+ for (size_t i = 0; i < n; ++i) {
46
+ r_[i] = rng.next();
47
+ }
48
+ }
49
+ };
50
+
51
+ Elt lagrange(quad_corner_t p, size_t logn, const Elt* R) {
52
+ Elt l = F.one();
53
+ for (size_t i = 0; i < logn; i++) {
54
+ if ((p & (quad_corner_t(1) << i)) != quad_corner_t(0)) {
55
+ F.mul(l, R[i]);
56
+ } else {
57
+ F.mul(l, F.subf(F.one(), R[i]));
58
+ }
59
+ }
60
+ return l;
61
+ }
62
+
63
+ void one_bind_g(index_t n, size_t logn) {
64
+ RandomSlice R(logn);
65
+ RandomSlice R2(logn);
66
+ auto EQUAD = std::make_unique<EQuad<Field>>(n);
67
+ Elt s = F.zero();
68
+ Elt s2 = F.zero();
69
+ Elt alpha = rng.next();
70
+ for (index_t i = 0; i < n; ++i) {
71
+ quad_corner_t p = quad_corner_t(13 * i);
72
+ Elt r = rng.next();
73
+ EQUAD->ec_[i] = EQuad<Field>::ecorner{
74
+ .g = p, .h = {quad_corner_t(0), quad_corner_t(0)}, .v = r};
75
+ F.add(s, F.mulf(r, lagrange(p, logn, R.r_.data())));
76
+ F.add(s2, F.mulf(r, lagrange(p, logn, R2.r_.data())));
77
+ }
78
+
79
+ auto QUAD = QuadBuilder<Field>::compress(EQUAD.get(), F);
80
+ auto HQUAD =
81
+ QUAD->bind_g(logn, R.r_.data(), R2.r_.data(), alpha, F.zero(), F);
82
+ EXPECT_EQ(HQUAD->scalar(), F.addf(s, F.mulf(alpha, s2)));
83
+ }
84
+
85
+ TEST(EQuad, BindG) {
86
+ one_bind_g(index_t(666), 10 + 4);
87
+ one_bind_g(index_t(1), 9 + 4);
88
+ for (size_t i = 200; i < 300; i++) {
89
+ one_bind_g(index_t(i), 9 + 4);
90
+ }
91
+ one_bind_g(index_t(467), 9 + 4);
92
+ one_bind_g(index_t(512), 9 + 4);
93
+ }
94
+
95
+ // compare interleaved binding of quad<> with
96
+ // a pair of bind_all() of Sparse<>.
97
+ void one_bind_h(index_t n, size_t logn) {
98
+ auto EQUAD = std::make_unique<EQuad<Field>>(n);
99
+ auto S = Sparse<Field>(n);
100
+ RandomSlice R0(logn);
101
+ RandomSlice R1(logn);
102
+ size_t mask = (size_t(1) << logn) - 1;
103
+ for (index_t i = 0; i < n; ++i) {
104
+ quad_corner_t h0 = quad_corner_t((13 * i + 4) & mask);
105
+ quad_corner_t h1 = quad_corner_t((23 * i + 3) & mask);
106
+
107
+ // EQuad<Field> canonicalizes h0, h1 because
108
+ // they are only used for a commutative F.mul,
109
+ // but Sparse<Field> does not, so we canonicalize
110
+ // h0, h1 in advance
111
+ if (h0 > h1) {
112
+ std::swap(h0, h1);
113
+ }
114
+
115
+ Elt r = rng.next();
116
+ EQUAD->ec_[i] =
117
+ EQuad<Field>::ecorner{.g = quad_corner_t(0), .h = {h0, h1}, .v = r};
118
+ S.c_[i] = Sparse<Field>::corner{
119
+ .p0 = 0, .p1 = corner_t(h0), .p2 = corner_t(h1), .v = r};
120
+ }
121
+
122
+ EQUAD->canonicalize(F);
123
+ S.canonicalize(F);
124
+ S.reshape();
125
+
126
+ S.bind_all(logn, R0.r_.data(), F);
127
+ S.reshape();
128
+ S.bind_all(logn, R1.r_.data(), F);
129
+ auto QUAD = QuadBuilder<Field>::compress(EQUAD.get(), F);
130
+ auto HQUAD = QUAD->bind_g(/*logv=*/0, nullptr, nullptr, /*alpha=*/F.zero(),
131
+ /*beta=*/F.zero(), F);
132
+
133
+ for (size_t round = 0; round < logn; ++round) {
134
+ HQUAD->bind_h(R0.r_[round], /*hand=*/0, F);
135
+ HQUAD->bind_h(R1.r_[round], /*hand=*/1, F);
136
+ }
137
+
138
+ EXPECT_EQ(HQUAD->scalar(), S.scalar());
139
+ }
140
+
141
+ TEST(EQuad, BindH) {
142
+ one_bind_h(index_t(666), 10);
143
+ one_bind_h(index_t(1), 9);
144
+ for (size_t i = 200; i < 300; i++) {
145
+ for (size_t logn = 1; logn < 20; ++logn) {
146
+ one_bind_h(index_t(i), logn);
147
+ }
148
+ }
149
+ one_bind_h(index_t(467), 9);
150
+ one_bind_h(index_t(512), 9);
151
+ one_bind_h(index_t(512), 33);
152
+ }
153
+
154
+ TEST(ApproximateDeltaTableBuilder, Basic) {
155
+ ApproximateDeltaTableBuilder<Field> db(10);
156
+ // These three should be different and likely hash to different buckets,
157
+ // but if they collide it's also fine for the builder's correctness.
158
+ db.dedup(quad_corner_t(1), quad_corner_t(2), quad_corner_t(3), 4);
159
+ db.dedup(quad_corner_t(5), quad_corner_t(6), quad_corner_t(7), 8);
160
+ db.dedup(quad_corner_t(1), quad_corner_t(2), quad_corner_t(3), 4);
161
+
162
+ auto table = db.delta_table();
163
+ // If no collision, size should be 2. If collision, size could be 3.
164
+ EXPECT_GE(table->size(), 2);
165
+ EXPECT_LE(table->size(), 3);
166
+ }
167
+
168
+ } // namespace
169
+ } // namespace proofs
@@ -0,0 +1,324 @@
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 <algorithm>
16
+ #include <cstdint>
17
+ #include <cstdlib>
18
+ #include <memory>
19
+ #include <utility>
20
+ #include <vector>
21
+
22
+ #include "algebra/bogorng.h"
23
+ #include "algebra/fp.h"
24
+ #include "arrays/affine.h"
25
+ #include "arrays/dense.h"
26
+ #include "random/transcript.h"
27
+ #include "sumcheck/circuit.h"
28
+ #include "sumcheck/equad.h"
29
+ #include "sumcheck/prover.h"
30
+ #include "sumcheck/quad.h"
31
+ #include "sumcheck/quad_builder.h"
32
+ #include "sumcheck/verifier.h"
33
+ #include "gtest/gtest.h"
34
+
35
+ namespace proofs {
36
+ namespace {
37
+ using Field = Fp<4>;
38
+ static const Field F(
39
+ "11579208923731619542357098500868790785326998466564056403945758400790883467"
40
+ "1663");
41
+ using Elt = typename Field::Elt;
42
+
43
+ Bogorng<Field> rng(&F);
44
+ using index_t = Quad<Field>::index_t;
45
+ using ecorner = EQuad<Field>::ecorner;
46
+ using quad_corner_t = Quad<Field>::quad_corner_t;
47
+
48
+ /* From https://eprint.iacr.org/2015/1060.pdf Algorithm 7: Complete,
49
+ projective point addition for prime order j-invariant 0 short
50
+ Weierstrass curves E/Fq : y^2 = x^3 + b.
51
+
52
+ X3 = (X1 Y2 + X2 Y1)(Y1 Y2 - 3b Z1 Z2) - 3b(Y1 Z2 + Y2 Z1)(X1 Z2 + X2 Z1)
53
+ Y3 = (Y1 Y2 + 3b Z1 Z2)(Y1 Y2 - 3b Z1 Z2) + 9b X1 X2 (X1 Z2 + X2 Z1)
54
+ Z3 = (Y1 Z2 + Y2 Z1)(Y1 Y2 + 3b Z1 Z2) + 3 X1 X2(X1 Y2 + X2 Y1)
55
+ */
56
+
57
+ constexpr uint64_t b = 7;
58
+ Elt kone = F.one(), k3 = F.of_scalar(3), k3b = F.of_scalar(3 * b),
59
+ k9b = F.of_scalar(9 * b);
60
+
61
+ void addE(Elt* X3, Elt* Y3, Elt* Z3, const Elt& X1, const Elt& Y1,
62
+ const Elt& Z1, const Elt& X2, const Elt& Y2, const Elt& Z2) {
63
+ // after common-subexpression elimination:
64
+ Elt t0 = F.mulf(X2, Y1);
65
+ Elt t1 = F.mulf(X1, Y2);
66
+ Elt t2 = F.addf(t1, t0);
67
+ Elt t3 = F.mulf(Y1, Y2);
68
+ Elt t4 = F.mulf(Z1, Z2);
69
+ Elt t5 = F.mulf(Y1, Z2);
70
+ Elt t6 = F.mulf(Y2, Z1);
71
+ Elt t7 = F.addf(t5, t6);
72
+ Elt t8 = F.mulf(X1, Z2);
73
+ Elt t9 = F.mulf(X2, Z1);
74
+ Elt t10 = F.addf(t8, t9);
75
+ Elt t11 = F.mulf(X1, X2);
76
+ Elt t12 = F.mulf(k3b, t4);
77
+ Elt t13 = F.addf(t3, t12);
78
+ Elt t14 = F.subf(t3, t12);
79
+
80
+ *X3 = F.subf(F.mulf(t2, t14), F.mulf(k3b, F.mulf(t7, t10)));
81
+ *Y3 = F.addf(F.mulf(t13, t14), F.mulf(k9b, F.mulf(t11, t10)));
82
+ *Z3 = F.addf(F.mulf(t7, t13), F.mulf(k3, F.mulf(t11, t2)));
83
+ }
84
+
85
+ /* Rewrite as quadratic forms in two layers:
86
+
87
+ L2:
88
+ t0 = (Y1 Y2 + 3b Z1 Z2)
89
+ t1 = (X1 Y2 + X2 Y1)
90
+ t2 = (Y1 Y2 - 3b Z1 Z2)
91
+ t3 = (Y1 Z2 + Y2 Z1)
92
+ t4 = (X1 Z2 + X2 Z1)
93
+ t5 = X1 X2
94
+
95
+ L1:
96
+ X3 = t1 t2 - 3b t3 t4
97
+ Y3 = t0 t2 + 9b t5 t4
98
+ Z3 = t3 t0 + 3 t5 t1
99
+ */
100
+
101
+ // input wires
102
+ enum { wX1, wY1, wZ1, wX2, wY2, wZ2 };
103
+
104
+ // t[i] implicitly i
105
+
106
+ // output wires
107
+ enum {
108
+ wX3,
109
+ wY3,
110
+ wZ3,
111
+ };
112
+
113
+ struct testquad {
114
+ Elt coef;
115
+ size_t g, l, r;
116
+ };
117
+
118
+ std::unique_ptr<Quad<Field>> sparse_of_testquad(size_t n,
119
+ const struct testquad* q) {
120
+ auto S = std::make_unique<EQuad<Field>>(n);
121
+
122
+ for (size_t i = 0; i < n; i++) {
123
+ auto l = q[i].l, r = q[i].r;
124
+
125
+ // canonicalize to l <= r
126
+ if (l > r) {
127
+ std::swap(l, r);
128
+ }
129
+
130
+ S->ec_[i] = ecorner{.g = quad_corner_t(q[i].g),
131
+ .h = {quad_corner_t(r), quad_corner_t(l)},
132
+ .v = q[i].coef};
133
+ }
134
+
135
+ S->canonicalize(F);
136
+ return QuadBuilder<Field>::compress(S.get(), F);
137
+ }
138
+
139
+ #define NELEM(x) (sizeof(x) / sizeof(x[0]))
140
+
141
+ std::unique_ptr<Quad<Field>> addE_quad0() {
142
+ testquad Q[] = {
143
+ // X3 = t1 t2 - 3b t3 t4
144
+ {kone, wX3, 1, 2},
145
+ {F.negf(k3b), wX3, 3, 4},
146
+
147
+ // Y3 = t0 t2 + 9b t5 t4
148
+ {kone, wY3, 0, 2},
149
+ {k9b, wY3, 5, 4},
150
+
151
+ // Z3 = t3 t0 + 3 t5 t1
152
+ {kone, wZ3, 3, 0},
153
+ {k3, wZ3, 5, 1},
154
+ };
155
+ return sparse_of_testquad(NELEM(Q), Q);
156
+ }
157
+
158
+ std::unique_ptr<Quad<Field>> addE_quad1() {
159
+ testquad Q[] = {
160
+ // t0 = (Y1 Y2 + 3b Z1 Z2)
161
+ {kone, 0, wY1, wY2},
162
+ {k3b, 0, wZ1, wZ2},
163
+
164
+ // t1 = (X1 Y2 + X2 Y1)
165
+ {kone, 1, wX1, wY2},
166
+ {kone, 1, wX2, wY1},
167
+
168
+ // t2 = (Y1 Y2 - 3b Z1 Z2)
169
+ {kone, 2, wY1, wY2},
170
+ {F.negf(k3b), 2, wZ1, wZ2},
171
+
172
+ // t3 = (Y1 Z2 + Y2 Z1)
173
+ {kone, 3, wY1, wZ2},
174
+ {kone, 3, wY2, wZ1},
175
+
176
+ // t4 = (X1 Z2 + X2 Z1)
177
+ {kone, 4, wX1, wZ2},
178
+ {kone, 4, wX2, wZ1},
179
+
180
+ // t5 = X1 X2
181
+ {kone, 5, wX1, wX2},
182
+ };
183
+ return sparse_of_testquad(NELEM(Q), Q);
184
+ }
185
+
186
+ std::unique_ptr<Circuit<Field>> addE_circuit(size_t logc, corner_t nc) {
187
+ std::unique_ptr<Circuit<Field>> c = std::make_unique<Circuit<Field>>();
188
+ *c = Circuit<Field>{
189
+ .nv = 3, // outputs
190
+ .logv = 2,
191
+ .nc = nc,
192
+ .logc = logc,
193
+ .nl = 2,
194
+ };
195
+ c->l.push_back(Layer<Field>{.nw = 6, .logw = 3, .quad = addE_quad0()});
196
+ c->l.push_back(Layer<Field>{.nw = 6, .logw = 3, .quad = addE_quad1()});
197
+
198
+ return c;
199
+ }
200
+
201
+ TEST(Sumcheck, EvalCircuit) {
202
+ size_t logc = 8;
203
+ corner_t nc = 209;
204
+ auto CIRCUIT = addE_circuit(logc, nc);
205
+ auto W = std::make_unique<Dense<Field>>(nc, 6);
206
+ for (corner_t i = 0; i < W->n0_ * W->n1_; ++i) {
207
+ W->v_[i] = rng.next();
208
+ }
209
+ Prover<Field>::inputs in;
210
+ Prover<Field> prover(F);
211
+ auto Wclone = W->clone();
212
+ const Dense<Field>* Wsave = &*Wclone;
213
+ auto V = prover.eval_circuit(&in, CIRCUIT.get(), std::move(Wclone), F);
214
+
215
+ EXPECT_EQ(Wclone.get(), nullptr); // moved to in(nl-1)
216
+ EXPECT_EQ(in[1].get(), Wsave);
217
+
218
+ for (corner_t i = 0; i < nc; ++i) {
219
+ Elt Xw, Yw, Zw;
220
+ addE(&Xw, &Yw, &Zw, (W->v_[i + nc * 0]), (W->v_[i + nc * 1]),
221
+ (W->v_[i + nc * 2]), (W->v_[i + nc * 3]), (W->v_[i + nc * 4]),
222
+ (W->v_[i + nc * 5]));
223
+
224
+ Elt X3 = V->v_[i + nc * 0], Y3 = (V->v_[i + nc * 1]),
225
+ Z3 = (V->v_[i + nc * 2]);
226
+ EXPECT_EQ(X3, Xw);
227
+ EXPECT_EQ(Y3, Yw);
228
+ EXPECT_EQ(Z3, Zw);
229
+ }
230
+
231
+ // create a proof for the side-effect of invoking the constructor/destructor
232
+ // to detect memory leaks
233
+ Proof<Field> P(CIRCUIT->nl);
234
+ }
235
+
236
+ void one_test_sumcheck_without_com(const Circuit<Field>* CIRCUIT) {
237
+ auto nc = CIRCUIT->nc;
238
+ auto nl = CIRCUIT->nl;
239
+
240
+ // random inputs
241
+ auto Wprover = std::make_unique<Dense<Field>>(nc, CIRCUIT->l[nl - 1].nw);
242
+ for (corner_t i = 0; i < Wprover->n0_ * Wprover->n1_; ++i) {
243
+ Wprover->v_[i] = rng.next();
244
+ }
245
+ auto Wverifier = Wprover->clone();
246
+
247
+ Proof<Field> proof(CIRCUIT->nl);
248
+ Prover<Field>::inputs in;
249
+ Prover<Field> prover(F);
250
+ auto V = prover.eval_circuit(&in, CIRCUIT, std::move(Wprover), F);
251
+
252
+ Transcript tsp((uint8_t *)"test", 4);
253
+ prover.prove(&proof, nullptr, CIRCUIT, in, tsp);
254
+
255
+ const char* why;
256
+ Transcript tsv((uint8_t *)"test", 4);
257
+ bool ok = Verifier<Field>::verify(&why, CIRCUIT, &proof, std::move(V),
258
+ std::move(Wverifier), tsv, F);
259
+ EXPECT_EQ(ok, true);
260
+ EXPECT_EQ(why, "ok");
261
+ }
262
+
263
+ void one_test_sumcheck(const Circuit<Field>* CIRCUIT) {
264
+ one_test_sumcheck_without_com(CIRCUIT);
265
+ }
266
+
267
+ TEST(Sumcheck, SumcheckAddE) {
268
+ auto CIRCUIT = addE_circuit(8, corner_t(177));
269
+ one_test_sumcheck(CIRCUIT.get());
270
+ }
271
+
272
+ TEST(Sumcheck, SumcheckAddEOneCopy) {
273
+ auto CIRCUIT = addE_circuit(0, corner_t(1));
274
+ one_test_sumcheck(CIRCUIT.get());
275
+ }
276
+
277
+ // ------------------------------------------------------------
278
+ // tests with random circuits
279
+ size_t around(size_t n) { return n + (std::rand() % n); }
280
+ quad_corner_t rand_corner(size_t n) { return quad_corner_t(std::rand()) % n; }
281
+
282
+ std::unique_ptr<Quad<Field>> random_quad(index_t n, corner_t nv, corner_t nw) {
283
+ auto S = std::make_unique<EQuad<Field>>(n);
284
+ for (index_t i = 0; i < n; i++) {
285
+ S->ec_[i] = ecorner{
286
+ .g = rand_corner(nv),
287
+ .h = {rand_corner(nw), rand_corner(nw)},
288
+ .v = rng.next(),
289
+ };
290
+ }
291
+ S->canonicalize(F);
292
+ return QuadBuilder<Field>::compress(S.get(), F);
293
+ }
294
+
295
+ std::unique_ptr<Circuit<Field>> random_circuit() {
296
+ std::unique_ptr<Circuit<Field>> CIRCUIT = std::make_unique<Circuit<Field>>();
297
+ *CIRCUIT = Circuit<Field>{
298
+ .nv = around(7),
299
+ .logv = 4,
300
+ .nc = around(12),
301
+ .logc = 5,
302
+ .nl = around(5),
303
+ };
304
+ size_t nv = CIRCUIT->nv;
305
+ for (size_t ly = 0; ly < CIRCUIT->nl; ++ly) {
306
+ corner_t nw = around(20);
307
+ CIRCUIT->l.push_back(Layer<Field>{
308
+ .nw = nw,
309
+ .logw = 6,
310
+ .quad = random_quad(around(300), nv, nw),
311
+ });
312
+ nv = nw; // outputs of next layer == inputs of this layer
313
+ }
314
+ return CIRCUIT;
315
+ }
316
+
317
+ TEST(Sumcheck, RandomCircuit) {
318
+ for (size_t i = 0; i < 10; ++i) {
319
+ auto CIRCUIT = random_circuit();
320
+ one_test_sumcheck(CIRCUIT.get());
321
+ }
322
+ }
323
+ } // namespace
324
+ } // namespace proofs