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,533 @@
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_ALGEBRA_FP_GENERIC_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_FP_GENERIC_H_
17
+
18
+ #include <array>
19
+ #include <cstddef>
20
+ #include <cstdint>
21
+ #include <functional>
22
+ #include <optional>
23
+ #include <utility>
24
+
25
+ #include "algebra/nat.h"
26
+ #include "algebra/static_string.h"
27
+ #include "algebra/sysdep.h"
28
+ #include "util/panic.h"
29
+
30
+ namespace proofs {
31
+ struct PrimeFieldTypeTag {};
32
+
33
+ /*
34
+ The Fp_generic class contains the implementation of a finite field.
35
+ */
36
+ template <size_t W64, bool optimized_mul, class OPS>
37
+ class FpGeneric {
38
+ public:
39
+ // Type alias for a natural number, and the limbs within the nat are public
40
+ // to allow casting and operations.
41
+ using N = Nat<W64>;
42
+ using limb_t = typename N::limb_t;
43
+ using TypeTag = PrimeFieldTypeTag;
44
+
45
+ static constexpr size_t kU64 = N::kU64;
46
+ static constexpr size_t kBytes = N::kBytes;
47
+ static constexpr size_t kSubFieldBytes = kBytes;
48
+ static constexpr size_t kBits = N::kBits;
49
+ static constexpr size_t kSubFieldBits = kBits;
50
+ static constexpr size_t kLimbs = N::kLimbs;
51
+
52
+ static constexpr bool kCharacteristicTwo = false;
53
+ static constexpr bool kSupportsDot = true;
54
+ static constexpr size_t kNPolyEvaluationPoints = 6;
55
+ N m_;
56
+ size_t exact_bits_;
57
+
58
+ /* The Elt struct represented an element in the finite field.
59
+ */
60
+ struct Elt {
61
+ N n;
62
+ bool operator==(const Elt& y) const { return n == y.n; }
63
+ bool operator!=(const Elt& y) const { return !operator==(y); }
64
+ };
65
+
66
+ explicit FpGeneric(const N& modulus)
67
+ : m_(modulus), exact_bits_(kBits), negm_(N{}) {
68
+ negm_.sub(m_);
69
+
70
+ // Compute the exact number of bits in the modulus.
71
+ // This value helps with sampling.
72
+ exact_bits_ = kBits;
73
+ while (m_.bit(exact_bits_ - 1) == 0) {
74
+ --exact_bits_;
75
+ }
76
+
77
+ // compute rawhalf = (m + 1) / 2 = floor(m / 2) + 1 since m is odd
78
+ N raw_half = m_;
79
+ raw_half.shiftr(1);
80
+ raw_half.add(N(1));
81
+ raw_half_ = Elt{raw_half};
82
+
83
+ mprime_ = -inv_mod_b(m_.limb_[0]);
84
+ rsquare_ = Elt{N(1)};
85
+ for (size_t bits = 0; bits < 2 * kBits; ++bits) {
86
+ add(rsquare_, rsquare_);
87
+ }
88
+
89
+ for (uint64_t i = 0; i < sizeof(k_) / sizeof(k_[0]); ++i) {
90
+ // convert k_[i] into montgomery form by calling mul0()
91
+ // directly, since mul() requires k_[0] and k_[1] to be
92
+ // defined
93
+ k_[i] = Elt{N(i)};
94
+ mul0(k_[i].n, rsquare_);
95
+ }
96
+
97
+ mone_ = negf(k_[1]);
98
+ half_ = invertf(k_[2]);
99
+
100
+ for (size_t i = 0; i < kNPolyEvaluationPoints; ++i) {
101
+ poly_evaluation_points_[i] = of_scalar(i);
102
+ if (i == 0) {
103
+ inv_small_scalars_[i] = zero();
104
+ } else {
105
+ inv_small_scalars_[i] = invertf(poly_evaluation_points_[i]);
106
+ }
107
+ }
108
+ }
109
+
110
+ explicit FpGeneric(const StaticString s) : FpGeneric(N(s)) {}
111
+
112
+ template <size_t LEN>
113
+ explicit FpGeneric(const char (&s)[LEN]) : FpGeneric(N(s)) {}
114
+
115
+ // Hack: works only if OPS::modulus is defined, and will
116
+ // fail to compile otherwise.
117
+ explicit FpGeneric() : FpGeneric(N(OPS::kModulus)) {}
118
+
119
+ FpGeneric(const FpGeneric&) = delete;
120
+ FpGeneric& operator=(const FpGeneric&) = delete;
121
+
122
+ template <size_t N>
123
+ Elt of_string(const char (&s)[N]) const {
124
+ return of_charp(&s[0]);
125
+ }
126
+
127
+ Elt of_string(const StaticString& s) const { return of_charp(s.as_pointer); }
128
+
129
+ std::optional<Elt> of_untrusted_string(const char* s) const {
130
+ auto maybe = N::of_untrusted_string(s);
131
+ if (maybe.has_value() && fits(maybe.value())) {
132
+ return to_montgomery(maybe.value());
133
+ } else {
134
+ return std::nullopt;
135
+ }
136
+ }
137
+
138
+ // Field arithmetic. We allow field operations on both Nat and Elt,
139
+ // the idea being that Elt is a Nat in Montgomery form, and
140
+ // Montgomery is just multiplication by a constant. Thus,
141
+ // we allow addition and subtraction of Nats, and multiplication
142
+ // of Nat by Elt, but not Nat by Nat since we only
143
+ // have a Montgomery multiplier.
144
+
145
+ // a += y
146
+ void add(N& a, const N& y) const {
147
+ if (kLimbs == 1) {
148
+ limb_t aa = a.limb_[0], yy = y.limb_[0], mm = m_.limb_[0];
149
+ a.limb_[0] = addcmovc(aa - mm, yy, aa + yy);
150
+ } else {
151
+ limb_t ah = add_limb(kLimbs, a.limb_, y.limb_);
152
+ maybe_minus_m(a.limb_, ah);
153
+ }
154
+ }
155
+
156
+ void add(Elt& a, const Elt& y) const { add(a.n, y.n); }
157
+
158
+ // a -= y
159
+ //
160
+ void sub(N& a, const N& y) const {
161
+ if (kLimbs == 1) {
162
+ a.limb_[0] = sub_sysdep(a.limb_[0], y.limb_[0], m_.limb_[0]);
163
+ } else {
164
+ limb_t ah = sub_limb(kLimbs, a.limb_, y.limb_);
165
+ maybe_plus_m(a.limb_, ah);
166
+ }
167
+ }
168
+
169
+ void sub(Elt& a, const Elt& y) const { sub(a.n, y.n); }
170
+
171
+ // x *= y, Montgomery
172
+ void mul(Elt& x, const Elt& y) const {
173
+ if (optimized_mul) {
174
+ if (x == zero() || y == one()) {
175
+ return;
176
+ }
177
+ if (y == zero() || x == one()) {
178
+ x = y;
179
+ return;
180
+ }
181
+ }
182
+ mul0(x.n, y);
183
+ }
184
+
185
+ // Nat by Elt
186
+ void mul(N& x, const Elt& y) const { mul0(x, y); }
187
+
188
+ // x = -x
189
+ void neg(Elt& x) const {
190
+ Elt y(k_[0]);
191
+ sub(y, x);
192
+ x = y;
193
+ }
194
+
195
+ // x = 1/x
196
+ void invert(Elt& x) const { x = invertf(x); }
197
+
198
+ // functional interface
199
+ Elt addf(Elt a, const Elt& y) const {
200
+ add(a, y);
201
+ return a;
202
+ }
203
+ Elt subf(Elt a, const Elt& y) const {
204
+ sub(a, y);
205
+ return a;
206
+ }
207
+ Elt mulf(Elt a, const Elt& y) const {
208
+ mul(a, y);
209
+ return a;
210
+ }
211
+ Elt negf(Elt a) const {
212
+ neg(a);
213
+ return a;
214
+ }
215
+
216
+ // This is the binary extended gcd algorithm, modified
217
+ // to return the inverse of x.
218
+ Elt invertf(Elt x) const {
219
+ N a = from_montgomery(x);
220
+ N b = m_;
221
+ Elt u = one();
222
+ Elt v = zero();
223
+ while (a != /*zero*/ N{}) {
224
+ if ((a.limb_[0] & 0x1u) == 0) {
225
+ a.shiftr(1);
226
+ byhalf(u);
227
+ } else {
228
+ if (a < b) { // swap to maintain invariant
229
+ std::swap(a, b);
230
+ std::swap(u, v);
231
+ }
232
+ a.sub(b).shiftr(1); // a = (a-b)/2
233
+ sub(u, v);
234
+ byhalf(u);
235
+ }
236
+ }
237
+ return v;
238
+ }
239
+
240
+ // Reference implementation, unused.
241
+ N from_montgomery_reference(const Elt& x) const {
242
+ Elt r{N(1)};
243
+ mul(r, x);
244
+ return r.n;
245
+ }
246
+
247
+ // Optimized implementation of from_montgomery_reference(), exploiting
248
+ // the fact that the multiplicand is Elt{N(1)}.
249
+ N from_montgomery(const Elt& x) const {
250
+ limb_t a[2 * kLimbs + 1]; // uninitialized
251
+ mov(kLimbs, a, x.n.limb_);
252
+ a[kLimbs] = zero_limb<limb_t>();
253
+ for (size_t i = 0; i < kLimbs; ++i) {
254
+ a[i + kLimbs + 1] = zero_limb<limb_t>();
255
+ OPS::reduction_step(&a[i], mprime_, m_);
256
+ }
257
+ maybe_minus_m(a + kLimbs, a[2 * kLimbs]);
258
+ N r;
259
+ mov(kLimbs, r.limb_, a + kLimbs);
260
+ return r;
261
+ }
262
+
263
+ Elt to_montgomery(const N& xn) const {
264
+ Elt x{xn};
265
+ mul(x, rsquare_);
266
+ return x;
267
+ }
268
+
269
+ bool in_subfield(const Elt& e) const { return true; }
270
+
271
+ bool fits(uint64_t a) const { return fits(N(a)); }
272
+ bool fits(const N& a) const { return a < m_; }
273
+
274
+ // The of_scalar methods should only be used on trusted inputs known
275
+ // at compile time to be valid field elements. As a result, they return
276
+ // Elt directly instead of std::optional, and panic if the condition is not
277
+ // satisfied. All untrusted input should be handled via the of_bytes method.
278
+ Elt of_scalar(uint64_t a) const { return of_scalar_field(a); }
279
+
280
+ // basis for the binary representation of of_scalar(), so that
281
+ // of_scalar(sum_i b[i] 2^i) = sum_i b[i] beta(i)
282
+ Elt beta(size_t i) const {
283
+ check(i < 64, "i < 64");
284
+ return of_scalar(static_cast<uint64_t>(1) << i);
285
+ }
286
+
287
+ Elt of_scalar_field(uint64_t a) const { return of_scalar_field(N(a)); }
288
+ Elt of_scalar_field(const std::array<uint64_t, W64>& a) const {
289
+ return of_scalar_field(N(a));
290
+ }
291
+ Elt of_scalar_field(const N& a) const {
292
+ check(fits(a), "of_scalar must be less than m");
293
+ return to_montgomery(a);
294
+ }
295
+
296
+ // Reduction of a Nat<WX> into a field Elt.
297
+ // For optimization purposes, the reduce() algorithm
298
+ // computes a scaled answer which must be normalized at the end.
299
+ // The scale factor is computed by a relatively slow routine
300
+ // reduce_scale(), which returns a special type indexed
301
+ // by WX to avoid confusion.
302
+ template <size_t WX>
303
+ struct ScaleElt {
304
+ Elt e;
305
+ };
306
+
307
+ template <size_t WX>
308
+ ScaleElt<WX> reduce_scale() const {
309
+ Elt e = rsquare_;
310
+ for (size_t i = 0; i < Nat<WX>::kBits; ++i) {
311
+ add(e, e);
312
+ }
313
+ return ScaleElt<WX>{e};
314
+ }
315
+
316
+ template <size_t WX>
317
+ Elt reduce(const Nat<WX>& x, const ScaleElt<WX>& scale) const {
318
+ Elt r;
319
+ r.n = reduce_nat(x);
320
+ mul(r, scale.e);
321
+ return r;
322
+ }
323
+
324
+ template <size_t WX>
325
+ Elt reduce(const Nat<WX>& x) const {
326
+ return reduce(x, reduce_scale<WX>());
327
+ }
328
+
329
+ std::optional<Elt> of_bytes_field(const uint8_t ab[/* kBytes */]) const {
330
+ N an = N::of_bytes(ab);
331
+ if (fits(an)) {
332
+ return to_montgomery(an);
333
+ } else {
334
+ return std::nullopt;
335
+ }
336
+ }
337
+
338
+ // Samples a uniformly random element from the field by repeatedly
339
+ // generating random bytes and reducing them modulo `m_`. The sampling
340
+ // continues until a value less than `m_` is obtained. The `fill_bytes`
341
+ // function is used to obtain random bytes, and `exact_bits_` determines
342
+ // how many bits to sample for each attempt. Without masking the sample to the
343
+ // exact_bits, the method would take a long time when the modulus is far from
344
+ // an exact multiple of the number of limbs.
345
+ Elt sample(
346
+ const std::function<void(size_t n, uint8_t buf[])>& fill_bytes) const {
347
+ size_t total_l = (exact_bits_ + 7) / 8;
348
+ uint8_t buf[kBytes] = {0};
349
+ for (;;) {
350
+ fill_bytes(total_l, buf);
351
+ N an = N::of_bytes(buf, exact_bits_);
352
+ if (an < m_) {
353
+ return to_montgomery(an);
354
+ }
355
+ }
356
+ }
357
+
358
+ Elt sample_subfield(
359
+ const std::function<void(size_t n, uint8_t buf[])>& fill_bytes) const {
360
+ return sample(fill_bytes);
361
+ }
362
+
363
+ void to_bytes_field(uint8_t ab[/* kBytes */], const Elt& x) const {
364
+ from_montgomery(x).to_bytes(ab);
365
+ }
366
+
367
+ std::optional<Elt> of_bytes_subfield(const uint8_t ab[/* kBytes */]) const {
368
+ return of_bytes_field(ab);
369
+ }
370
+
371
+ void to_bytes_subfield(uint8_t ab[/* kBytes */], const Elt& x) const {
372
+ to_bytes_field(ab, x);
373
+ }
374
+
375
+ const Elt& zero() const { return k_[0]; }
376
+ const Elt& one() const { return k_[1]; }
377
+ const Elt& two() const { return k_[2]; }
378
+ const Elt& half() const { return half_; }
379
+ const Elt& mone() const { return mone_; }
380
+
381
+ Elt poly_evaluation_point(size_t i) const {
382
+ check(i < kNPolyEvaluationPoints, "i < kNPolyEvaluationPoints");
383
+ return poly_evaluation_points_[i];
384
+ }
385
+
386
+ // return (X[k] - X[k - i])^{-1}, were X[i] is the
387
+ // i-th poly evalaluation point.
388
+ Elt newton_denominator(size_t k, size_t i) const {
389
+ check(k < kNPolyEvaluationPoints, "k < kNPolyEvaluationPoints");
390
+ check(i <= k, "i <= k");
391
+ check(k != (k - i), "k != (k - i)");
392
+ return inv_small_scalars_[/* k - (k - i) = */ i];
393
+ }
394
+
395
+ // Type for counters. For prime fields counters and field
396
+ // elements have the same representation, so all conversions
397
+ // are trivial.
398
+ struct CElt {
399
+ Elt e;
400
+ };
401
+ CElt as_counter(uint64_t a) const { return CElt{of_scalar_field(a)}; }
402
+
403
+ // Convert a counter into *some* field element such that the counter is
404
+ // zero (as a counter) iff the field element is zero.
405
+ Elt znz_indicator(const CElt& celt) const { return celt.e; }
406
+
407
+ // dot product
408
+ struct NatScaledForDot {
409
+ N n;
410
+ };
411
+ NatScaledForDot prescale_for_dot(Elt e) const {
412
+ ScaleElt<W64 + 2> scale = reduce_scale<W64 + 2>();
413
+ mul(e, scale.e);
414
+ return NatScaledForDot{from_montgomery(e)};
415
+ }
416
+ Elt dot(size_t n, const Nat<1> a[/*n*/],
417
+ const NatScaledForDot b[/*n*/]) const {
418
+ Nat<W64 + 2> s{};
419
+ for (size_t i = 0; i < n; ++i) {
420
+ s.mac(a[i], b[i].n);
421
+ }
422
+ return Elt{reduce_nat(s)};
423
+ }
424
+
425
+ private:
426
+ void maybe_minus_m(limb_t a[kLimbs], limb_t ah) const {
427
+ limb_t a1[kLimbs];
428
+ mov(kLimbs, a1, negm_.limb_);
429
+ limb_t ah1 = add_limb(kLimbs, a1, a);
430
+ cmovne(kLimbs, a, ah, ah1, a1);
431
+ }
432
+ void maybe_plus_m(limb_t a[kLimbs], limb_t ah) const {
433
+ limb_t a1[kLimbs];
434
+ mov(kLimbs, a1, a);
435
+ (void)add_limb(kLimbs, a1, m_.limb_);
436
+ cmovnz(kLimbs, a, ah, a1);
437
+ }
438
+
439
+ void byhalf(Elt& a) const {
440
+ if (a.n.shiftr(1) != 0) {
441
+ // the lost bit is a raw 1, not one() in Montgomery form,
442
+ // hence we must add a raw 1/2, not half().
443
+ add(a, raw_half_);
444
+ }
445
+ }
446
+
447
+ // unoptimized montgomery multiplication that does not
448
+ // depend on the constants zero() and one() being defined.
449
+ void mul0(N& x, const Elt& y) const {
450
+ limb_t a[2 * kLimbs + 1]; // uninitialized
451
+ mulstep<true>(a, x.limb_[0], y.n.limb_);
452
+ for (size_t i = 1; i < kLimbs; ++i) {
453
+ mulstep<false>(a + i, x.limb_[i], y.n.limb_);
454
+ }
455
+ maybe_minus_m(a + kLimbs, a[2 * kLimbs]);
456
+ mov(kLimbs, x.limb_, a + kLimbs);
457
+ }
458
+
459
+ template <bool first>
460
+ inline void mulstep(limb_t* a, limb_t x, const limb_t y[kLimbs]) const {
461
+ if (kLimbs == 1) {
462
+ // The general case (below) represents the (kLimbs+1)-word
463
+ // product as L+(H<<bitsPerLimb), where in general L and H
464
+ // overlap, requiring two additions. For kLimbs==1, L and H do
465
+ // not overlap, and we can interpret [L, H] as a single
466
+ // double-precision number.
467
+ a[2] = zero_limb<limb_t>();
468
+ check(first, "mulstep template must be have first=true for 1 limb");
469
+ mulhl(1, a, a + 1, x, y);
470
+ OPS::reduction_step(a, mprime_, m_);
471
+ } else {
472
+ limb_t l[kLimbs], h[kLimbs];
473
+ a[kLimbs + 1] = zero_limb<limb_t>();
474
+ if (first) {
475
+ a[kLimbs] = zero_limb<limb_t>();
476
+ mulhl(kLimbs, a, h, x, y);
477
+ } else {
478
+ mulhl(kLimbs, l, h, x, y);
479
+ accum(kLimbs + 1, a, kLimbs, l);
480
+ }
481
+ accum(kLimbs + 1, a + 1, kLimbs, h);
482
+ OPS::reduction_step(a, mprime_, m_);
483
+ }
484
+ }
485
+
486
+ // This method should only be used on static strings known at
487
+ // compile time to be valid field elements. We make it
488
+ // private to prevent misuse.
489
+ Elt of_charp(const char* s) const {
490
+ Elt a(k_[0]);
491
+ Elt base = of_scalar(10);
492
+ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
493
+ s += 2;
494
+ base = of_scalar(16);
495
+ }
496
+
497
+ for (; *s; s++) {
498
+ Elt d = of_scalar(digit(*s));
499
+ mul(a, base);
500
+ add(a, d);
501
+ }
502
+ return a;
503
+ }
504
+
505
+ // Unscaled reduction of X into a Nat<W64>. The result
506
+ // must be multiplied by reduce_scale<WX>
507
+ template <size_t WX>
508
+ N reduce_nat(const Nat<WX>& x) const {
509
+ constexpr size_t kLimbsX = Nat<WX>::kLimbs;
510
+ limb_t a[kLimbs + kLimbsX + 1] = {};
511
+ for (size_t i = 0; i < kLimbsX; ++i) {
512
+ accum(kLimbs + 1, &a[i], 1, &x.limb_[i]);
513
+ OPS::reduction_step(&a[i], mprime_, m_);
514
+ }
515
+ maybe_minus_m(a + kLimbsX, a[kLimbs + kLimbsX]);
516
+ N n;
517
+ mov(kLimbs, n.limb_, a + kLimbsX);
518
+ return n;
519
+ }
520
+
521
+ N negm_;
522
+ Elt rsquare_; // 2^(kbits + kBits) mod p
523
+ limb_t mprime_;
524
+ Elt k_[3]; // small constants
525
+ Elt half_; // 1/2
526
+ Elt raw_half_;
527
+ Elt mone_; // minus one
528
+ Elt poly_evaluation_points_[kNPolyEvaluationPoints];
529
+ Elt inv_small_scalars_[kNPolyEvaluationPoints];
530
+ };
531
+ } // namespace proofs
532
+
533
+ #endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_FP_GENERIC_H_
@@ -0,0 +1,91 @@
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_ALGEBRA_FP_P128_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_FP_P128_H_
17
+
18
+ #include <array>
19
+ #include <cstdint>
20
+
21
+ #include "algebra/fp_generic.h"
22
+ #include "algebra/nat.h"
23
+ #include "algebra/sysdep.h"
24
+
25
+ namespace proofs {
26
+ // Optimized implementation of Fp(2^128 - 2^108 + 1). We call this
27
+ // prime P128 because of lack of imagination, but unlike P256,
28
+ // this is not a NIST standard name. The field contains
29
+ // roots of unity of order 2^108.
30
+
31
+ // Root of unity from pari-gp:
32
+ // ? p=2^128-2^108+1
33
+ // %1 = 340282042402384805036647824275747635201
34
+ // ? g=ffgen(x+Mod(1,p))
35
+ // %2 = 340282042402384805036647824275747635200
36
+ // ? w=sqrtn(g,2^107)
37
+ // %3 = 17166008163159356379329005055841088858
38
+ //
39
+ // ? w=Mod(17166008163159356379329005055841088858, p)
40
+ // %4 = Mod(17166008163159356379329005055841088858,
41
+ // 340282042402384805036647824275747635201)
42
+ // ? w^(2^107)
43
+ // %5 = Mod(340282042402384805036647824275747635200,
44
+ // 340282042402384805036647824275747635201)
45
+ // ? w^(2^108)
46
+ // %6 = Mod(1, 340282042402384805036647824275747635201)
47
+ //
48
+ // Root of unity of order 32:
49
+ // ? w32=w^(2^(108-32))
50
+ // %15 = Mod(164956748514267535023998284330560247862,
51
+ // 340282042402384805036647824275747635201)
52
+ // ? w32^(2^31)
53
+ // %16 = Mod(340282042402384805036647824275747635200,
54
+ // 340282042402384805036647824275747635201)
55
+ // ? w32^(2^32)
56
+ // %17 = Mod(1, 340282042402384805036647824275747635201)
57
+
58
+ /*
59
+ This struct contains an optimized reduction step for the chosen field.
60
+ */
61
+ struct Fp128Reduce {
62
+ // Harcoded base_64 modulus.
63
+ static const constexpr std::array<uint64_t, 2> kModulus = {
64
+ 0x0000000000000001u,
65
+ 0xFFFFF00000000000u,
66
+ };
67
+
68
+ static inline void reduction_step(uint64_t a[], uint64_t mprime,
69
+ const Nat<2>& m) {
70
+ uint64_t r = -a[0];
71
+ uint64_t sub[2] = {r << 44, r >> 20};
72
+ uint64_t add[3] = {r, 0, r};
73
+ accum(4, a, 3, add);
74
+ negaccum(3, a + 1, 2, sub);
75
+ }
76
+
77
+ static inline void reduction_step(uint32_t a[], uint32_t mprime,
78
+ const Nat<2>& m) {
79
+ uint32_t r = -a[0];
80
+ uint32_t sub[2] = {r << 12, r >> 20};
81
+ uint32_t add[5] = {r, 0, 0, 0, r};
82
+ accum(6, a, 5, add);
83
+ negaccum(3, a + 3, 2, sub);
84
+ }
85
+ };
86
+
87
+ template <bool optimized_mul = false>
88
+ using Fp128 = FpGeneric<2, optimized_mul, Fp128Reduce>;
89
+ } // namespace proofs
90
+
91
+ #endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_FP_P128_H_
@@ -0,0 +1,68 @@
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_ALGEBRA_FP_P256_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_FP_P256_H_
17
+
18
+ #include <array>
19
+ #include <cstdint>
20
+
21
+ #include "algebra/fp_generic.h"
22
+ #include "algebra/nat.h"
23
+ #include "algebra/sysdep.h"
24
+
25
+ namespace proofs {
26
+ // Optimized implementation of
27
+ // Fp(115792089210356248762697446949407573530086143415290314195533631308867097853951)
28
+
29
+ /*
30
+ This struct contains an optimized reduction step for the chosen field.
31
+ */
32
+ struct Fp256Reduce {
33
+ // Harcoded base_64 modulus.
34
+ static const constexpr std::array<uint64_t, 4> kModulus = {
35
+ 0xFFFFFFFFFFFFFFFFu,
36
+ 0xFFFFFFFFu,
37
+ 0,
38
+ 0xFFFFFFFF00000001u,
39
+ };
40
+
41
+
42
+ static inline void reduction_step(uint64_t a[], uint64_t mprime,
43
+ const Nat<4>& m) {
44
+ // p = 2^256 - 2^224 + 2^192 + 2^96 - 1
45
+ // mprime = 1.
46
+ // This step computes a += (mprime * a0) * p
47
+ uint64_t r = a[0];
48
+ uint64_t l[5] = {r, 0, 0, r << 32, r >> 32};
49
+ negaccum(6, a, 5, l);
50
+ uint64_t h[4] = {r << 32, r >> 32, r, r};
51
+ accum(5, a + 1, 4, h);
52
+ }
53
+
54
+ static inline void reduction_step(uint32_t a[], uint32_t mprime,
55
+ const Nat<4>& m) {
56
+ uint32_t r = a[0];
57
+ uint32_t l[8] = {r, 0, 0, 0, 0, 0, 0, r};
58
+ negaccum(10, a, 8, l);
59
+ uint32_t h[6] = {r, 0, 0, r, 0, r};
60
+ accum(7, a + 3, 6, h);
61
+ }
62
+ };
63
+
64
+ template <bool optimized_mul = false>
65
+ using Fp256 = FpGeneric<4, optimized_mul, Fp256Reduce>;
66
+ } // namespace proofs
67
+
68
+ #endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_FP_P256_H_