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,596 @@
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_ELLIPTIC_CURVE_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_EC_ELLIPTIC_CURVE_H_
17
+
18
+ #include <cstddef>
19
+ #include <cstdint>
20
+
21
+ #include "algebra/nat.h"
22
+ #include "util/panic.h"
23
+
24
+ namespace proofs {
25
+ // Elliptic curve class that supports basic operations such as addition,
26
+ // doubling. The algorithms are described in
27
+ // https://eprint.iacr.org/2015/1060.pdf.
28
+ // The const Field parameter is meant as a type check to keep different
29
+ // elliptic curves from interacting. The convention is to use the last 5
30
+ // digits of the coordinate field prime in base-10 to name a curve.
31
+ // The kN template parameter describes the number of bits in the curve
32
+ // order, e.g., to handle curves like P-521, K-283, etc.
33
+ template <class Field_, size_t W, size_t kN>
34
+ class EllipticCurve {
35
+ public:
36
+ using Field = Field_;
37
+ using Elt = typename Field::Elt;
38
+ using N = Nat<W>;
39
+
40
+ static constexpr const size_t kBits = kN; /* # bits in size of the group */
41
+
42
+ const Field& f_;
43
+ Elt a_;
44
+ Elt b_;
45
+ Elt gx_, gy_, gz_; // generator of the group
46
+ const Elt k2, k3, k8, k3b, k9b, k24b;
47
+
48
+ struct ECPoint {
49
+ Elt x;
50
+ Elt y;
51
+ Elt z;
52
+
53
+ ECPoint() = default;
54
+ ECPoint(const Elt& x, const Elt& y, const Elt& z) : x(x), y(y), z(z) {}
55
+ };
56
+
57
+ EllipticCurve(const Elt& a, const Elt& b, const Elt& gX, const Elt& gY,
58
+ const Field_& F)
59
+ : f_(F),
60
+ a_(a),
61
+ b_(b),
62
+ gx_(gX),
63
+ gy_(gY),
64
+ gz_(F.one()),
65
+ k2(F.of_scalar(2)),
66
+ k3(F.of_scalar(3)),
67
+ k8(F.of_scalar(8)),
68
+ k3b(F.mulf(k3, b_)),
69
+ k9b(F.mulf(F.of_scalar(9), b_)),
70
+ k24b(F.mulf(F.of_scalar(24), b_)) {
71
+ is_minus_3_a_ = (a_ == F.negf(k3));
72
+ is_zero_a_ = (a_ == F.zero());
73
+ }
74
+
75
+ // This equality method makes no assumptions about whether the inputs
76
+ // are valid points on the curve. Just verifying cross-mult is not
77
+ // enough if one of the points is invalid. This method is not constant
78
+ // time and can return early if any point is infinity.
79
+ bool equal(const ECPoint& p, const ECPoint& q) const {
80
+ // handle inf point, then point equality, and finally projective eq
81
+ if (q.x == f_.zero() && q.z == f_.zero() && q.y != f_.zero() &&
82
+ p.x == f_.zero() && p.z == f_.zero() && p.y != f_.zero()) {
83
+ return true;
84
+ }
85
+ if (q.x == p.x && q.z == p.z && q.y == p.y) {
86
+ return true;
87
+ }
88
+
89
+ return (f_.mulf(p.x, q.z) == f_.mulf(q.x, p.z) &&
90
+ f_.mulf(p.y, q.z) == f_.mulf(q.y, p.z));
91
+ }
92
+
93
+ // This method assumes a point is either zero or has z=1 coordinate,
94
+ // so it does not implement the full mathematical notion of Jacobian-form
95
+ // ec point.
96
+ bool is_on_curve(const ECPoint& p) const {
97
+ if (equal(p, zero())) {
98
+ return true;
99
+ }
100
+ // Do not support Jacobian coordinate with z != 1"
101
+ if (p.z != f_.one()) {
102
+ return false;
103
+ }
104
+ return is_on_curve(p.x, p.y);
105
+ }
106
+
107
+ // This caller of the constructor must first verify that (x,y) is on the
108
+ // curve using the isOnCurve() method.
109
+ ECPoint point(const Elt& x, const Elt& y) const {
110
+ ECPoint p(x, y, f_.one());
111
+ check(is_on_curve(p), "Invalid curve point");
112
+ return p;
113
+ }
114
+
115
+ void normalize(ECPoint& p) const {
116
+ if (p.z == f_.zero()) return;
117
+ f_.invert(p.z);
118
+ f_.mul(p.x, p.z);
119
+ f_.mul(p.y, p.z);
120
+ p.z = f_.one();
121
+ }
122
+
123
+ void addE(ECPoint& p3, const ECPoint& p2) const {
124
+ addE(p3.x, p3.y, p3.z, p3.x, p3.y, p3.z, p2.x, p2.y, p2.z);
125
+ }
126
+
127
+ void doubleE(ECPoint& p3) const {
128
+ doubleE(p3.x, p3.y, p3.z, p3.x, p3.y, p3.z);
129
+ }
130
+
131
+ // Functional interface.
132
+ ECPoint addEf(ECPoint p1, const ECPoint& p2) const {
133
+ addE(p1, p2);
134
+ return p1;
135
+ }
136
+
137
+ ECPoint doubleEf(ECPoint p1) const {
138
+ doubleE(p1);
139
+ return p1;
140
+ }
141
+
142
+ // Computes the elliptic curve point p * scalar.
143
+ // This method is not constant time, but that is not necessary in the current
144
+ // zk implementation.
145
+ ECPoint scalar_multf(const ECPoint& p, const N& scalar) const {
146
+ ECPoint x = p;
147
+ ECPoint p3 = zero();
148
+ for (size_t d = 0; d < N::kLimbs; ++d) {
149
+ auto nd = scalar.limb_[d];
150
+ for (size_t i = 0; i < N::kBitsPerLimb; ++i) {
151
+ if (nd & 1) {
152
+ addE(p3, x);
153
+ }
154
+ doubleE(x);
155
+ nd >>= 1;
156
+ }
157
+ }
158
+ return p3;
159
+ }
160
+
161
+ // Computes the multi-scalar elliptic curve point multiplication.
162
+ // Input: p1, p2, ..., pn, and scalars s1, s2, ..., sn
163
+ // Output: p1 * s1 + p2 * s2 + ... + pn * sn
164
+ // This method is not a constant time operation.
165
+ ECPoint scalar_multf(size_t n, ECPoint p[/*n*/], N scalar[/*n*/]) const {
166
+ if (n == 0) {
167
+ return zero();
168
+ } else if (n == 1) {
169
+ return scalar_multf(p[0], scalar[0]);
170
+ } else {
171
+ return bos_coster(n, p, scalar);
172
+ }
173
+ }
174
+
175
+ ECPoint zero() const { return ECPoint(f_.zero(), f_.one(), f_.zero()); }
176
+ ECPoint generator() const { return ECPoint(gx_, gy_, gz_); }
177
+
178
+ // Check whether Y^2 = X^3 + aX + b.
179
+ bool is_on_curve(const Elt& X, const Elt& Y) const {
180
+ Elt left = f_.mulf(Y, Y);
181
+ Elt X3 = f_.mulf(X, f_.mulf(X, X));
182
+ Elt right = f_.addf(f_.addf(X3, f_.mulf(a_, X)), b_);
183
+ return left == right;
184
+ }
185
+
186
+ void addE(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X1, const Elt& Y1,
187
+ const Elt& Z1, const Elt& X2, const Elt& Y2, const Elt& Z2) const {
188
+ // Optimized special cases.
189
+ if (is_zero_a_) return addEZeroA(X3o, Y3o, Z3o, X1, Y1, Z1, X2, Y2, Z2);
190
+ if (is_minus_3_a_)
191
+ return addEMinus3A(X3o, Y3o, Z3o, X1, Y1, Z1, X2, Y2, Z2);
192
+
193
+ /*
194
+ Source: 1998 Cohen–Miyaji–Ono "Efficient elliptic curve exponentiation using
195
+ mixed coordinates", formula (3), plus common-subexpression elimination.
196
+ These equations are taken from the Hyperelliptic curve formula database.
197
+ This could have special short-cuts for addition with inf and self-addition,
198
+ which speeds up all multi-exponentiation computations that involve a lot of
199
+ small exponents.
200
+ */
201
+ if (X1 == f_.zero() && Z1 == f_.zero()) {
202
+ X3o = X2;
203
+ Y3o = Y2;
204
+ Z3o = Z2;
205
+ return;
206
+ }
207
+
208
+ if (X2 == f_.zero() && Z2 == f_.zero()) {
209
+ X3o = X1;
210
+ Y3o = Y1;
211
+ Z3o = Z1;
212
+ return;
213
+ }
214
+
215
+ Elt Y1Z2 = f_.mulf(Y1, Z2);
216
+ Elt X1Z2 = f_.mulf(X1, Z2);
217
+ Elt u = f_.subf(f_.mulf(Y2, Z1), Y1Z2);
218
+ Elt v = f_.subf(f_.mulf(X2, Z1), X1Z2);
219
+ if (u == f_.zero()) {
220
+ doubleE(X3o, Y3o, Z3o, X1, Y1, Z1);
221
+ return;
222
+ // Self addition, invoke Double method.
223
+ }
224
+ /* This check occurs after the u check.
225
+ If u!=0, but v=0, then the points are inverses.
226
+ */
227
+ if (v == f_.zero()) {
228
+ X3o = f_.zero();
229
+ Y3o = f_.one();
230
+ Z3o = f_.zero();
231
+ return;
232
+ }
233
+
234
+ Elt Z1Z2 = f_.mulf(Z1, Z2);
235
+ Elt uu = f_.mulf(u, u);
236
+ Elt vv = f_.mulf(v, v);
237
+ Elt vvv = f_.mulf(v, vv);
238
+ Elt R = f_.mulf(vv, X1Z2);
239
+ Elt A = f_.subf(f_.subf(f_.mulf(uu, Z1Z2), vvv), f_.mulf(k2, R));
240
+ Elt X3 = f_.mulf(v, A);
241
+ Elt Y3 = f_.subf(f_.mulf(u, f_.subf(R, A)), f_.mulf(vvv, Y1Z2));
242
+ Elt Z3 = f_.mulf(vvv, Z1Z2);
243
+
244
+ X3o = X3;
245
+ Y3o = Y3;
246
+ Z3o = Z3;
247
+ }
248
+
249
+ void doubleE(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X, const Elt& Y,
250
+ const Elt& Z) const {
251
+ // Optimized special cases.
252
+ if (is_zero_a_) return doubleEZeroA(X3o, Y3o, Z3o, X, Y, Z);
253
+ if (is_minus_3_a_) return doubleEMinus3A(X3o, Y3o, Z3o, X, Y, Z);
254
+
255
+ /*
256
+ // 1998 Cohen–Miyaji–Ono "Efficient elliptic curve exponentiation using
257
+ mixed coordinates", formula (4), This version of the double formula trades
258
+ general mults for mults by 2,4,8 which can be implemented with additions.
259
+ This results in savings of 200ns on double.
260
+ */
261
+ if (X == f_.zero() && Z == f_.zero()) {
262
+ X3o = X;
263
+ Y3o = f_.one();
264
+ Z3o = Z;
265
+ return;
266
+ }
267
+
268
+ Elt Z2 = f_.mulf(Z, Z);
269
+ Elt X2 = f_.mulf(X, X);
270
+ Elt X2_3 = f_.addf(f_.addf(X2, X2), X2);
271
+ Elt s = f_.mulf(Y, Z);
272
+ Elt ss = f_.mulf(s, s);
273
+ Elt sss = f_.mulf(s, ss);
274
+ Elt sss_2 = f_.addf(sss, sss);
275
+ Elt w = f_.addf(f_.mulf(a_, Z2), X2_3);
276
+ Elt R = f_.mulf(Y, s);
277
+ Elt sss_4 = f_.addf(sss_2, sss_2);
278
+ Elt B = f_.mulf(X, R);
279
+ Elt sss_8 = f_.addf(sss_4, sss_4);
280
+ Elt B_2 = f_.addf(B, B);
281
+ Elt R2 = f_.mulf(R, R);
282
+ Elt B_4 = f_.addf(B_2, B_2);
283
+ Elt B_8 = f_.addf(B_4, B_4);
284
+ Elt w2 = f_.mulf(w, w);
285
+ Elt h = f_.subf(w2, B_8);
286
+ Elt s_2 = f_.addf(s, s);
287
+ Elt X3 = f_.mulf(h, s_2);
288
+ Elt R2_2 = f_.addf(R2, R2);
289
+ Elt R2_4 = f_.addf(R2_2, R2_2);
290
+ Elt R2_8 = f_.addf(R2_4, R2_4);
291
+ Elt Y3 = f_.subf(f_.mulf(w, f_.subf(B_4, h)), R2_8);
292
+ Elt Z3 = sss_8;
293
+
294
+ X3o = X3;
295
+ Y3o = Y3;
296
+ Z3o = Z3;
297
+ }
298
+
299
+ private:
300
+ /* From Algorithm 7: Complete, projective point addition for prime order
301
+ j-invariant 0 short Weierstrass curves E/Fq : y^2 = x^3 + b.
302
+
303
+ X3 = (X1 Y2 + X2 Y1)(Y1 Y2 - 3b Z1 Z2) - 3b(Y1 Z2 + Y2 Z1)(X1 Z2 + X2 Z1)
304
+ Y3 = (Y1 Y2 + 3b Z1 Z2)(Y1 Y2 - 3b Z1 Z2) + 9b X1 X2 (X1 Z2 + X2 Z1)
305
+ Z3 = (Y1 Z2 + Y2 Z1)(Y1 Y2 + 3b Z1 Z2) + 3 X1 X2(X1 Y2 + X2 Y1)
306
+ */
307
+ void addEZeroA(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X1, const Elt& Y1,
308
+ const Elt& Z1, const Elt& X2, const Elt& Y2,
309
+ const Elt& Z2) const {
310
+ Elt t0 = f_.mulf(X2, Y1);
311
+ Elt t1 = f_.mulf(X1, Y2);
312
+ Elt t2 = f_.addf(t1, t0);
313
+ Elt t3 = f_.mulf(Y1, Y2);
314
+ Elt t4 = f_.mulf(Z1, Z2);
315
+ Elt t5 = f_.mulf(Y1, Z2);
316
+ Elt t6 = f_.mulf(Y2, Z1);
317
+ Elt t7 = f_.addf(t5, t6);
318
+ Elt t8 = f_.mulf(X1, Z2);
319
+ Elt t9 = f_.mulf(X2, Z1);
320
+ Elt t10 = f_.addf(t8, t9);
321
+ Elt t11 = f_.mulf(X1, X2);
322
+ Elt t12 = f_.mulf(k3b, t4);
323
+ Elt t13 = f_.addf(t3, t12);
324
+ Elt t14 = f_.subf(t3, t12);
325
+
326
+ X3o = f_.subf(f_.mulf(t2, t14), f_.mulf(k3b, f_.mulf(t7, t10)));
327
+ Y3o = f_.addf(f_.mulf(t13, t14), f_.mulf(k9b, f_.mulf(t11, t10)));
328
+ Z3o = f_.addf(f_.mulf(t7, t13), f_.mulf(k3, f_.mulf(t11, t2)));
329
+ }
330
+
331
+ /*Algorithm 4: Complete, projective point addition for prime order short
332
+ * Weierstrass curves E/Fq : y^2 = x^33 + ax + b with a = −3.
333
+ */
334
+ void addEMinus3A(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X1, const Elt& Y1,
335
+ const Elt& Z1, const Elt& X2, const Elt& Y2,
336
+ const Elt& Z2) const {
337
+ Elt t0 = f_.mulf(X1, X2);
338
+ Elt t1 = f_.mulf(Y1, Y2);
339
+ Elt t2 = f_.mulf(Z1, Z2);
340
+ Elt t3 = f_.addf(X1, Y1);
341
+ Elt t4 = f_.addf(X2, Y2);
342
+ t3 = f_.mulf(t3, t4);
343
+ t4 = f_.addf(t0, t1);
344
+ t3 = f_.subf(t3, t4);
345
+ t4 = f_.addf(Y1, Z1);
346
+ Elt X3 = f_.addf(Y2, Z2);
347
+ t4 = f_.mulf(t4, X3);
348
+ X3 = f_.addf(t1, t2);
349
+ t4 = f_.subf(t4, X3);
350
+ X3 = f_.addf(X1, Z1);
351
+ Elt Y3 = f_.addf(X2, Z2);
352
+ X3 = f_.mulf(X3, Y3);
353
+ Y3 = f_.addf(t0, t2);
354
+ Y3 = f_.subf(X3, Y3);
355
+ Elt Z3 = f_.mulf(b_, t2);
356
+ X3 = f_.subf(Y3, Z3);
357
+ Z3 = f_.addf(X3, X3);
358
+ X3 = f_.addf(X3, Z3);
359
+ Z3 = f_.subf(t1, X3);
360
+ X3 = f_.addf(t1, X3);
361
+ Y3 = f_.mulf(b_, Y3);
362
+ t1 = f_.addf(t2, t2);
363
+ t2 = f_.addf(t1, t2);
364
+ Y3 = f_.subf(Y3, t2);
365
+ Y3 = f_.subf(Y3, t0);
366
+ t1 = f_.addf(Y3, Y3);
367
+ Y3 = f_.addf(t1, Y3);
368
+ t1 = f_.addf(t0, t0);
369
+ t0 = f_.addf(t1, t0);
370
+ t0 = f_.subf(t0, t2);
371
+ t1 = f_.mulf(t4, Y3);
372
+ t2 = f_.mulf(t0, Y3);
373
+ Y3 = f_.mulf(X3, Z3);
374
+ Y3 = f_.addf(Y3, t2);
375
+ X3 = f_.mulf(t3, X3);
376
+ X3 = f_.subf(X3, t1);
377
+ Z3 = f_.mulf(t4, Z3);
378
+ t1 = f_.mulf(t3, t0);
379
+ Z3 = f_.addf(Z3, t1);
380
+
381
+ X3o = X3;
382
+ Y3o = Y3;
383
+ Z3o = Z3;
384
+ }
385
+
386
+ /* From Algorithm 6: Exception-free point doubling for prime order short
387
+ * Weierstrass curves E/Fq : y^2 = x^3 + ax + b with a = −3.
388
+ */
389
+ void doubleEMinus3A(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X, const Elt& Y,
390
+ const Elt& Z) const {
391
+ Elt t0 = f_.mulf(X, X);
392
+ Elt t1 = f_.mulf(Y, Y);
393
+ Elt t2 = f_.mulf(Z, Z);
394
+ Elt t3 = f_.mulf(X, Y);
395
+ t3 = f_.addf(t3, t3);
396
+ Elt Z3 = f_.mulf(X, Z);
397
+ Z3 = f_.addf(Z3, Z3);
398
+ Elt Y3 = f_.mulf(b_, t2);
399
+ Y3 = f_.subf(Y3, Z3);
400
+ Elt X3 = f_.addf(Y3, Y3);
401
+ Y3 = f_.addf(X3, Y3);
402
+ X3 = f_.subf(t1, Y3);
403
+ Y3 = f_.addf(t1, Y3);
404
+ Y3 = f_.mulf(X3, Y3);
405
+ X3 = f_.mulf(X3, t3);
406
+ t3 = f_.addf(t2, t2);
407
+ t2 = f_.addf(t2, t3);
408
+ Z3 = f_.mulf(b_, Z3);
409
+ Z3 = f_.subf(Z3, t2);
410
+ Z3 = f_.subf(Z3, t0);
411
+ t3 = f_.addf(Z3, Z3);
412
+ Z3 = f_.addf(Z3, t3);
413
+ t3 = f_.addf(t0, t0);
414
+ t0 = f_.addf(t3, t0);
415
+ t0 = f_.subf(t0, t2);
416
+ t0 = f_.mulf(t0, Z3);
417
+ Y3 = f_.addf(Y3, t0);
418
+ t0 = f_.mulf(Y, Z);
419
+ t0 = f_.addf(t0, t0);
420
+ Z3 = f_.mulf(t0, Z3);
421
+ X3 = f_.subf(X3, Z3);
422
+ Z3 = f_.mulf(t0, t1);
423
+ Z3 = f_.addf(Z3, Z3);
424
+ Z3 = f_.addf(Z3, Z3);
425
+
426
+ X3o = X3;
427
+ Y3o = Y3;
428
+ Z3o = Z3;
429
+ }
430
+
431
+ /* From Algorithm 9: Exception-free point doubling for prime order
432
+ j-invariant 0 short Weierstrass curves E/Fq y^2 = x^3 + b
433
+
434
+ X3 = 2XY (YY − 9bZZ)
435
+ Y3 = (YY − 9bZZ)(YY + 3bZZ) + 24bYYZZ
436
+ Z3 = 8YYYZ.
437
+ */
438
+ void doubleEZeroA(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X, const Elt& Y,
439
+ const Elt& Z) const {
440
+ Elt t0 = f_.mulf(X, Y);
441
+ Elt t1 = f_.mulf(Y, Y);
442
+ Elt t2 = f_.mulf(Z, Z);
443
+ Elt t4 = f_.mulf(Y, Z);
444
+ Elt t5 = f_.mulf(k9b, t2); // 9bZZ
445
+ Elt t6 = f_.subf(t1, t5); // YY - 9bZZ
446
+ Elt t7 = f_.mulf(k3b, t2); // 3bZZ
447
+ Elt t8 = f_.addf(t1, t7); // YY + 3bZZ
448
+ X3o = f_.mulf(k2, f_.mulf(t0, t6));
449
+ Y3o = f_.addf(f_.mulf(t6, t8), f_.mulf(k24b, f_.mulf(t1, t2)));
450
+ Z3o = f_.mulf(k8, f_.mulf(t1, t4));
451
+ }
452
+
453
+ //------------------------------------------------------------
454
+ // Multi-exponentiation SUM_i scalarMult(p[i], s[i])
455
+
456
+ // We follow the basic strategy outlined in Daniel J. Bernstein,
457
+ // Niels Duif, Tanja Lange, Peter Schwabe, and Bo-Yin Yang,
458
+ // "High-speed high-security signatures",
459
+ // https://eprint.iacr.org/2011/368, where Bernstein et al. credit
460
+ // the method to Bos and Coster via a reference to Peter de Rooij,
461
+ // "Efficient exponentiation using precomputation and vector
462
+ // addition chains", in Eurocrypt ’94. In my opinion [matteof@]
463
+ // the method of Bernstein et al. is not quite the same as the papers
464
+ // that they reference, but either way we follow Bernstein et al.
465
+ // with a few modifications, and call the method bos_coster() in
466
+ // this file.
467
+
468
+ // The basic idea is to keep the list (p[i], s[i]) of pairs
469
+ // (point, scalar) in descending order of scalar, so that s[0]
470
+ // is the maximum.
471
+
472
+ // Bernstein's method repeatedly replaces p[0]*s[0]+p[1]*s[1]
473
+ // by p[0]*(s[0]-s[1])+(p[0]+p[1])*s[1], where now the first
474
+ // scalar becomes smaller. Eventually all the scalars s[i] become
475
+ // 0 for i>=1.
476
+
477
+ // For random scalars, one can roughly expect s[0]-s[1] to be
478
+ // about |F|/n, so the method can be expected to set approximately
479
+ // log n scalar bits to zero in each iteration. However, its worst
480
+ // case is horrific. E.g., if s[1]=1 and s[0] is O(2**256), the
481
+ // method will require O(2**256) iterations to converge.
482
+
483
+ // To avoid this worst-case behavior, we depart from Bernstein and
484
+ // perform either a Bernstein step or a double-and-add step,
485
+ // whichever one decreases s[0] the most. A double-and-add writes
486
+ // s[0] = 2*a+b and replaces p[0]*s[0] with (2*p[0])*(s[0]/2) *
487
+ // b*p[0], where the second multiplication is trivial because b \in
488
+ // {0,1}. With this choice, we are guaranteed to eliminate at least
489
+ // one scalar bit per iteration, so the method is no worse than a
490
+ // loop of single scalar multiplications. Bernstein et al., page
491
+ // 17, are aware of the problem, but they say that doing anything
492
+ // about it is "not worthwhile". On the other hand, the fix doesn't
493
+ // cost anything either, so may as well do it. (Bernstein et
494
+ // al. propose a different fix.)
495
+
496
+ // For easy access to the largest s[0] and second-largest s[1], we
497
+ // keep the (p[i], s[i]) terms in a heap. Here, "heap" denotes a
498
+ // variant of the standard heap where the root node H[0] has one
499
+ // child H[1] (as opposed to two children), and every other node i>0
500
+ // has two children H[2*i] and H[2*i+1]. A heap comprises at least
501
+ // two elements H[0] and H[1]. In this way, the two largest scalars
502
+ // are always available directly.
503
+
504
+ // The following function is equivalent to assigning (p[i], s[i]) =
505
+ // (tp, ts) followed by restoring heap order. However, the logic is
506
+ // a bit complicated by our desire to avoid unnecessary copies of
507
+ // large objects (e.g., swap p[i] with a child, followed by another
508
+ // swap of the child with its child.)
509
+ //
510
+ // Warning: tp and ts MUST NOT be references to p[i] and s[i], since
511
+ // the algorithm overwrites the p and s arrays. This complication
512
+ // ensues because we are trying to avoid unnecessary copies.
513
+ void bury(size_t i, size_t n, ECPoint p[/*n*/], N s[/*n*/], const ECPoint& tp,
514
+ const N& ts) const {
515
+ while (2 * i < n) {
516
+ // at least one child
517
+ size_t cld = 2 * i;
518
+ if (2 * i + 1 < n && s[cld] < s[2 * i + 1]) {
519
+ // right child exists and is larger
520
+ cld = 2 * i + 1;
521
+ }
522
+
523
+ if (ts < s[cld]) {
524
+ // I is out of order with CLD. Bubble CLD up the tree and
525
+ // continue as in BURY(CLD, N, P, S, TP, TS).
526
+ s[i] = s[cld];
527
+ p[i] = p[cld];
528
+ i = cld;
529
+ } else {
530
+ // already in heap order, stop here.
531
+ break;
532
+ }
533
+ }
534
+
535
+ p[i] = tp;
536
+ s[i] = ts;
537
+ }
538
+
539
+ // bury (p[0], s[0]) to its rightful place in the heap.
540
+ void bury0(size_t n, ECPoint p[/*n*/], N s[/*n*/]) const {
541
+ if (s[0] < s[1]) {
542
+ // equivalent to swap(s[0], s[1]); bury(s[1]);
543
+ // but without the possibly unnecessary assignment of (s,p)[1]
544
+ ECPoint tp = p[0];
545
+ N ts = s[0];
546
+ p[0] = p[1];
547
+ s[0] = s[1];
548
+ bury(1, n, p, s, tp, ts);
549
+ }
550
+ }
551
+
552
+ // The main Bernstein/Bos-Coster algorithm.
553
+ ECPoint bos_coster(size_t n, ECPoint p[/*n*/], N s[/*n*/]) const {
554
+ check(n >= 2, "n >= 2");
555
+ ECPoint res = zero();
556
+
557
+ // build a heap on [1..n)
558
+ for (size_t i = /*floor*/ (n / 2); i >= 1; --i) {
559
+ // create temporary copies of p[i], s[i], which are passed by
560
+ // const &.
561
+ bury(i, n, p, s, ECPoint(p[i]), N(s[i]));
562
+ }
563
+ // finish the heap on [0..n)
564
+ bury0(n, p, s);
565
+
566
+ while (s[0] != /*zero*/ N{}) {
567
+ // ns0 = s[0] - s[1]
568
+ N ns0(s[0]);
569
+ ns0.sub(s[1]);
570
+
571
+ // Double-and-add is (locally) better than Bernstein iff s[0]/2
572
+ // < s[0] - s[1], equivalent to s[0] > 2*s[1], equivalent to
573
+ // ns0 = s[0] - s[1] > s[1]:
574
+ if (s[1] < ns0) {
575
+ // res += (s[0] & 1) * p[0]; s[0] /= 2; p[0] *= 2;
576
+ uint64_t lsb = s[0].shiftr(1);
577
+ if (lsb != 0) {
578
+ addE(res, p[0]);
579
+ }
580
+ doubleE(p[0]);
581
+ } else {
582
+ // s[0] -= s[1], p[1] += p[0]
583
+ s[0] = ns0;
584
+ addE(p[1], p[0]);
585
+ }
586
+ bury0(n, p, s);
587
+ }
588
+ return res;
589
+ }
590
+
591
+ bool is_zero_a_;
592
+ bool is_minus_3_a_;
593
+ };
594
+ } // namespace proofs
595
+
596
+ #endif // PRIVACY_PROOFS_ZK_LIB_EC_ELLIPTIC_CURVE_H_