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,65 @@
1
+ // Copyright 2026 Google LLC.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_COMPILER_CIRCUIT_DUMP_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_COMPILER_CIRCUIT_DUMP_H_
17
+
18
+ #include <stddef.h>
19
+
20
+ #include "circuits/compiler/compiler.h"
21
+ #include "util/log.h"
22
+
23
+ // Debug printing routines for circuit tests.
24
+ namespace proofs {
25
+
26
+ template <class Field>
27
+ inline void dump_info(const char* name, size_t size,
28
+ const QuadCircuit<Field>& Q) {
29
+ log(INFO, "Compiled circuit: %s[%zu]", name, size);
30
+ dump_q(Q);
31
+ }
32
+
33
+ template <class Field>
34
+ inline void dump_info(const char* name, size_t sz0, size_t sz1,
35
+ const QuadCircuit<Field>& Q) {
36
+ log(INFO, "Compiled circuit: %s[%zu][%zu]", name, sz0, sz1);
37
+ dump_q(Q);
38
+ }
39
+
40
+ template <class Field>
41
+ inline void dump_info(const char* name, size_t sz0, size_t sz1, size_t sz2,
42
+ const QuadCircuit<Field>& Q) {
43
+ log(INFO, "Compiled circuit: %s[%zu][%zu][%zu]", name, sz0, sz1, sz2);
44
+ dump_q(Q);
45
+ }
46
+
47
+ template <class Field>
48
+ inline void dump_info(const char* name, const QuadCircuit<Field>& Q) {
49
+ log(INFO, "Compiled circuit: %s", name);
50
+ dump_q(Q);
51
+ }
52
+
53
+ template <class Field>
54
+ inline void dump_q(const QuadCircuit<Field>& Q) {
55
+ log(INFO,
56
+ " depth: %zu wires: %zu in: %zu out:%zu use:%zu ovh:%zu t:%zu cse:%zu "
57
+ "notn:%zu",
58
+ Q.depth_, Q.nwires_, Q.ninput_, Q.noutput_,
59
+ Q.nwires_ - Q.nwires_overhead_, Q.nwires_overhead_, Q.nquad_terms_,
60
+ Q.nwires_cse_eliminated_, Q.nwires_not_needed_);
61
+ }
62
+
63
+ } // namespace proofs
64
+
65
+ #endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_COMPILER_CIRCUIT_DUMP_H_
@@ -0,0 +1,471 @@
1
+ // Copyright 2026 Google LLC.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_COMPILER_COMPILER_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_COMPILER_COMPILER_H_
17
+
18
+ #include <stddef.h>
19
+ #include <stdint.h>
20
+
21
+ #include <algorithm>
22
+ #include <memory>
23
+ #include <vector>
24
+
25
+ #include "algebra/hash.h"
26
+ #include "circuits/compiler/node.h"
27
+ #include "circuits/compiler/pdqhash.h"
28
+ #include "circuits/compiler/schedule.h"
29
+ #include "sumcheck/circuit.h"
30
+ #include "sumcheck/circuit_id.h"
31
+ #include "sumcheck/quad.h"
32
+ #include "util/panic.h"
33
+
34
+ namespace proofs {
35
+ /*
36
+ QuadCircuit contains methods that facilitate defining circuits used to
37
+ express predicates that are to be proven or verified. This class allows one
38
+ to use basic arithmetic circuit operations (add, mul, input, assert0, ...)
39
+ to define the circuit on a set of abstract wire labels.
40
+
41
+ The "mkcircuit" compiler method than optimizes the circuit by applying all of
42
+ the basic tricks of constant propagation, common sub-expression elimination,
43
+ squashing layers into as few as possible, and grouping terms into quads.
44
+
45
+ Quads are a new form of gate (in contrast to the add and mul gates in most
46
+ sumcheck proof systems). Quads represent a "sum of quadratic terms" where
47
+ each term is w_l * w_r * v for two wire labels and a constant v.
48
+ */
49
+ template <class Field>
50
+ class QuadCircuit {
51
+ public:
52
+ using Elt = typename Field::Elt;
53
+ using nodeinfo = NodeInfoF<Field>;
54
+ using node = NodeF<Field>;
55
+ using size_t_for_storage = term::size_t_for_storage;
56
+ using quad_corner_t = typename Quad<Field>::quad_corner_t;
57
+
58
+ const Field& f_;
59
+
60
+ public:
61
+ // Variables for informational purposes:
62
+ size_t ninput_;
63
+ size_t npub_input_; // number of public inputs, index of 1st private
64
+ size_t subfield_boundary_; // least wire not known to be in the subfield
65
+ size_t noutput_;
66
+
67
+ // set by the algebraic simplifiers in this file
68
+ size_t depth_;
69
+ size_t nwires_cse_eliminated_;
70
+ size_t nwires_not_needed_;
71
+
72
+ // set by the scheduler
73
+ size_t nwires_;
74
+ size_t nquad_terms_;
75
+ size_t nwires_overhead_;
76
+
77
+ explicit QuadCircuit(const Field& f)
78
+ : f_(f),
79
+ ninput_(0),
80
+ npub_input_(0),
81
+ subfield_boundary_(0),
82
+ noutput_(0),
83
+ depth_(0),
84
+ nwires_cse_eliminated_(0),
85
+ nwires_not_needed_(0),
86
+ nwires_(-1), // undefined until set in mkcircuit()
87
+ nquad_terms_(-1),
88
+ nwires_overhead_(-1) {
89
+ // make sure that Elt(0) is represented as index 0 in the constant
90
+ // table.
91
+ size_t ki0 = kstore(f.zero());
92
+ proofs::check(ki0 == 0, "ki0 == 0");
93
+ size_t ki1 = kstore(f.one());
94
+ proofs::check(ki1 == 1, "ki1 == 1");
95
+
96
+ // make sure node 0 exists, carrying input[0] = F.one()
97
+ input_wire();
98
+ }
99
+
100
+ // Produce a linear term 1 * op0 that the compiler will not
101
+ // attempt to optimize to op0. The reason for this function
102
+ // is to implement linear terms such as a*x in the quadratic form
103
+ // a*x+b*x*y. Left to its own devices, the compiler peeks into x,
104
+ // and if x=k*z*w, it produces a term (a*k)*z*w in the previous
105
+ // layer, possibly destroying common subexpressions. linear(op)
106
+ // introduces an explicit multiplication by wire 0, which the
107
+ // compiler does not attempt to optimize away.
108
+ size_t linear(size_t op0) { return mul(0, op0); }
109
+ size_t linear(const Elt& k, size_t op0) { return mul(k, 0, op0); }
110
+
111
+ size_t mul(const Elt& k, size_t op) {
112
+ if (k == f_.zero()) {
113
+ return konst(k);
114
+ } else if (k == f_.one() || nodes_[op].zero()) {
115
+ return op;
116
+ } else {
117
+ return push_node(scale(k, op));
118
+ }
119
+ }
120
+
121
+ size_t mul(size_t op0, size_t op1) { return mul(f_.one(), op0, op1); }
122
+
123
+ size_t mul(const Elt& k, size_t op0, size_t op1) {
124
+ const auto& n0 = nodes_[op0];
125
+ const auto& n1 = nodes_[op1];
126
+
127
+ if (n0.zero()) {
128
+ return op0;
129
+ } else if (n0.constant()) {
130
+ // k * (k1 * op1) -> (k * k1) * op1
131
+ return mul(f_.mulf(k, kload(n0.terms[0].ki)), op1);
132
+ } else if (n0.linearp()) {
133
+ // k * ((k1 * op0) * op1) -> (k * k1) * op0 * op1
134
+ return mul(f_.mulf(k, kload(n0.terms[0].ki)), n0.terms[0].op1, op1);
135
+ } else if (n1.zero() || n1.constant() || n1.linearp()) {
136
+ return mul(k, op1, op0);
137
+ } else {
138
+ // general term k * op0 * op1
139
+ return push_node(node(kstore(k), op0, op1));
140
+ }
141
+ }
142
+
143
+ size_t add(size_t op0, size_t op1) {
144
+ const auto& n0 = nodes_[op0];
145
+ const auto& n1 = nodes_[op1];
146
+
147
+ if (n0.zero()) {
148
+ return op1;
149
+ } else if (n1.zero()) {
150
+ return op0;
151
+ } else {
152
+ // If the two addends are of different depth, do not merge
153
+ // them, which is accomplished by multiplying the shallower
154
+ // node by 1 and treating it as a single term of the final
155
+ // sum.
156
+ //
157
+ // Like many other "optimizations", this is a heuristic
158
+ // that may or may not work, but it seems to be uniformly
159
+ // beneficial or at least not harmful for all our circuits
160
+ // as of 2023-11-15.
161
+ if (n0.info.depth < n1.info.depth) {
162
+ op0 = linear(op0);
163
+ } else if (n1.info.depth < n0.info.depth) {
164
+ op1 = linear(op1);
165
+ }
166
+ return push_node(merge(op0, op1));
167
+ }
168
+ }
169
+ size_t sub(size_t op0, size_t op1) { return add(op0, mul(f_.mone(), op1)); }
170
+
171
+ size_t konst(const Elt& k) { return push_node(node(kstore(k), 0, 0)); }
172
+
173
+ // Generate a special node that asserts that op == 0.
174
+ // The node has the form 0*(1*op), which does not normally
175
+ // appear in circuits.
176
+ size_t assert0(size_t op) {
177
+ const node* n = &nodes_[op];
178
+ if (n->zero()) {
179
+ // Identically zero, so nothing to generate.
180
+ // More importantly, we cannot multiply OP by 1,
181
+ // since OP doesn't really exist.
182
+ return op;
183
+ } else if (n->linearp()) {
184
+ // n = k * (1 * op1).
185
+ //
186
+ // Reduce to assert0(op1), but handle the screw case k==0,
187
+ // which shouldn't happen but just in case...
188
+ if (n->terms[0].ki == 0) {
189
+ return op;
190
+ } else {
191
+ return assert0(n->terms[0].op1);
192
+ }
193
+ } else {
194
+ typename term::assert0_type_hack hack;
195
+ std::vector<term> terms;
196
+ terms.push_back(term(op, hack));
197
+ size_t n1 = push_node(node(terms));
198
+ nodes_[n1].info.is_assert0 = true;
199
+ return n1;
200
+ }
201
+ }
202
+
203
+ // Wrappers to avoid creating unnecessary wires. The
204
+ // compiler will discard them anyway, but they still take
205
+ // time and space.
206
+ size_t axpy(size_t y, const Elt& a, size_t x) {
207
+ if (a == f_.zero()) {
208
+ return y;
209
+ }
210
+ return add(y, linear(a, x));
211
+ }
212
+ size_t apy(size_t y, const Elt& a) {
213
+ if (a == f_.zero()) {
214
+ return y;
215
+ }
216
+ return add(y, konst(a));
217
+ }
218
+
219
+ // Create an input wire.
220
+ //
221
+ // Most code should never call this function directly. Call
222
+ // Logic::eltw_input() instead.
223
+ size_t input_wire() { return push_node(node(quad_corner_t(ninput_++))); }
224
+
225
+ // This function demarcates the end of the public inputs and beginning of
226
+ // private inputs. It can only be called once.
227
+ void private_input() {
228
+ proofs::check(
229
+ npub_input_ == 0,
230
+ "private_input can only be called once after setting public inputs");
231
+ npub_input_ = ninput_;
232
+ }
233
+
234
+ // This function demarcates the end of the private inputs in the
235
+ // subfield and beginning of the full-field private inputs. It can
236
+ // only be called once.
237
+ void begin_full_field() {
238
+ proofs::check(subfield_boundary_ == 0,
239
+ "begin_full_field() can only be called once");
240
+ subfield_boundary_ = ninput_;
241
+ }
242
+
243
+ size_t ninput() const { return ninput_; }
244
+
245
+ void output_wire(size_t n, size_t wire_id) {
246
+ output_internal(n, quad_corner_t(wire_id));
247
+ }
248
+
249
+ std::unique_ptr<Circuit<Field>> mkcircuit(size_t nc) {
250
+ size_t depth_ub = compute_depth_ub();
251
+ fixup_last_layer_assertions(depth_ub);
252
+ compute_needed(depth_ub);
253
+
254
+ Scheduler<Field> sched(nodes_, f_);
255
+ std::unique_ptr<Circuit<Field>> c =
256
+ sched.mkcircuit(constants_, depth_ub, nc);
257
+
258
+ // re-export the scheduler telemetry
259
+ nwires_ = sched.nwires_;
260
+ nquad_terms_ = sched.nquad_terms_;
261
+ nwires_overhead_ = sched.nwires_overhead_;
262
+
263
+ c->ninputs = ninput();
264
+ c->npub_in = npub_input_;
265
+ c->subfield_boundary = subfield_boundary_;
266
+
267
+ circuit_id(c->id, *c, f_);
268
+ return c;
269
+ }
270
+
271
+ private:
272
+ void output_internal(size_t n, quad_corner_t wire_id) {
273
+ nodes_[n].info.is_output = true;
274
+ nodes_[n].info.desired_wire_id_for_output = wire_id;
275
+ noutput_++;
276
+ }
277
+
278
+ size_t push_node(node n) {
279
+ // common-subexpression elimination: if we have already seen a
280
+ // node equal to n, return that node.
281
+ uint64_t d = n.hash();
282
+
283
+ auto pred = [&](PdqHash::value_t op) { return n == nodes_[op]; };
284
+ if (size_t op = cse_.find(d, pred); op != PdqHash::kNil) {
285
+ // do not linear terms as eliminated by the CSE, since they are
286
+ // likely placeholder nodes absorbed by the next layer.
287
+ if (!n.linearp()) {
288
+ ++nwires_cse_eliminated_;
289
+ }
290
+ return op;
291
+ }
292
+
293
+ // compute the node depth, which has been so far uninitialized
294
+ n.info.depth = 0;
295
+ for (const auto& t : n.terms) {
296
+ n.info.depth = std::max<size_t>(
297
+ n.info.depth, 1 + std::max<size_t>(nodes_[t.op0].info.depth,
298
+ nodes_[t.op1].info.depth));
299
+ }
300
+
301
+ size_t nid = nodes_.size();
302
+ nodes_.push_back(n);
303
+
304
+ // record NID into the common-subexpression elimination table
305
+ cse_.insert(d, nid);
306
+
307
+ return nid;
308
+ }
309
+
310
+ node materialize_input(size_t op) {
311
+ if (nodes_[op].info.is_input) {
312
+ return node(/*kstore(f.one())=*/1, 0, op);
313
+ } else {
314
+ return /*a copy of*/ nodes_[op];
315
+ }
316
+ }
317
+
318
+ node scale(const Elt& k, size_t op) {
319
+ node n = materialize_input(op);
320
+ for (auto& t : n.terms) {
321
+ t.ki = kstore(f_.mulf(kload(t.ki), k));
322
+ }
323
+ return n;
324
+ }
325
+
326
+ void push_back_unless_zero(std::vector<term>& terms, const term& t) const {
327
+ if (t.ki != 0) {
328
+ terms.push_back(t);
329
+ }
330
+ }
331
+
332
+ node merge(size_t op0, size_t op1) {
333
+ const node n0 = materialize_input(op0);
334
+ const node n1 = materialize_input(op1);
335
+ const std::vector<term>& t0 = n0.terms;
336
+ const std::vector<term>& t1 = n1.terms;
337
+ std::vector<term> terms;
338
+ size_t i0 = 0, i1 = 0;
339
+ while (i0 < t0.size() && i1 < t1.size()) {
340
+ term t;
341
+ if (t0[i0].eqndx(t1[i1])) {
342
+ t = t0[i0];
343
+ t.ki = kstore(f_.addf(kload(t.ki), kload(t1[i1].ki)));
344
+ i0++;
345
+ i1++;
346
+ } else if (t0[i0].ltndx(t1[i1])) {
347
+ t = t0[i0++];
348
+ } else {
349
+ t = t1[i1++];
350
+ }
351
+ push_back_unless_zero(terms, t);
352
+ }
353
+
354
+ while (i0 < t0.size()) {
355
+ push_back_unless_zero(terms, t0[i0++]);
356
+ }
357
+
358
+ while (i1 < t1.size()) {
359
+ push_back_unless_zero(terms, t1[i1++]);
360
+ }
361
+
362
+ return node(terms);
363
+ }
364
+
365
+ // constants_[n] stores the n-th constant, once.
366
+ // Modulo collisions, constants_[constttab_[hash(k)]] == k
367
+ // for k \in Elt.
368
+ std::vector<Elt> constants_;
369
+ PdqHash consttab_;
370
+
371
+ std::vector<node> nodes_;
372
+ PdqHash cse_;
373
+
374
+ size_t kstore(const Elt& k) {
375
+ uint64_t d = elt_hash(k, f_);
376
+ auto pred = [&](PdqHash::value_t ki) { return k == constants_[ki]; };
377
+ size_t ki = consttab_.find(d, pred);
378
+
379
+ if (ki == PdqHash::kNil) {
380
+ ki = constants_.size();
381
+ constants_.push_back(k);
382
+ consttab_.insert(d, ki);
383
+ }
384
+ return ki;
385
+ }
386
+ Elt& kload(size_t ki) { return constants_[ki]; }
387
+
388
+ void mark_needed(size_t op, size_t depth_at_which_needed) {
389
+ nodeinfo* nfo = &nodes_[op].info;
390
+ nfo->is_needed = true;
391
+ nfo->max_needed_depth =
392
+ std::max<size_t>(depth_at_which_needed, nfo->max_needed_depth);
393
+
394
+ // If DEPTH_AT_WHICH_NEEDED > DEPTH + 1, we need a constant 1 at
395
+ // depth DEPTH_AT_WHICH_NEEDED-1 (and implicily any lower depths) in
396
+ // order to copy the node across levels.
397
+ if (depth_at_which_needed > nfo->depth + 1) {
398
+ nodeinfo* nfo0 = &nodes_[0].info;
399
+ nfo0->is_needed = true;
400
+ nfo0->max_needed_depth =
401
+ std::max<size_t>(depth_at_which_needed - 1, nfo0->max_needed_depth);
402
+ }
403
+ }
404
+
405
+ size_t compute_depth_ub() {
406
+ size_t r = 0;
407
+ for (auto& n : nodes_) {
408
+ if (n.info.is_output) {
409
+ r = std::max<size_t>(r, 1 + n.info.depth);
410
+ } else if (n.info.is_assert0) {
411
+ // Assertions of the form 0*(1*OP) contribute n.info.depth and
412
+ // not 1 + n.info.depth. If the assertion is in the last
413
+ // layer, it will be transformed in an output of OP at
414
+ // n.info.depth. If the assertion is not in the last layer,
415
+ // then it doesn't matter whether we use DEPTH or 1 + DEPTH.
416
+ if (n.linearp()) {
417
+ r = std::max<size_t>(r, n.info.depth);
418
+ } else {
419
+ r = std::max<size_t>(r, 1 + n.info.depth);
420
+ }
421
+ }
422
+ }
423
+ depth_ = r;
424
+ return r;
425
+ }
426
+
427
+ void fixup_last_layer_assertions(size_t depth_ub) {
428
+ // convert assertions in the last layer into outputs
429
+ for (auto& n : nodes_) {
430
+ if (!n.info.is_output && n.info.is_assert0 && n.info.depth == depth_ub &&
431
+ n.linearp()) {
432
+ n.info.is_assert0 = false;
433
+ output_internal(n.terms[0].op1, nodeinfo::kWireIdUndefined);
434
+ }
435
+ }
436
+ }
437
+
438
+ void compute_needed(size_t depth_ub) {
439
+ nwires_not_needed_ = 0;
440
+ for (size_t i = nodes_.size(); i-- > 0;) {
441
+ nodeinfo* nfo = &nodes_[i].info;
442
+
443
+ // mark all inputs as needed, to prevent ambiguity
444
+ // in the layout of the W[] vector.
445
+ if (nfo->is_input) {
446
+ mark_needed(i, 1);
447
+ }
448
+ // outputs are needed at depth_ub_
449
+ if (nfo->is_output) {
450
+ mark_needed(i, depth_ub);
451
+ }
452
+ // assertions are needed in the next layer
453
+ if (nfo->is_assert0) {
454
+ mark_needed(i, nfo->depth + 1);
455
+ }
456
+
457
+ if (nfo->is_needed) {
458
+ for (const auto& t : nodes_[i].terms) {
459
+ mark_needed(t.op0, nfo->depth);
460
+ mark_needed(t.op1, nfo->depth);
461
+ }
462
+ } else {
463
+ ++nwires_not_needed_;
464
+ }
465
+ }
466
+ }
467
+ };
468
+
469
+ } // namespace proofs
470
+
471
+ #endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_COMPILER_COMPILER_H_
@@ -0,0 +1,110 @@
1
+ // Copyright 2026 Google LLC.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #include "circuits/compiler/compiler.h"
16
+
17
+ #include <stddef.h>
18
+
19
+ #include <memory>
20
+
21
+ #include "algebra/fp.h"
22
+ #include "arrays/dense.h"
23
+ #include "circuits/compiler/circuit_dump.h"
24
+ #include "sumcheck/circuit.h"
25
+ #include "sumcheck/testing.h"
26
+ #include "gtest/gtest.h"
27
+
28
+ namespace proofs {
29
+ namespace {
30
+ typedef Fp<1> Field;
31
+ const Field F("18446744073709551557");
32
+
33
+ TEST(Compiler, OutputAnInput) {
34
+ // screw case of outputting an input wire directly
35
+ QuadCircuit<Field> Q(F);
36
+
37
+ size_t a = Q.input_wire();
38
+ size_t b = Q.input_wire();
39
+ size_t c = Q.input_wire();
40
+
41
+ Q.output_wire(a, 0);
42
+ // add some depth
43
+ Q.output_wire(Q.mul(b, c), 1);
44
+
45
+ auto CIRCUIT = Q.mkcircuit(1);
46
+ EXPECT_EQ(Q.nwires_,
47
+ /*one=*/1u + /*inputs=*/3u + /*mul(b,c)=*/1u + /*copy(a)*/ 1u);
48
+ }
49
+
50
+ TEST(Compiler, AliasOfLinearAndCopyWire) {
51
+ // Screw case creating an explicit linear term 1*n
52
+ // at the same time as n is copied by the scheduler
53
+ QuadCircuit<Field> Q(F);
54
+
55
+ size_t a = Q.input_wire();
56
+ Q.output_wire(a, 0);
57
+ Q.output_wire(Q.linear(a), 1);
58
+ auto CIRCUIT = Q.mkcircuit(1);
59
+ dump_info<Field>("AliasOfLinearAndCopyWire", Q);
60
+ EXPECT_EQ(Q.nwires_,
61
+ /*one*/ 1u + /*a*/ 1u + /*copy of a at d=2*/ 1u + /*linear(a)=*/1u);
62
+ }
63
+
64
+ TEST(Compiler, Assert0) {
65
+ QuadCircuit<Field> Q(F);
66
+
67
+ // circuit verifies that a + b = c
68
+ size_t a = Q.input_wire();
69
+ size_t b = Q.input_wire();
70
+ size_t c = Q.input_wire();
71
+
72
+ Q.assert0(Q.sub(Q.add(a, b), c));
73
+
74
+ size_t nc = 1;
75
+ auto CIRCUIT = Q.mkcircuit(nc);
76
+ dump_info<Field>("assert0", Q);
77
+
78
+ Dense<Field> W(nc, 1 + 3);
79
+ W.v_[0] = F.one();
80
+ W.v_[1] = F.of_scalar(3);
81
+ W.v_[2] = F.of_scalar(5);
82
+ W.v_[3] = F.of_scalar(8);
83
+
84
+ // no outputs
85
+ Proof<Field> pr(CIRCUIT->nl);
86
+ run_prover<Field>(CIRCUIT.get(), W.clone(), &pr, F);
87
+ run_verifier<Field>(CIRCUIT.get(), W.clone(), pr, F);
88
+ }
89
+
90
+ TEST(Compiler, Output0) {
91
+ QuadCircuit<Field> Q(F);
92
+
93
+ size_t a = Q.konst(F.two());
94
+ size_t b = Q.konst(F.one());
95
+ size_t c = Q.mul(a, b);
96
+ size_t d = Q.sub(a, c);
97
+ Q.output_wire(d, 0);
98
+
99
+ size_t nc = 1;
100
+ auto CIRCUIT = Q.mkcircuit(nc);
101
+ dump_info<Field>("output0", Q);
102
+
103
+ EXPECT_EQ(Q.ninput_, 1u);
104
+ EXPECT_EQ(Q.noutput_, 1u);
105
+ EXPECT_EQ(Q.nwires_, 1u);
106
+ EXPECT_EQ(Q.nquad_terms_, 0u);
107
+ }
108
+
109
+ } // namespace
110
+ } // namespace proofs