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,201 @@
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_ECDSA_VERIFY_WITNESS_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_ECDSA_VERIFY_WITNESS_H_
17
+
18
+ #include <cstddef>
19
+
20
+ #include "algebra/utility.h"
21
+ #include "arrays/dense.h"
22
+ #include "util/panic.h"
23
+
24
+ /*
25
+ Methods to help prepare witnesses for use in assertions about ecdsa.
26
+ */
27
+ namespace proofs {
28
+
29
+ template <class EC, class ScalarField>
30
+ class VerifyWitness3 {
31
+ using Field = typename EC::Field;
32
+ using Elt = typename Field::Elt;
33
+ using Nat = typename Field::N;
34
+ using Point = typename EC::ECPoint;
35
+ using Scalar = typename ScalarField::Elt;
36
+
37
+ public:
38
+ constexpr static size_t kBits = EC::kBits;
39
+ const ScalarField& fn_;
40
+ const EC& ec_;
41
+ Elt rx_, ry_;
42
+ Elt rx_inv_;
43
+ Elt s_inv_;
44
+ Elt pk_inv_;
45
+ Elt pre_[8];
46
+ Elt bi_[kBits];
47
+ Elt int_x_[kBits]; /* Intermediate x,y elliptic curve points */
48
+ Elt int_y_[kBits]; /* encountered during the scalar mult loop. */
49
+ Elt int_z_[kBits]; /* z-coordinate of the intermediate points */
50
+
51
+ VerifyWitness3(const ScalarField& Fn, const EC& ec) : fn_(Fn), ec_(ec) {}
52
+
53
+ void fill_witness(DenseFiller<Field>& filler) const {
54
+ filler.push_back(rx_);
55
+ filler.push_back(ry_);
56
+ filler.push_back(rx_inv_);
57
+ filler.push_back(s_inv_);
58
+ filler.push_back(pk_inv_);
59
+ for (size_t i = 0; i < 8; ++i) {
60
+ filler.push_back(pre_[i]);
61
+ }
62
+ for (size_t i = 0; i < kBits; ++i) {
63
+ filler.push_back(bi_[i]);
64
+ if (i < kBits - 1) {
65
+ filler.push_back(int_x_[i]);
66
+ filler.push_back(int_y_[i]);
67
+ filler.push_back(int_z_[i]);
68
+ }
69
+ }
70
+ }
71
+
72
+ // Produces witnesses to support the verification of the equation
73
+ // id = g*e + pk*r + (rx,ry)*-s
74
+ // Note that the same rx is interpreted in scalar field as r.
75
+ bool compute_witness(const Elt pkX, const Elt pkY, const Nat e, const Nat r,
76
+ const Nat s) {
77
+ const Field& F = ec_.f_;
78
+ const Scalar _s = fn_.invertf(fn_.to_montgomery(s));
79
+ const Scalar tms = fn_.negf(fn_.to_montgomery(s));
80
+
81
+ // Because Fp does not have a sqrt method, compute ry via the
82
+ // elliptic curve point g*(e/s) + pk*(r/s).
83
+ auto te_s = fn_.mulf(fn_.to_montgomery(e), _s);
84
+ auto tr_s = fn_.mulf(fn_.to_montgomery(r), _s);
85
+ const Nat nes = fn_.from_montgomery(te_s);
86
+ const Nat nrs = fn_.from_montgomery(tr_s);
87
+ Point bases[] = {ec_.generator(), Point(pkX, pkY, F.one())};
88
+ Nat scalars[] = {nes, nrs};
89
+ auto pr = ec_.scalar_multf(2, bases, scalars);
90
+ ec_.normalize(pr);
91
+
92
+ rx_ = F.to_montgomery(r);
93
+ ry_ = pr.y;
94
+
95
+ // In the case of a malicious input with rx=0 or s=0, the proof will fail.
96
+ if (rx_ != F.zero()) {
97
+ rx_inv_ = F.invertf(rx_);
98
+ check(F.mulf(rx_, rx_inv_) == F.one(), "bad inv");
99
+ }
100
+
101
+ s_inv_ = F.to_montgomery(fn_.from_montgomery(tms));
102
+ if (s_inv_ != F.zero()) {
103
+ F.invert(s_inv_);
104
+ }
105
+
106
+ if (pkX != F.zero()) {
107
+ pk_inv_ = F.invertf(pkX);
108
+ }
109
+
110
+ const Nat nms = fn_.from_montgomery(tms); /* -s */
111
+
112
+ // Produce the table of pre-computed g,r,pk sums.
113
+ const Elt one = F.one(), gX = ec_.gx_, gY = ec_.gy_;
114
+ const Elt lh[] = {gX, gY, gX, gY, pkX, pkY};
115
+ const Elt rh[] = {pkX, pkY, rx_, ry_, rx_, ry_};
116
+ Elt zi;
117
+ for (size_t i = 0; i < 3; ++i) {
118
+ ec_.addE(pre_[2 * i], pre_[2 * i + 1], zi,
119
+ lh[2 * i], lh[2 * i + 1], one,
120
+ rh[2 * i], rh[2 * i + 1], one);
121
+
122
+ // This invert cannot fail because both the generator and pk are
123
+ // trusted inputs, so the above addition is not the identity.
124
+ // In the case that it is, the proof will fail (and it should, since
125
+ // the system is unsound with sk=-1).
126
+ if (zi != F.zero()) {
127
+ F.invert(zi);
128
+ }
129
+ F.mul(pre_[2 * i], zi);
130
+ F.mul(pre_[2 * i + 1], zi);
131
+ }
132
+ // rgpk
133
+ ec_.addE(pre_[6], pre_[7], zi, pre_[2], pre_[3], one, pkX, pkY, one);
134
+ if (zi != F.zero()) {
135
+ F.invert(zi);
136
+ }
137
+ F.mul(pre_[6], zi);
138
+ F.mul(pre_[7], zi);
139
+
140
+ Elt aX = F.zero(), aY = one, aZ = F.zero();
141
+
142
+ // Compute b[], and intermediate points, encode b as:
143
+ // 1:g 2:pk 3: gpk 4: r 5: r+g 6: r+pk 7:g+r+pk
144
+ // Elt int_z[kBits];
145
+ size_t b[kBits];
146
+ // bool early_zero = false; /* indicates if any intermediate z is zero */
147
+ for (size_t i = 0; i < kBits; ++i) {
148
+ b[i] = e.bit(kBits - i - 1) + 2 * r.bit(kBits - i - 1) +
149
+ 4 * nms.bit(kBits - i - 1);
150
+
151
+ // Manually compute standard (-n...n representation).
152
+ bi_[i] = F.subf(F.of_scalar(2 * b[i]), F.of_scalar(7));
153
+
154
+ if (i > 0) {
155
+ ec_.doubleE(aX, aY, aZ, aX, aY, aZ);
156
+ }
157
+ switch (b[i]) {
158
+ case 0:
159
+ ec_.addE(aX, aY, aZ, aX, aY, aZ, F.zero(), F.one(), F.zero());
160
+ break;
161
+ case 1:
162
+ ec_.addE(aX, aY, aZ, aX, aY, aZ, gX, gY, one);
163
+ break;
164
+ case 2:
165
+ ec_.addE(aX, aY, aZ, aX, aY, aZ, pkX, pkY, one);
166
+ break;
167
+ case 3:
168
+ ec_.addE(aX, aY, aZ, aX, aY, aZ, pre_[0], pre_[1], one);
169
+ break;
170
+ case 4:
171
+ ec_.addE(aX, aY, aZ, aX, aY, aZ, rx_, ry_, one);
172
+ break;
173
+ case 5:
174
+ ec_.addE(aX, aY, aZ, aX, aY, aZ, pre_[2], pre_[3], one);
175
+ break;
176
+ case 6:
177
+ ec_.addE(aX, aY, aZ, aX, aY, aZ, pre_[4], pre_[5], one);
178
+ break;
179
+ case 7:
180
+ ec_.addE(aX, aY, aZ, aX, aY, aZ, pre_[6], pre_[7], one);
181
+ break;
182
+ }
183
+
184
+ int_x_[i] = aX;
185
+ int_y_[i] = aY;
186
+ int_z_[i] = aZ;
187
+ }
188
+
189
+ if (aX != F.zero()) {
190
+ return false;
191
+ }
192
+ if (aZ != F.zero()) {
193
+ return false;
194
+ }
195
+
196
+ return true;
197
+ }
198
+ };
199
+ } // namespace proofs
200
+
201
+ #endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_ECDSA_VERIFY_WITNESS_H_
@@ -0,0 +1,140 @@
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_LOGIC_BIT_ADDER_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_ADDER_H_
17
+
18
+ #include <stddef.h>
19
+
20
+ #include <cstdint>
21
+ #include <initializer_list>
22
+ #include <vector>
23
+
24
+ // Circuit element that maps bitvec<N> V to a field element E
25
+ // in such a way that:
26
+ //
27
+ // 1) addition can be performed efficiently, e.g. as field
28
+ // addition or field multiplication
29
+ // 2) given and E that is the sum of K bitvecs, a simple circuit
30
+ // asserts that E = A mod 2^N
31
+ namespace proofs {
32
+
33
+ template <class Logic, size_t N, bool kCharacteristicTwo>
34
+ class BitAdderAux;
35
+
36
+ // Use the additive group in fields with large characteristic
37
+ template <class Logic, size_t N>
38
+ class BitAdderAux<Logic, N, /*kCharacteristicTwo=*/false> {
39
+ public:
40
+ using Field = typename Logic::Field;
41
+ using BitW = typename Logic::BitW;
42
+ using EltW = typename Logic::EltW;
43
+ using Elt = typename Field::Elt;
44
+ using BV = typename Logic::template bitvec<N>;
45
+ const Logic& l_;
46
+
47
+ explicit BitAdderAux(const Logic& l) : l_(l) {}
48
+
49
+ EltW as_field_element(const BV& v) const {
50
+ constexpr uint64_t uno = 1;
51
+ EltW r = l_.konst(l_.zero());
52
+ for (size_t i = 0; i < N; ++i) {
53
+ r = l_.axpy(r, l_.elt(uno << i), l_.eval(v[i]));
54
+ }
55
+ return r;
56
+ }
57
+
58
+ EltW add(const EltW& a, const EltW& b) const { return l_.add(a, b); }
59
+ EltW add(const BV& a, const BV& b) const {
60
+ return add(as_field_element(a), as_field_element(b));
61
+ }
62
+ EltW add(
63
+ std::initializer_list<typename Logic::template bitvec_view<N>> a) const {
64
+ return l_.add(0, a.size(), [&](size_t i) {
65
+ return as_field_element(*(a.begin()[i].ptr));
66
+ });
67
+ }
68
+
69
+ // assert that B = A + i*2^N for 0 <= i < k
70
+ void assert_eqmod(const BV& a, const EltW& b, size_t k) const {
71
+ constexpr uint64_t uno = 1;
72
+ EltW z = l_.sub(b, as_field_element(a));
73
+ EltW zz = l_.mul(
74
+ 0, k, [&](size_t i) { return l_.sub(z, l_.konst((uno << N) * i)); });
75
+ l_.assert0(zz);
76
+ }
77
+ };
78
+
79
+ // Use the multiplicative group in GF(2^k)
80
+ template <class Logic, size_t N>
81
+ class BitAdderAux<Logic, N, /*kCharacteristicTwo=*/true> {
82
+ public:
83
+ using Field = typename Logic::Field;
84
+ using BitW = typename Logic::BitW;
85
+ using EltW = typename Logic::EltW;
86
+ using Elt = typename Field::Elt;
87
+ using BV = typename Logic::template bitvec<N>;
88
+ const Logic& l_;
89
+
90
+ explicit BitAdderAux(const Logic& l) : l_(l) {
91
+ // assume that X is a root of unity of order large enough.
92
+ Elt alpha = l_.f_.x();
93
+
94
+ for (size_t i = 0; i < N; ++i) {
95
+ alpha_2_i_[i] = alpha;
96
+ alpha = l_.mulf(alpha, alpha);
97
+ }
98
+ alpha_2_n_ = alpha;
99
+ }
100
+
101
+ EltW as_field_element(const BV& v) const {
102
+ return l_.mul(0, N, [&](size_t i) {
103
+ return l_.mux(v[i], l_.konst(alpha_2_i_[i]), l_.konst(l_.one()));
104
+ });
105
+ }
106
+
107
+ EltW add(const EltW& a, const EltW& b) const { return l_.mul(a, b); }
108
+ EltW add(const BV& a, const BV& b) const {
109
+ return add(as_field_element(a), as_field_element(b));
110
+ }
111
+ EltW add(
112
+ std::initializer_list<typename Logic::template bitvec_view<N>> a) const {
113
+ return l_.mul(0, a.size(), [&](size_t i) {
114
+ return as_field_element(*(a.begin()[i].ptr));
115
+ });
116
+ }
117
+
118
+ // assert that B = A + alpha^(i*2^N) for 0 <= i < k
119
+ void assert_eqmod(const BV& a, const EltW& b, size_t k) const {
120
+ std::vector<Elt> p(k);
121
+ p[0] = l_.f_.one();
122
+ for (size_t i = 1; i < k; ++i) {
123
+ p[i] = l_.f_.mulf(alpha_2_n_, p[i - 1]);
124
+ }
125
+ EltW aa = as_field_element(a);
126
+ EltW prod = l_.mul(
127
+ 0, k, [&](size_t i) { return l_.sub(b, l_.mul(l_.konst(p[i]), aa)); });
128
+ l_.assert0(prod);
129
+ }
130
+
131
+ private:
132
+ Elt alpha_2_i_[N + 1];
133
+ Elt alpha_2_n_;
134
+ };
135
+
136
+ template <class Logic, size_t N>
137
+ using BitAdder = BitAdderAux<Logic, N, Logic::Field::kCharacteristicTwo>;
138
+ } // namespace proofs
139
+
140
+ #endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_ADDER_H_
@@ -0,0 +1,64 @@
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/logic/bit_adder.h"
16
+
17
+ #include <stddef.h>
18
+
19
+
20
+ #include "algebra/fp_p128.h"
21
+ #include "circuits/logic/evaluation_backend.h"
22
+ #include "circuits/logic/logic.h"
23
+ #include "gf2k/gf2_128.h"
24
+ #include "gtest/gtest.h"
25
+
26
+ namespace proofs {
27
+ namespace {
28
+
29
+ template <class Field>
30
+ void test_bit_adder() {
31
+ constexpr size_t w = 4;
32
+ constexpr size_t mask = (1 << w) - 1;
33
+ const Field F;
34
+
35
+ using EvalBackend = EvaluationBackend<Field>;
36
+ using Logic = Logic<Field, EvalBackend>;
37
+ using BV = typename Logic::template bitvec<w>;
38
+ for (size_t a = 0; a < (1 << w); ++a) {
39
+ for (size_t b = 0; b < (1 << w); ++b) {
40
+ for (size_t c = 0; c < (1 << w); ++c) {
41
+ for (size_t s = 0; s < (1 << w); ++s) {
42
+ const EvalBackend ebk(F, /* panic_on_assertion_failure=*/false);
43
+ const Logic L(&ebk, F);
44
+ BV ea = L.template vbit<w>(a);
45
+ BV eb = L.template vbit<w>(b);
46
+ BV ec = L.template vbit<w>(c);
47
+ BV es = L.template vbit<w>(s);
48
+
49
+ BitAdder<Logic, w> BA(L);
50
+ BA.assert_eqmod(es, BA.add({ea, eb, ec}), 3);
51
+ EXPECT_EQ(ebk.assertion_failed(), (((a + b + c) ^ s) & mask) != 0);
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+
58
+ TEST(BitAdder, Fields) {
59
+ test_bit_adder<GF2_128<>>();
60
+ test_bit_adder<Fp128<>>();
61
+ }
62
+
63
+ } // namespace
64
+ } // namespace proofs
@@ -0,0 +1,247 @@
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_LOGIC_BIT_PLUCKER_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_H_
17
+
18
+ #include <stddef.h>
19
+
20
+ #include <array>
21
+ #include <vector>
22
+
23
+ #include "algebra/interpolation.h"
24
+ #include "algebra/poly.h"
25
+ #include "circuits/logic/bit_plucker_constants.h"
26
+ #include "circuits/logic/polynomial.h"
27
+
28
+ namespace proofs {
29
+ /*
30
+
31
+ Many circuits we design require bit inputs in {0,1} when the field F takes 128+
32
+ bits to represent. Each input to a circuit is an element in F, and must either
33
+ be sent to the verifier or committed, and thus sending several single-bit
34
+ inputs represents an overhead.
35
+
36
+ A bit-plucker is a circuit component that maps a set
37
+ S \subset F of size 2^k into k wires, b_0, ..., b_k-1, that are each in {0,1}.
38
+ Thus, it can reduce the number of inputs that a predicate circuit requires, and
39
+ thus makes the proof smaller or more efficient to compute or verify.
40
+
41
+ The optimal bit-plucker for k bits depends on k. For small k, the simplest
42
+ bit plucker is sufficient. In some cases, bit pluckers can exploit the field
43
+ structure.
44
+
45
+ [ RUN ] BitPlucker.PluckSize
46
+ pluck[1]: depth: 3 wires: 6 in: 2 out:2 use:4 ovh:2 t:6 cse:0 notn:9
47
+ pluck[2]: depth: 4 wires: 14 in: 2 out:4 use:9 ovh:5 t:18 cse:5
48
+ notn:19
49
+ pluck[3]: depth: 5 wires: 25 in: 2 out:6 use:17 ovh:8 t:38 cse:23
50
+ notn:40
51
+ pluck[4]: depth: 6 wires: 40 in: 2 out:8 use:29 ovh:11 t:74 cse:73
52
+ notn:87
53
+ pluck[5]: depth: 7 wires: 61 in: 2 out:10 use:47 ovh:14 t:144 cse:199
54
+ notn:194
55
+ pluck[6]: depth: 8 wires: 92 in: 2 out:12 use:75 ovh:17 t:288 cse:501
56
+ notn:437
57
+ pluck[7]: depth: 9 wires: 141 in: 2 out:14 use:121 ovh:20 t:594
58
+ cse:1203 notn:984
59
+ pluck[8]: depth: 10 wires: 224 in: 2 out:16 use:201 ovh:23 t:1254
60
+ cse:2801 notn:2203
61
+
62
+ Our experiments also considered an O(N)-wires, O(N)-terms bit plucker.
63
+ To pluck a LOGN-bit quantity E, write E = N0*E1 + E0 where E0 is a
64
+ LOGN0-bit quantity and where E1 is a LOGN1-bit quantity, and where
65
+ LOGN0 = ceil(LOGN/2), LOGN1 = floor(LOGN/2). This decomposition
66
+ can be computed by interpolating two Polynomials of length N. Now
67
+ we are left with plucking two quantities E0, E1, which can be done
68
+ by any subquadratic-time plucker.
69
+
70
+ A similar idea for the LOGN -> N binary decoder is in Knuth 7.1.2
71
+ Exercise 39. (A plucker is the moral transpose of the binary
72
+ decoder.)
73
+
74
+ However, this plucker was dominated by the smaller one for our use case, and
75
+ thus removed from the code here. It can be resurrected from experimental if
76
+ needed.
77
+
78
+ [ RUN ] BitPlucker.LargePluckSize
79
+ large_pluck[2] depth: 5 wires: 15 in: 2 out:4 use:9 ovh:6 t:19 cse:9
80
+ notn:27
81
+ large_pluck[3] depth: 7 wires: 31 in: 2 out:5 use:20 ovh:11 t:43
82
+ cse:19 notn:50
83
+ large_pluck[4] depth: 8 wires: 46 in: 2 out:8 use:33 ovh:13 t:70
84
+ cse:33 notn:89
85
+ large_pluck[5] depth: 10 wires: 79 in: 2 out:8 use:60 ovh:19 t:128
86
+ cse:68 notn:164
87
+ large_pluck[6] depth: 11 wires: 119 in: 2 out:12 use:99 ovh:20 t:209
88
+ cse:119 notn:299
89
+ large_pluck[7] depth: 13 wires: 206 in: 2 out:11 use:179 ovh:27 t:381
90
+ cse:234 notn:567
91
+ large_pluck[8] depth: 14 wires: 344 in: 2 out:16 use:317 ovh:27 t:668
92
+ cse:413 notn:1065
93
+ large_pluck[9] depth: 16 wires: 631 in: 2 out:14 use:596 ovh:35 t:1260
94
+ cse:796 notn:2064
95
+ large_pluck[10] depth: 17 wires: 1157 in: 2 out:20 use:1123 ovh:34
96
+ t:2347 cse:1435 notn:3967
97
+ large_pluck[11] depth: 19 wires: 2224 in: 2 out:17 use:2181 ovh:43
98
+ t:4551 cse:2762 notn:7789
99
+ large_pluck[12] depth: 20 wires: 4294 in: 2 out:24 use:4253 ovh:41
100
+ t:8782 cse:5113 notn:15205
101
+
102
+ */
103
+ template <class Logic, size_t LOGN>
104
+ class BitPlucker {
105
+ public:
106
+ static constexpr size_t kN = 1 << LOGN;
107
+ static constexpr size_t kNv32Elts = (32u + LOGN - 1u) / LOGN;
108
+ static constexpr size_t kNv256Elts = (256u + LOGN - 1u) / LOGN;
109
+ static constexpr size_t kNv128Elts = (128u + LOGN - 1u) / LOGN;
110
+ using Field = typename Logic::Field;
111
+ using BitW = typename Logic::BitW;
112
+ using EltW = typename Logic::EltW;
113
+ using Elt = typename Field::Elt;
114
+ using PolyN = Poly<kN, Field>;
115
+ using InterpolationN = Interpolation<kN, Field>;
116
+ using v32 = typename Logic::v32;
117
+ using v256 = typename Logic::v256;
118
+ using packed_v32 = std::array<EltW, kNv32Elts>;
119
+ using packed_v128 = std::array<EltW, kNv128Elts>;
120
+ using packed_v256 = std::array<EltW, kNv256Elts>;
121
+
122
+ const Logic& l_;
123
+ std::vector<PolyN> plucker_;
124
+
125
+ explicit BitPlucker(const Logic& l) : l_(l), plucker_(LOGN) {
126
+ // evaluation points
127
+ PolyN X;
128
+ for (size_t i = 0; i < kN; ++i) {
129
+ X[i] = bit_plucker_point<Field, kN>()(i, l_.f_);
130
+ }
131
+ for (size_t k = 0; k < LOGN; ++k) {
132
+ PolyN Y;
133
+ for (size_t i = 0; i < kN; ++i) {
134
+ Y[i] = l_.f_.of_scalar((i >> k) & 1);
135
+ }
136
+ plucker_[k] = InterpolationN::monomial_of_lagrange(Y, X, l_.f_);
137
+ }
138
+ }
139
+
140
+ typename Logic::template bitvec<LOGN> pluck(const EltW& e) const {
141
+ typename Logic::template bitvec<LOGN> r;
142
+ const Logic& L = l_; // shorthand
143
+ const Polynomial<Logic> P(L);
144
+
145
+ for (size_t k = 0; k < LOGN; ++k) {
146
+ EltW v = P.eval(plucker_[k], e);
147
+ L.assert_is_bit(v);
148
+ r[k] = BitW(v, l_.f_);
149
+ }
150
+
151
+ return r;
152
+ }
153
+
154
+ v32 unpack_v32(const packed_v32& v) const { return unpack<v32>(v); }
155
+
156
+ template <typename T, typename PackedT>
157
+ T unpack(const PackedT& v) const {
158
+ T r;
159
+ for (size_t i = 0; i < v.size(); ++i) {
160
+ auto b = pluck(v[i]);
161
+ for (size_t j = 0; j < LOGN; ++j) {
162
+ if (LOGN * i + j < r.size()) {
163
+ r[LOGN * i + j] = b[j];
164
+ }
165
+ }
166
+ }
167
+ return r;
168
+ }
169
+
170
+ template <typename T>
171
+ static T packed_input(const Logic& lc) {
172
+ T r;
173
+ for (size_t i = 0; i < r.size(); ++i) {
174
+ r[i] = lc.eltw_input();
175
+ }
176
+ return r;
177
+ }
178
+ };
179
+
180
+ /*
181
+ On input Elt ind, and Elt arr[], returns arr[ind].
182
+ This muxer is useful when the same array needs to be muxed multiple times
183
+ with different indices. It differs from the above classes in that it
184
+ precomputes the coefficient array, which can depend on EltW inputs.
185
+
186
+ The template parameter N indicates the size of the array.
187
+ The template parameter PP defines the set of points used for the interpolation.
188
+ This value defaults to N, which defines the set of points
189
+ { -N-1, -N-3, -N-5, ..., N-3, N-1}
190
+ but in some cases, one may want to explicitly specify the set of points.
191
+ */
192
+ template <class Logic, size_t N, size_t PP = N>
193
+ class EltMuxer {
194
+ static constexpr size_t kN = N;
195
+ static constexpr size_t kPP = PP;
196
+
197
+ public:
198
+ using Field = typename Logic::Field;
199
+ using EltW = typename Logic::EltW;
200
+ using PolyN = Poly<kN, Field>;
201
+ using InterpolationN = Interpolation<kN, Field>;
202
+
203
+ EltMuxer(const Logic& l, const EltW arr[/* kN */]) : l_(l), coeff_(kN) {
204
+ for (size_t i = 0; i < kN; ++i) {
205
+ coeff_[i] = l_.konst(0);
206
+ }
207
+ for (size_t i = 0; i < kN; ++i) {
208
+ PolyN basis_i = even_lagrange_basis(i);
209
+ for (size_t j = 0; j < kN; ++j) {
210
+ auto bi = l_.konst(basis_i[j]);
211
+ auto barr_i = l_.mul(bi, arr[i]);
212
+ coeff_[j] = l_.add(coeff_[j], barr_i);
213
+ }
214
+ }
215
+ }
216
+
217
+ EltW mux(const EltW& ind) const {
218
+ const Polynomial<Logic> P(l_);
219
+
220
+ std::array<EltW, kN> xi;
221
+ P.powers_of_x(kN, xi.data(), ind);
222
+
223
+ // dot product with coefficients
224
+ EltW r = l_.konst(0);
225
+ for (size_t i = 0; i < kN; ++i) {
226
+ auto cxi = l_.mul(coeff_[i], xi[i]);
227
+ r = l_.add(r, cxi);
228
+ }
229
+ return r;
230
+ }
231
+
232
+ private:
233
+ const Logic& l_;
234
+ std::vector<EltW> coeff_;
235
+
236
+ PolyN even_lagrange_basis(size_t k) {
237
+ PolyN X, Y;
238
+ for (size_t i = 0; i < kN; ++i) {
239
+ X[i] = bit_plucker_point<Field, PP>()(i, l_.f_);
240
+ Y[i] = l_.f_.of_scalar((i == k));
241
+ }
242
+ return InterpolationN::monomial_of_lagrange(Y, X, l_.f_);
243
+ }
244
+ };
245
+ } // namespace proofs
246
+
247
+ #endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_H_
@@ -0,0 +1,35 @@
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_LOGIC_BIT_PLUCKER_CONSTANTS_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_CONSTANTS_H_
17
+
18
+ #include <stddef.h>
19
+ #include <stdint.h>
20
+
21
+ namespace proofs {
22
+ // bit-plucker code common to both compiler-time and
23
+ // wire-fill time
24
+ template <class Field, size_t N>
25
+ struct bit_plucker_point {
26
+ using Elt = typename Field::Elt;
27
+
28
+ // packing of bits compatible with even_lagrange_basis():
29
+ Elt operator()(uint64_t bits, const Field& F) const {
30
+ return F.subf(F.of_scalar(2 * bits), F.of_scalar(N - 1));
31
+ }
32
+ };
33
+ } // namespace proofs
34
+
35
+ #endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_CONSTANTS_H_