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,137 @@
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_ARRAYS_EQS_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ARRAYS_EQS_H_
17
+
18
+ #include <cstddef>
19
+ #include <vector>
20
+
21
+ #include "arrays/affine.h"
22
+ #include "arrays/dense.h"
23
+ #include "util/panic.h"
24
+
25
+ namespace proofs {
26
+
27
+ // Stateful implementation of EQ[I, j] which, for fixed
28
+ // I, holds an array indexed by j.
29
+ template <class Field>
30
+ class Eqs : public Dense<Field> {
31
+ using Elt = typename Field::Elt;
32
+ using Dense<Field>::v_;
33
+ using Dense<Field>::n0_;
34
+
35
+ public:
36
+ Eqs(size_t logn, corner_t n, const Elt I[/*logn*/], const Field& F)
37
+ : Dense<Field>(n, 1) {
38
+ filleq(&v_[0], logn, n, I, F);
39
+ }
40
+
41
+ corner_t n() const { return n0_; }
42
+
43
+ // Optimization for a special case: return a raw vector
44
+ // eq[i] = EQ(G0, i) + alpha * EQ(G1, i)
45
+ // for all 0 <= i < n.
46
+ static std::vector<Elt> raw_eq2(size_t logn, corner_t n, const Elt* G0,
47
+ const Elt* G1, const Elt& alpha,
48
+ const Field& F) {
49
+ std::vector<Elt> eq(n);
50
+ fill_recursive(&eq[0], logn, n, G0, G1, F.one(), alpha, F);
51
+ return eq;
52
+ }
53
+
54
+ private:
55
+ // fill_recursive(eq, l, n, G0, G1, w0, w1, F) populates eq[0, n) with
56
+ // eq[i] = w0 * EQ[G0, i] + w1 * EQ[G1, i]
57
+ static void fill_recursive(Elt* eq, size_t l, corner_t n, const Elt* G0,
58
+ const Elt* G1, const Elt& w0, const Elt& w1,
59
+ const Field& F) {
60
+ if (l > 0) {
61
+ const size_t nl = l - 1;
62
+ const corner_t s = corner_t(1) << nl;
63
+
64
+ Elt w0hi = F.mulf(w0, G0[nl]);
65
+ Elt w1hi = F.mulf(w1, G1[nl]);
66
+ Elt w0lo = F.subf(w0, w0hi);
67
+ Elt w1lo = F.subf(w1, w1hi);
68
+ if (n <= s) {
69
+ fill_recursive(eq, nl, n, G0, G1, w0lo, w1lo, F);
70
+ } else {
71
+ fill_recursive(eq, nl, s, G0, G1, w0lo, w1lo, F);
72
+ fill_recursive(eq + s, nl, n - s, G0, G1, w0hi, w1hi, F);
73
+ }
74
+ } else {
75
+ eq[0] = F.addf(w0, w1);
76
+ }
77
+ }
78
+
79
+ // Return ceil(a / 2^{n}) for a != 0.
80
+ //
81
+ // Several ways exist to compute ceil(a/b) given a primitive that
82
+ // computes floor(a/b), such as the C++ unsigned division operator.
83
+ // The simplest one is floor((a+(b-1))/b), which potentially overflows.
84
+ // Another way is 1+floor((a-1)/b), which underflows for a==0 but
85
+ // otherwise does not overflow. More complicated ways exist that neither
86
+ // overflow nor underflow. Since the rest of the code assumes
87
+ // a!=0 anyway, we use the 1+floor((a-1)/b) version.
88
+ static corner_t ceilshr(corner_t a, size_t n) { return 1u + ((a - 1u) >> n); }
89
+
90
+ // Compute the array EQ[Q, i] for all 0<=i<n, for n <= 2^{logn}.
91
+ // (logn can otherwise be arbitrarily large.)
92
+ //
93
+ // Let Q be the array of field elements Q[0,logn), and let
94
+ // i[l] be the l-th bit of the binary representation of i, for
95
+ // 0 <= l < logn.
96
+ //
97
+ // We have
98
+ // EQ[Q, i] = (1 - Q[0]) * EQ[Q[1:], i[1:]] if i[0] = 0;
99
+ // EQ[Q, i] = Q[0] * EQ[Q[1:], i[1:]] if i[0] = 1.
100
+ //
101
+ // Thus, EQ{n, logn} can be expressed in terms of EQ{ceil(n/2), logn-1}
102
+ // of half the size.
103
+ static void filleq(Elt* eq, size_t logn, corner_t n, const Elt* Q,
104
+ const Field& F) {
105
+ check(n > 0, "n > 0");
106
+ eq[0] = F.one();
107
+ for (size_t l = logn; l-- > 0;) {
108
+ corner_t nl = ceilshr(n, l);
109
+ corner_t i = ceilshr(nl, 1);
110
+
111
+ // Special case for the first iteration of the i-loop
112
+ // below: don't compute eq[2*i+1] (post decrement) if it
113
+ // would overflow the array.
114
+ if (/*2*(i-1)+1 = */ 2 * i - 1 >= nl) {
115
+ i--;
116
+ Elt v = eq[i], qv = Q[l];
117
+ F.mul(qv, v);
118
+ eq[2 * i] = v;
119
+ F.sub(eq[2 * i], qv);
120
+ }
121
+ while (i-- > 0) {
122
+ // Assign
123
+ // eq[2*i] = (1-Q[l])*eq[i]
124
+ // eq[2*i+1] = Q[l]*eq[i]
125
+ // with one multiplication.
126
+ Elt v = eq[i], qv = Q[l];
127
+ F.mul(qv, v);
128
+ eq[2 * i] = v;
129
+ F.sub(eq[2 * i], qv);
130
+ eq[2 * i + 1] = qv;
131
+ }
132
+ }
133
+ }
134
+ };
135
+ } // namespace proofs
136
+
137
+ #endif // PRIVACY_PROOFS_ZK_LIB_ARRAYS_EQS_H_
@@ -0,0 +1,151 @@
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 "arrays/eqs.h"
16
+
17
+ #include <stddef.h>
18
+
19
+ #include <vector>
20
+
21
+ #include "algebra/bogorng.h"
22
+ #include "algebra/fp.h"
23
+ #include "arrays/affine.h"
24
+ #include "arrays/dense.h"
25
+ #include "arrays/eq.h"
26
+ #include "arrays/sparse.h"
27
+ #include "gtest/gtest.h"
28
+
29
+ namespace proofs {
30
+ namespace {
31
+ using Field = Fp<4>;
32
+ using Elt = typename Field::Elt;
33
+ using index_t = Sparse<Field>::index_t;
34
+
35
+ static const Field F(
36
+ "21888242871839275222246405745257275088548364400416034343698204186575808495"
37
+ "617");
38
+
39
+ class RandomSlice {
40
+ public:
41
+ std::vector<Elt> r_;
42
+ explicit RandomSlice(size_t n) : r_(n) {
43
+ Bogorng<Field> rng(&F);
44
+ for (size_t i = 0; i < n; ++i) {
45
+ r_[i] = rng.next();
46
+ }
47
+ }
48
+ };
49
+
50
+ // V[T] = EQ[T|i] V[i]
51
+ void one_test_eqs_bind(size_t logn, corner_t n) {
52
+ RandomSlice T(logn);
53
+ Eqs<Field> EQ(logn, n, T.r_.data(), F);
54
+ auto V = Dense<Field>(n, 1);
55
+ V.clear(F);
56
+
57
+ Elt rhs = F.zero();
58
+ for (corner_t i = 0; i < n; i++) {
59
+ F.add(rhs, F.mulf(EQ.at(i), V.v_[i]));
60
+ }
61
+
62
+ V.bind_all(logn, T.r_.data(), F);
63
+ Elt lhs = V.scalar();
64
+
65
+ EXPECT_EQ(lhs, rhs);
66
+ }
67
+
68
+ // EQ[A|B] = EQ[A|i] EQ[i|B]
69
+ void one_test_eqs_decomposition(size_t logn, corner_t n) {
70
+ RandomSlice A(logn);
71
+ RandomSlice B(logn);
72
+ Eqs<Field> EQA(logn, n, A.r_.data(), F);
73
+ Eqs<Field> EQB(logn, n, B.r_.data(), F);
74
+
75
+ Elt rhs = F.zero();
76
+ for (corner_t i = 0; i < n; i++) {
77
+ F.add(rhs, F.mulf(EQA.at(i), EQB.at(i)));
78
+ }
79
+
80
+ Elt lhs = Eq<Field>::eval(logn, n, A.r_.data(), B.r_.data(), F);
81
+ EXPECT_EQ(lhs, rhs);
82
+ }
83
+
84
+ TEST(Eqs, All) {
85
+ for (size_t logn = 0; logn < 8; logn++) {
86
+ for (size_t i = 1; i <= (1 << logn); i++) {
87
+ one_test_eqs_bind(logn, corner_t(i));
88
+ one_test_eqs_decomposition(logn, corner_t(i));
89
+ }
90
+ }
91
+ }
92
+
93
+ // recursive implementation of bindv(EQ[], .) as described in the
94
+ // RFC, so that we can verify equivalence with our implementation.
95
+ std::vector<Elt> bindeq(size_t l, const Elt X[/*l*/]) {
96
+ size_t n = size_t(1) << l;
97
+ std::vector<Elt> B(n);
98
+ if (l == 0) {
99
+ B[0] = F.one();
100
+ } else {
101
+ auto A = bindeq(l - 1, X + 1);
102
+ for (size_t i = 0; 2 * i < n; ++i) {
103
+ B[2 * i] = F.mulf(F.subf(F.one(), X[0]), A[i]);
104
+ B[2 * i + 1] = F.mulf(X[0], A[i]);
105
+ }
106
+ }
107
+ return B;
108
+ }
109
+
110
+ TEST(Eqs, RFC) {
111
+ size_t logn = 11;
112
+ size_t n = size_t(1) << logn;
113
+ RandomSlice X(logn);
114
+ auto RFC = bindeq(logn, X.r_.data());
115
+ Eqs<Field> EQ(logn, n, X.r_.data(), F);
116
+ for (size_t i = 0; i < n; ++i) {
117
+ EXPECT_EQ(RFC[i], EQ.at(i));
118
+ }
119
+
120
+ // truncating N truncates bindv(EQ, .) with no other ill effects
121
+ size_t n2 = n - 7;
122
+ Eqs<Field> EQ2(logn, n2, X.r_.data(), F);
123
+ for (size_t i = 0; i < n2; ++i) {
124
+ EXPECT_EQ(RFC[i], EQ2.at(i));
125
+ }
126
+ }
127
+
128
+ TEST(Eqs, RawEq2) {
129
+ Bogorng<Field> rng(&F);
130
+ for (size_t logn = 0; logn < 6; logn++) {
131
+ for (corner_t n = 1; n <= (corner_t(1) << logn); n++) {
132
+ RandomSlice G0(logn);
133
+ RandomSlice G1(logn);
134
+ Elt alpha = rng.next();
135
+
136
+ auto eq =
137
+ Eqs<Field>::raw_eq2(logn, n, G0.r_.data(), G1.r_.data(), alpha, F);
138
+ Eqs<Field> EQ0(logn, n, G0.r_.data(), F);
139
+ Eqs<Field> EQ1(logn, n, G1.r_.data(), F);
140
+
141
+ ASSERT_EQ(eq.size(), n);
142
+ for (corner_t i = 0; i < n; i++) {
143
+ Elt expected = F.addf(EQ0.at(i), F.mulf(alpha, EQ1.at(i)));
144
+ EXPECT_EQ(eq[i], expected)
145
+ << "logn=" << logn << ", n=" << n << ", i=" << i;
146
+ }
147
+ }
148
+ }
149
+ }
150
+ } // namespace
151
+ } // namespace proofs
@@ -0,0 +1,192 @@
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_ARRAYS_SPARSE_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ARRAYS_SPARSE_H_
17
+
18
+ #include <stddef.h>
19
+
20
+ #include <algorithm>
21
+ #include <memory>
22
+ #include <vector>
23
+
24
+ #include "algebra/compare.h"
25
+ #include "algebra/poly.h"
26
+ #include "arrays/affine.h"
27
+ #include "util/panic.h"
28
+
29
+ namespace proofs {
30
+ // ------------------------------------------------------------
31
+ // Sparse representation of multi-affine functions.
32
+ //
33
+ // This class is mainly used as a reference implementation
34
+ // for testing, and it exposes a similar interface as dense<Field>.
35
+ // Sumcheck has its own specialized "quad" implementation.
36
+ //
37
+ template <class Field>
38
+ class Sparse {
39
+ using Elt = typename Field::Elt;
40
+ using T2 = Poly<2, Field>;
41
+
42
+ public:
43
+ // A corner on the sparse hypercube, represented as triple of size_t
44
+ // and a value. The 3D representation is kind of a guess of how
45
+ // many bits we'll ever need. Under the theory that "size_t" has
46
+ // enough bits to index a dense array that fills the address space,
47
+ // and that the program should support |points| gates, and each gate
48
+ // has three terminals, then a triple ought to be both necessary and
49
+ // sufficient.
50
+ struct corner {
51
+ size_t p0, p1, p2;
52
+ Elt v;
53
+
54
+ bool eqndx(const corner& y) const {
55
+ return (p2 == y.p2 && p1 == y.p1 && p0 == y.p0);
56
+ }
57
+ bool operator==(const corner& y) const { return eqndx(y) && v == y.v; }
58
+ bool operator!=(const corner& y) const { return !operator==(y); }
59
+
60
+ static bool compare(const corner& x, const corner& y, const Field& F) {
61
+ if (x.p2 < y.p2) return true;
62
+ if (x.p2 > y.p2) return false;
63
+ if (x.p1 < y.p1) return true;
64
+ if (x.p1 > y.p1) return false;
65
+ if (x.p0 < y.p0) return true;
66
+ if (x.p0 > y.p0) return false;
67
+ return elt_less_than(x.v, y.v, F);
68
+ }
69
+ };
70
+
71
+ // the index of a point in a sparse array
72
+ using index_t = size_t;
73
+
74
+ index_t n_;
75
+ std::vector<corner> c_;
76
+
77
+ explicit Sparse(index_t n) : n_(n), c_(n) {}
78
+
79
+ // no copies, but see clone() below
80
+ Sparse(const Sparse& y) = delete;
81
+ Sparse(const Sparse&& y) = delete;
82
+ Sparse operator=(const Sparse& y) = delete;
83
+
84
+ // Nobody should need to clone a sparse array except tests.
85
+ // Reflect this fact in the name.
86
+ std::unique_ptr<Sparse> clone_testing_only() const {
87
+ auto s = std::make_unique<Sparse>(n_);
88
+ for (index_t i = 0; i < n_; ++i) {
89
+ s->c_[i] = c_[i];
90
+ }
91
+ return s;
92
+ }
93
+
94
+ T2 t2_at_corners(index_t* newi, index_t i, const Field& F) const {
95
+ // If c_[i] and c_[i+1] have the same (P2, P1), and they differ
96
+ // by the least-significant bit in P0:
97
+ if (i + 1 < n_ && //
98
+ c_[i].p2 == c_[i + 1].p2 && //
99
+ c_[i].p1 == c_[i + 1].p1 && //
100
+ (c_[i].p0 >> 1) == (c_[i + 1].p0 >> 1) && //
101
+ c_[i + 1].p0 == c_[i].p0 + 1) {
102
+ // we have two corners.
103
+ *newi = i + 2;
104
+ return T2{c_[i].v, c_[i + 1].v};
105
+ } else {
106
+ // we have one corner and the other one is zero.
107
+ *newi = i + 1;
108
+ if ((c_[i].p0 & 1) == 0) {
109
+ return T2{c_[i].v, F.zero()};
110
+ } else {
111
+ return T2{F.zero(), c_[i].v};
112
+ }
113
+ }
114
+ }
115
+
116
+ // For a given random number r, the binding operation computes
117
+ // v[p2, p1, p0] = (1 - r) * v[p2, p1, 2 * p0] + r * v[p2, p1, 2 * p0 + 1]
118
+ // Note that either the odd or the even element or both may not be actually
119
+ // present in the sparse array.
120
+ void bind(const Elt& r, const Field& F) {
121
+ index_t rd = 0, wr = 0;
122
+ while (rd < n_) {
123
+ index_t newrd;
124
+ T2 f = t2_at_corners(&newrd, rd, F);
125
+ c_[wr] = corner{.p0 = c_[rd].p0 >> 1,
126
+ .p1 = c_[rd].p1,
127
+ .p2 = c_[rd].p2,
128
+ .v = affine_interpolation(r, f.t_[0], f.t_[1], F)};
129
+ wr++;
130
+ rd = newrd;
131
+ }
132
+
133
+ // shrink the array
134
+ n_ = wr;
135
+ }
136
+
137
+ void bind_all(size_t logv, const Elt r[/*logv*/], const Field& F) {
138
+ for (size_t v = 0; v < logv; ++v) {
139
+ bind(r[v], F);
140
+ }
141
+ }
142
+
143
+ void reshape() {
144
+ // this function works only if c_[i].p0 == 0 for all i, but
145
+ // rather than checking them one at the time, keep a giant
146
+ // bitwise OR and check at the end
147
+ size_t lost_bits = 0;
148
+ for (index_t i = 0; i < n_; ++i) {
149
+ lost_bits |= c_[i].p0;
150
+ c_[i] = corner{.p0 = c_[i].p1, .p1 = c_[i].p2, .p2 = 0, .v = c_[i].v};
151
+ }
152
+ check(lost_bits == 0, "lost_bits == 0");
153
+ }
154
+
155
+ // This method can only be called after full binding; the caller
156
+ // is responsible for ensuring that pre-condition.
157
+ Elt scalar() {
158
+ check(n_ == 1, "n_ == 1");
159
+ check(c_[0].p0 == 0, "c_[0].p0_ == 0");
160
+ check(c_[0].p1 == 0, "c_[0].p1_ == 0");
161
+ check(c_[0].p2 == 0, "c_[0].p2_ == 0");
162
+ return c_[0].v;
163
+ }
164
+
165
+ void canonicalize(const Field& F) {
166
+ std::sort(c_.begin(), c_.end(), [&F](const corner& x, const corner& y) {
167
+ return corner::compare(x, y, F);
168
+ });
169
+ return coalesce(F);
170
+ }
171
+
172
+ private:
173
+ void coalesce(const Field& F) {
174
+ // Coalesce duplicates.
175
+ // The (rd,wr)=(0,0) iteration executes the else{} branch and
176
+ // continues with (1,1), so we start at (1,1) and avoid the
177
+ // special case for wr-1 at wr=0.
178
+ index_t wr = 1;
179
+ for (index_t rd = 1; rd < n_; ++rd) {
180
+ if (c_[rd].eqndx(c_[wr - 1])) {
181
+ F.add(c_[wr - 1].v, c_[rd].v);
182
+ } else {
183
+ c_[wr] = c_[rd];
184
+ wr++;
185
+ }
186
+ }
187
+ n_ = wr;
188
+ }
189
+ };
190
+ } // namespace proofs
191
+
192
+ #endif // PRIVACY_PROOFS_ZK_LIB_ARRAYS_SPARSE_H_