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,60 @@
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_EC_P256K1_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_EC_P256K1_H_
17
+
18
+ /*
19
+ This file declares the one instance of the P256k1 curve and its related fields.
20
+ There should be only one instance of this curve in any program due to the
21
+ typing conventions.
22
+
23
+ This curve is also known as secp256k1.
24
+
25
+ It is defined over the base field F_p for
26
+ p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
27
+ = 2^256 - 2^32 - 977
28
+ = 115792089237316195423570985008687907853269984665640564039457584007908834671663
29
+
30
+ and has an order of
31
+ n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
32
+ = 115792089237316195423570985008687907852837564279074904382605163141518161494337
33
+ */
34
+
35
+ #include "algebra/fp.h"
36
+ #include "algebra/fp_p256k1.h"
37
+ #include "ec/elliptic_curve.h"
38
+
39
+ namespace proofs {
40
+
41
+ using Fp256k1Base = Fp256k1<true>;
42
+ using Fp256k1Scalar = Fp<4, true>;
43
+ using Fp256k1Nat = Fp256k1Base::N;
44
+
45
+ // This is the base field of the curve.
46
+ extern const Fp256k1Base p256k1_base;
47
+
48
+ // Order of the curve.
49
+ extern const Fp256k1Nat n256k1_order;
50
+
51
+ // This field allows operations mod the order of the curve.
52
+ extern const Fp256k1Scalar p256k1_scalar;
53
+
54
+ typedef EllipticCurve<Fp256k1Base, 4, 256> P256k1;
55
+
56
+ extern const P256k1 p256k1;
57
+
58
+ } // namespace proofs
59
+
60
+ #endif // PRIVACY_PROOFS_ZK_LIB_EC_P256K1_H_
@@ -0,0 +1,503 @@
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_GF2K_GF2_128_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_GF2K_GF2_128_H_
17
+
18
+ #include <stdio.h>
19
+
20
+ #include <array>
21
+ #include <cstddef>
22
+ #include <cstdint>
23
+ #include <functional>
24
+ #include <optional>
25
+ #include <utility>
26
+
27
+ #include "gf2k/gf2poly.h"
28
+ #include "gf2k/sysdep.h"
29
+ #include "util/panic.h"
30
+
31
+ namespace proofs {
32
+
33
+ struct BinaryFieldTypeTag {};
34
+
35
+ template <size_t subfield_log_bits = 4>
36
+ class GF2_128 {
37
+ // avoid writing static_cast<size_t>(1) all the time.
38
+ static constexpr size_t k1 = 1;
39
+
40
+ public:
41
+ using TypeTag = BinaryFieldTypeTag;
42
+
43
+ // Fast representation of the field element via the system-dependent
44
+ // SIMD type.
45
+ using N = gf2_128_elt_t;
46
+
47
+ // "Slow" representation of the field element as array of
48
+ // C++ integral types.
49
+ using N1 = GF2Poly<2>;
50
+
51
+ static constexpr size_t kNPolyEvaluationPoints = 6;
52
+ static constexpr size_t kLogBits = 7;
53
+ static constexpr size_t kBits = k1 << kLogBits;
54
+ static constexpr size_t kBytes = kBits / 8u;
55
+
56
+ static constexpr size_t kSubFieldLogBits = subfield_log_bits;
57
+ static constexpr size_t kSubFieldBits = k1 << kSubFieldLogBits;
58
+ static constexpr size_t kSubFieldBytes = kSubFieldBits / 8u;
59
+
60
+ static_assert(kBits == 8u * kBytes);
61
+ static_assert(kSubFieldBits == 8u * kSubFieldBytes);
62
+ static constexpr bool kCharacteristicTwo = true;
63
+
64
+ struct Elt {
65
+ N n;
66
+
67
+ Elt() : n{} {}
68
+ explicit Elt(N n_) : n(n_) {}
69
+
70
+ // Don't bother using SIMD instructions for comparisons,
71
+ // otherwise we have to complicate the sysdep API surface.
72
+ // Unpack into uint64[2] and compute manually.
73
+ bool operator==(const Elt& y) const { return unpack() == y.unpack(); }
74
+ bool operator!=(const Elt& y) const { return !operator==(y); }
75
+
76
+ // Returns the coefficient of x^i in the polynomial.
77
+ uint8_t operator[](size_t i) const {
78
+ auto n1 = uint64x2_of_gf2_128(n);
79
+ if (i < 64) {
80
+ return static_cast<uint8_t>((n1[0] >> i) & 0x1);
81
+ } else if (i < 128) {
82
+ return static_cast<uint8_t>((n1[1] >> (i - 64)) & 0x1);
83
+ } else {
84
+ return 0;
85
+ }
86
+ }
87
+
88
+ N1 unpack() const { return N1(uint64x2_of_gf2_128(n)); }
89
+ };
90
+
91
+ explicit GF2_128() {
92
+ kone_ = of_scalar_field(0b1);
93
+ kx_ = of_scalar_field(0b10);
94
+
95
+ // x^{-1} = x^127 + x^6 + x + 1
96
+ std::array<uint64_t, 2> invx = {
97
+ (1ull << 6) | (1ull << 1) | (1ull << 0),
98
+ (1ull << (127 - 64)),
99
+ };
100
+ kinvx_ = of_scalar_field(invx);
101
+
102
+ Elt g = subfield_generator();
103
+ kg_ = g;
104
+ kinvg_ = invertf(g);
105
+
106
+ // basis of the subfield = {1, g, g^2, ...}
107
+ beta_[0] = one();
108
+ for (size_t i = 1; i < kSubFieldBits; ++i) {
109
+ beta_[i] = mulf(beta_[i - 1], g);
110
+ }
111
+
112
+ // Reduce the basis to row-echelon form
113
+ beta_ref();
114
+
115
+ // Evaluation points. We use g^i for these as well
116
+ poly_evaluation_points_[0] = zero();
117
+ Elt gi = one();
118
+ for (size_t i = 1; i < kNPolyEvaluationPoints; ++i) {
119
+ poly_evaluation_points_[i] = gi;
120
+ mul(gi, g);
121
+ }
122
+
123
+ for (size_t i = 1; i < kNPolyEvaluationPoints; i++) {
124
+ for (size_t k = kNPolyEvaluationPoints; k-- > i;) {
125
+ auto dx =
126
+ subf(poly_evaluation_points_[k], poly_evaluation_points_[k - i]);
127
+ check(dx != zero(), "dx != zero()");
128
+ newton_denominators_[k][i] = invertf(dx);
129
+ }
130
+ }
131
+
132
+ // basis of counters
133
+ Elt cgi(g); // = g ^ {2^i}, initially i = 0
134
+ for (size_t i = 0; i < kSubFieldBits; ++i) {
135
+ counter_beta_[i] = cgi;
136
+ mul(cgi, cgi);
137
+ }
138
+ }
139
+
140
+ GF2_128(const GF2_128&) = delete;
141
+ GF2_128& operator=(const GF2_128&) = delete;
142
+
143
+ // The bits of u are the coordinates with respect to the basis
144
+ // beta_[] of the subfield.
145
+ Elt of_scalar(uint64_t u) const {
146
+ Elt t = zero();
147
+ for (size_t k = 0; k < kSubFieldBits; ++k, u >>= 1) {
148
+ if (u & 1) {
149
+ add(t, beta_[k]);
150
+ }
151
+ }
152
+ check(u == 0, "of_scalar(u), too many bits");
153
+ return t;
154
+ }
155
+
156
+ Elt of_scalar_field(uint64_t n) const {
157
+ std::array<uint64_t, 2> u = {n, 0};
158
+ return of_scalar_field(u);
159
+ }
160
+ Elt of_scalar_field(const std::array<uint64_t, 2>& u) const {
161
+ return Elt(gf2_128_of_uint64x2(u));
162
+ }
163
+
164
+ // The base_only flag is a placeholder that takes meaning when F is an
165
+ // extension field.
166
+ std::optional<Elt> of_bytes_field(const uint8_t ab[/* kBytes */],
167
+ bool base_only = true) const {
168
+ N1 an = N1::of_bytes(ab);
169
+ return of_scalar_field(an.u64());
170
+ }
171
+
172
+ void to_bytes_field(uint8_t ab[/* kBytes */], const Elt& x) const {
173
+ x.unpack().to_bytes(ab);
174
+ }
175
+
176
+ Elt sample(
177
+ const std::function<void(size_t n, uint8_t buf[])>& fill_bytes) const {
178
+ // Every 128-bit sequence is a valid field element.
179
+ uint8_t buf[kBytes];
180
+ fill_bytes(sizeof(buf), buf);
181
+ std::optional<Elt> maybe = of_bytes_field(buf);
182
+ check(maybe.has_value(), "of_bytes_field failed unexpectedly");
183
+ return maybe.value();
184
+ }
185
+
186
+ Elt sample_subfield(
187
+ const std::function<void(size_t n, uint8_t buf[])>& fill_bytes) const {
188
+ uint8_t buf[kSubFieldBytes];
189
+ fill_bytes(sizeof(buf), buf);
190
+ std::optional<Elt> maybe = of_bytes_subfield(buf);
191
+ check(maybe.has_value(), "of_bytes_subfield failed unexpectedly");
192
+ return maybe.value();
193
+ }
194
+
195
+ bool in_subfield(Elt e) const {
196
+ auto eu = solve(e);
197
+ return eu.first == N1{};
198
+ }
199
+
200
+ std::optional<Elt> of_bytes_subfield(
201
+ const uint8_t ab[/* kSubFieldBytes */]) const {
202
+ uint64_t u = 0;
203
+ for (size_t i = kSubFieldBytes; i-- > 0;) {
204
+ u <<= 8;
205
+ u |= ab[i];
206
+ }
207
+ return of_scalar(u);
208
+ }
209
+
210
+ void to_bytes_subfield(uint8_t ab[/* kSubFieldBytes */], const Elt& x) const {
211
+ auto eu = solve(x);
212
+ check(eu.first == N1{}, "eu.first == N1{}");
213
+ uint64_t u = eu.second;
214
+ for (size_t i = 0; i < kSubFieldBytes; ++i) {
215
+ ab[i] = u & 0xFFu;
216
+ u >>= 8;
217
+ }
218
+ }
219
+
220
+ // functional interface
221
+ Elt addf(const Elt& x, const Elt& y) const {
222
+ return Elt{gf2_128_add(x.n, y.n)};
223
+ }
224
+ Elt subf(const Elt& x, const Elt& y) const {
225
+ return Elt{gf2_128_add(x.n, y.n)};
226
+ }
227
+ Elt mulf(const Elt& x, const Elt& y) const {
228
+ return Elt{gf2_128_mul(x.n, y.n)};
229
+ }
230
+ Elt negf(const Elt& x) const { return x; }
231
+
232
+ // two-operands interface
233
+ void add(Elt& a, const Elt& y) const { a = addf(a, y); }
234
+ void sub(Elt& a, const Elt& y) const { a = subf(a, y); }
235
+ void mul(Elt& a, const Elt& y) const { a = mulf(a, y); }
236
+ void neg(Elt& a) const { /* noop */ }
237
+ void invert(Elt& a) const { a = invertf(a); }
238
+
239
+ Elt zero() const { return Elt{}; }
240
+ Elt one() const { return kone_; }
241
+ Elt mone() const { return kone_; }
242
+ Elt x() const { return kx_; }
243
+ Elt invx() const { return kinvx_; }
244
+ Elt g() const { return kg_; }
245
+ Elt invg() const { return kinvg_; }
246
+ Elt beta(size_t i) const {
247
+ check(i < kSubFieldBits, "i < kSubFieldBits");
248
+ return beta_[i];
249
+ }
250
+
251
+ Elt poly_evaluation_point(size_t i) const {
252
+ check(i < kNPolyEvaluationPoints, "i < kNPolyEvaluationPoints");
253
+ return poly_evaluation_points_[i];
254
+ }
255
+
256
+ // return (X[k] - X[k - i])^{-1}, were X[i] is the
257
+ // i-th poly evalaluation point.
258
+ Elt newton_denominator(size_t k, size_t i) const {
259
+ check(k < kNPolyEvaluationPoints, "k < kNPolyEvaluationPoints");
260
+ check(i <= k, "i <= k");
261
+ check(k != (k - i), "k != (k - i)");
262
+ return newton_denominators_[k][i];
263
+ }
264
+
265
+ Elt invertf(Elt x) const {
266
+ N1 a = x.unpack();
267
+ // Let POLY be the generator of GF(2^128) as GF(2)[x]/(POLY(x)).
268
+ // The Euclid algorithm would initialize B = POLY, but we cannot
269
+ // store POLY in one N1. Instead, we use the invariant that B is
270
+ // always "odd" throughout the algorithm, and we represent B =
271
+ // BM1OX * X + 1, or BM1OX = (B - 1) / X. For B = POLY, BM1OX =
272
+ // 1/X initially.
273
+ N1 bm1ox = kinvx_.unpack();
274
+ Elt u = one();
275
+ Elt v = zero();
276
+ while (a != N1(0)) {
277
+ if (a.bit(0) == 0) {
278
+ a.shiftr(1);
279
+ byinvx(u);
280
+ } else {
281
+ // Now A is "odd". Write A = AM1OX * X + 1. This operation
282
+ // be done in-place in the A variable, but we use another
283
+ // name for clarity.
284
+ N1 am1ox = a;
285
+ am1ox.shiftr(1);
286
+
287
+ // Normalize to the partial order degree(A) >= degree(B).
288
+ // We use the stronger total order "<" which is consistent
289
+ // with the partial order that we care about.
290
+ if (am1ox < bm1ox) {
291
+ std::swap(am1ox, bm1ox);
292
+ std::swap(u, v);
293
+ }
294
+ am1ox.sub(bm1ox);
295
+ sub(u, v);
296
+ byinvx(u);
297
+ a = am1ox;
298
+ }
299
+ }
300
+ return v;
301
+ }
302
+
303
+ // Type for counters. We represent unsigned integer n as g^n
304
+ // where g is the generator of the subfield.
305
+ struct CElt {
306
+ Elt e;
307
+
308
+ bool operator==(const CElt& y) const { return e == y.e; }
309
+ bool operator!=(const CElt& y) const { return !operator==(y); }
310
+ };
311
+ CElt as_counter(uint64_t a) const {
312
+ // 2^{bits} - 2 fits, 2^{bits} - 1 does not
313
+ check((a + 1u) != 0, "as_counter() arg too large");
314
+ check(((a + 1u) >> kSubFieldBits) == 0, "as_counter() arg too large");
315
+ Elt r(one());
316
+ for (size_t i = 0; i < kSubFieldBits; ++i) {
317
+ if ((a >> i) & 1) {
318
+ mul(r, counter_beta(i));
319
+ }
320
+ }
321
+ return CElt{r};
322
+ }
323
+ Elt counter_beta(size_t i) const {
324
+ check(i < kSubFieldBits, "i < kSubFieldBits");
325
+ return counter_beta_[i];
326
+ }
327
+
328
+ // Convert a counter into *some* field element such that the counter is
329
+ // zero (as a counter) iff the field element is zero. Since
330
+ // n as a counter is g^n, we have ((g^n - 1) = 0) <=> (n = 0)
331
+ Elt znz_indicator(const CElt& celt) const { return subf(celt.e, one()); }
332
+
333
+ private:
334
+ Elt kone_;
335
+ Elt kx_;
336
+ Elt kinvx_; // x^{-1}
337
+ Elt kg_;
338
+ Elt kinvg_; // g^{-1}
339
+ Elt beta_[kSubFieldBits]; // basis of the subfield viewed as a
340
+ // vector space over GF(2)
341
+ Elt counter_beta_[kSubFieldBits]; // basis of the multiplicative group
342
+ // of counters.
343
+
344
+ // LU decomposition of beta_, in unpacked format. We store L^{-1}
345
+ // instead of L, see comments in beta_ref()
346
+ N1 u_[kSubFieldBits];
347
+ uint64_t linv_[kSubFieldBits];
348
+
349
+ // ldnz_[i] stores the column index of the leading nonzero in u_[i].
350
+ // This array is in principle redundant, since one can always
351
+ // reconstruct it from u_, but we cache it for efficiency.
352
+ size_t ldnz_[kSubFieldBits];
353
+
354
+ Elt poly_evaluation_points_[kNPolyEvaluationPoints];
355
+ Elt newton_denominators_[kNPolyEvaluationPoints][kNPolyEvaluationPoints];
356
+
357
+ void byinvx(Elt& u) const { mul(u, kinvx_); }
358
+
359
+ Elt subfield_generator() {
360
+ // Let k = kSubFieldLogBits and n = kLogBits.
361
+ // Let x be the generator of Field.
362
+
363
+ // The generator r of the subfield is then
364
+ // x^{(2^{2^n}-1)/(2^{2^k}-1)}
365
+
366
+ // Compute r via the identity
367
+ // (2^{2^n}-1)/(2^{2^k}-1) =
368
+ // (2^{2^k}+1)*(2^{2^(k+1)}+1)*...*(2^{2^(n-1)}+1)
369
+ Elt r(kx_);
370
+ for (size_t i = kSubFieldLogBits; i < kLogBits; ++i) {
371
+ // s <- r^{2^(2^i))
372
+ Elt s(r);
373
+ for (size_t j = 0; j < (1u << i); ++j) {
374
+ mul(s, s);
375
+ }
376
+ // r <- r^{2^(2^i)+1)
377
+ mul(r, s);
378
+ }
379
+
380
+ return r;
381
+ }
382
+
383
+ // beta_ref() is a just a variant of Gaussian elimination, but
384
+ // because many such variants exist, we now explain the exact
385
+ // mechanics of the algorithm.
386
+ //
387
+ // The problem that we need to solve is the inversion of
388
+ // of_scalar(): given e = of_scalar(u), solve for u. The constraint
389
+ // we have is that e and u are arrays of bits, conveniently stored
390
+ // in uint64_t, and ideally we want to perform parallel bitwise
391
+ // operations, as opposed to extracting individual bits.
392
+ //
393
+ // Consider the following block matrix, or tableau:
394
+ //
395
+ // [ B | -I ]
396
+ // [ ------ ]
397
+ // [ e | u ]
398
+ //
399
+ // Here e and u are reinterpreted as row vectors of GF(2) elements;
400
+ // I is the identity matrix; B is such that B[i] (the i-th row of b)
401
+ // is beta(i) (the i-th element of the basis of the subfield), and
402
+ // beta(i) is interpreted as a row vector of 128 GF(2) elements.
403
+ // (The minus sign in -I is irrelevant over GF(2), but would be
404
+ // necessary over other fields.)
405
+ //
406
+ // We now postulate that the only allowed operation on the tableau
407
+ // is "axpy": add one row to another, which we can do efficiently
408
+ // via bitwise xor.
409
+ //
410
+ // of_scalar(u) can be reinterpreted in terms axpy as follows.
411
+ // Start with a tableau with e=0. Reduce u to 0 via axpy
412
+ // operations, e.g., for all i such that u[i] = 1, add row i to the
413
+ // last row. Because this is exactly what of_scalar() does, at the
414
+ // end of the process we have e = of_scalar(u). Because I is
415
+ // full-rank, any sequence of axpy's that reduces u to 0 produces
416
+ // the same e.
417
+ //
418
+ // We now want to invert the of_scalar() process. We cannot apply
419
+ // the axpy operations in of_scalar() in reverse order, because we
420
+ // don't know u, and thus we don't know which operations
421
+ // of_scalar(u) would apply. However, because B is a basis, any
422
+ // sequence of axpy operations that starts with u=0 and reduces e to
423
+ // 0 reconstructs the same u.
424
+ //
425
+ // For lack of a better idea, we choose the following sequence of
426
+ // axpy operations. First reduce B to row-echelon form via axpy
427
+ // operations on B, and then reduce e to zero via additional axpy
428
+ // operations. A matrix U is in row-echelon form if the following
429
+ // condition holds: i' > i implies that U[i'][ldnz[i]] = 0, where
430
+ // ldnz[i] is the column index of the leading nonzero in row i.
431
+ //
432
+ // Since B is constant, we choose to pre-compute the row-echelon
433
+ // form of B in beta_ref(), and finish the process in solve() when e
434
+ // is known, for multiple values of e.
435
+ //
436
+ // As it happens, reducing B to row-echelon transforms the -I
437
+ // in the upper-right block to -L^{-1}, where B=LU is the LU
438
+ // factorization of B. We don't use this correspondence anywhere
439
+ // in the code other than in the choice of the name Linv for the block.
440
+ //
441
+ void beta_ref() {
442
+ for (size_t i = 0; i < kSubFieldBits; ++i) {
443
+ // B in the tableau, becomes U at the end.
444
+ u_[i] = beta_[i].unpack();
445
+
446
+ // -I in the tableau, becomes -L^{-1} at the end.
447
+ // Ignore the minus sign over GF(2).
448
+ linv_[i] = (static_cast<uint64_t>(1) << i);
449
+ }
450
+
451
+ // Reduce B to row-echelon form.
452
+ //
453
+ // Invariant: B([0,RNK), [0,J)) is already in row-echelon form.
454
+ // The loop body extends this property to J+1 and possibly RNK+1.
455
+ size_t rnk = 0;
456
+ for (size_t j = 0; rnk < kSubFieldBits && j < kBits; ++j) {
457
+ // find pivot at row >= RNK in column J
458
+ for (size_t i = rnk; i < kSubFieldBits; ++i) {
459
+ if (u_[i].bit(j)) {
460
+ std::swap(u_[rnk], u_[i]);
461
+ std::swap(linv_[rnk], linv_[i]);
462
+ goto have_pivot;
463
+ }
464
+ }
465
+ // If we get here there is no pivot. Keep the rank RNK the same
466
+ // and proceed to the next column ++J
467
+ continue;
468
+
469
+ have_pivot:
470
+ ldnz_[rnk] = j;
471
+
472
+ // Pivot on [rnk][j].
473
+ for (size_t i1 = rnk + 1; i1 < kSubFieldBits; ++i1) {
474
+ if (u_[i1].bit(j)) {
475
+ u_[i1].add(u_[rnk]); // axpy on U
476
+ linv_[i1] ^= linv_[rnk]; // axpy on Linv
477
+ }
478
+ }
479
+ ++rnk;
480
+ }
481
+
482
+ // the basis is indeed a basis:
483
+ check(rnk == kSubFieldBits, "rnk == kSubFieldBits");
484
+ }
485
+
486
+ std::pair<N1, uint64_t> solve(const Elt& e) const {
487
+ uint64_t u = 0;
488
+ N1 ue = e.unpack();
489
+ for (size_t rnk = 0; rnk < kSubFieldBits; ++rnk) {
490
+ size_t j = ldnz_[rnk];
491
+ if (ue.bit(j)) {
492
+ ue.add(u_[rnk]);
493
+ u ^= linv_[rnk];
494
+ }
495
+ }
496
+
497
+ return std::pair(ue, u);
498
+ }
499
+ };
500
+
501
+ } // namespace proofs
502
+
503
+ #endif // PRIVACY_PROOFS_ZK_LIB_GF2K_GF2_128_H_
@@ -0,0 +1,48 @@
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 <cstddef>
16
+
17
+ #include "gf2k/gf2_128.h"
18
+ #include "third_party/benchmark/include/benchmark/benchmark.h"
19
+
20
+ namespace proofs {
21
+ using Field = GF2_128<>;
22
+ using Elt = Field::Elt;
23
+ static const Field F;
24
+
25
+ void BM_gf2_128(benchmark::State& state) {
26
+ Elt x = F.of_scalar(2);
27
+ Elt y[1000];
28
+ for (auto _ : state) {
29
+ benchmark::DoNotOptimize(&x);
30
+ for (size_t j = 0; j < 1000; ++j) {
31
+ y[j] = x;
32
+ x = F.mulf(x, x);
33
+ }
34
+ for (size_t i = 0; i < 1000 * 1000; ++i) {
35
+ for (size_t j = 0; j < 1000; ++j) {
36
+ y[j] = F.mulf(y[j], x);
37
+ }
38
+ x = F.mulf(x, x);
39
+ }
40
+ for (size_t j = 0; j < 1000; ++j) {
41
+ x = F.mulf(y[j], x);
42
+ }
43
+ }
44
+ }
45
+ BENCHMARK(BM_gf2_128);
46
+ } // namespace proofs
47
+
48
+ BENCHMARK_MAIN();