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,371 @@
1
+ // Copyright 2026 Google LLC.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_ECDSA_VERIFY_CIRCUIT_H_
16
+ #define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_ECDSA_VERIFY_CIRCUIT_H_
17
+
18
+ #include <stddef.h>
19
+
20
+ #include "circuits/logic/bit_plucker.h"
21
+
22
+ namespace proofs {
23
+ // Verify ECDSA signature using triple scalar mult form.
24
+ //
25
+ // The field used by sumcheck is the base field of the elliptic curve.
26
+ // Compiled circuit: ecdsa verify
27
+ // d: 7 wires: 21099 in: 1038 out:764 use:13911 ovh:7188 t:42963 cse:11351
28
+ // notn:34724
29
+ //
30
+ template <class LogicCircuit, class Field, class EC>
31
+ class VerifyCircuit {
32
+ using EltW = typename LogicCircuit::EltW;
33
+ using BitW = typename LogicCircuit::BitW;
34
+ using Elt = typename LogicCircuit::Elt;
35
+ using Nat = typename Field::N;
36
+ static constexpr size_t kBits = EC::kBits;
37
+ using Bitvec = typename LogicCircuit::v256;
38
+
39
+ public:
40
+ struct Witness {
41
+ EltW rx, ry;
42
+ EltW pre[8];
43
+ EltW rx_inv, s_inv, pk_inv;
44
+ EltW bi[kBits];
45
+ EltW int_x[kBits - 1];
46
+ EltW int_y[kBits - 1];
47
+ EltW int_z[kBits - 1];
48
+
49
+ void input(const LogicCircuit& lc) {
50
+ rx = lc.eltw_input();
51
+ ry = lc.eltw_input();
52
+ rx_inv = lc.eltw_input();
53
+ s_inv = lc.eltw_input();
54
+ pk_inv = lc.eltw_input();
55
+ for (size_t i = 0; i < 8; ++i) {
56
+ pre[i] = lc.eltw_input();
57
+ }
58
+ for (size_t i = 0; i < kBits; ++i) {
59
+ bi[i] = lc.eltw_input();
60
+ if (i < kBits - 1) {
61
+ int_x[i] = lc.eltw_input();
62
+ int_y[i] = lc.eltw_input();
63
+ int_z[i] = lc.eltw_input();
64
+ }
65
+ }
66
+ }
67
+ };
68
+
69
+ VerifyCircuit(const LogicCircuit& lc, const EC& ec, const Nat& order)
70
+ : lc_(lc), ec_(ec), k2_(lc_.elt(2)), k3_(lc_.elt(3)) {
71
+ // Compute the bit representation of the order of the curve.
72
+ for (size_t i = 0; i < ec.kBits; ++i) {
73
+ bits_n_[i] = lc_.bit(order.bit(i));
74
+ }
75
+ }
76
+
77
+ // This verify takes the triple (pkx,pky,e) and checks that there exists
78
+ // (r=rx, ry, s) such that:
79
+ // identity = g*e + pk*r + (rx,ry)*-s
80
+ // It performs this check using a witness table that includes
81
+ // (g+pk, g+r, r+pk, g+r+pk), a correction element,
82
+ // bits of exponents (e, r, -s) s.t. each triple of bits is packed into {0,7},
83
+ // and intermediate ec points in (x,y,z) form. The bits are used to index the
84
+ // witness table in order to compute the right-hand side in a loop. The loop
85
+ // is sliced by providing the intermediate results in order reduce depth.
86
+ //
87
+ // An external constraint will need to ensure that e \neq 0 (e.g.,
88
+ // either the verifier checks this as part of the public input, or
89
+ // the hash that defines e is produced in the circuit). In our mdoc case,
90
+ // we use the later checks for both signatures.
91
+ //
92
+ // Other checks:
93
+ // r is interpreted as both in the base field and the scalar field.
94
+ // As a result, rx_inv is provided to ensure that r != 0.
95
+ // Similarly, s_inv is provided to ensure that s != 0.
96
+ //
97
+ // (rx,ry) is verified to be on the curve.
98
+ //
99
+ // (pkx, pky) \neq identity, because we set pk_z=1, we verify that
100
+ // pkx != 0, and we ensure that (pkx,pky) is on the curve.
101
+ //
102
+ void verify_signature3(EltW pk_x, EltW pk_y, EltW e, const Witness& w) const {
103
+ EltW zero = lc_.konst(lc_.zero());
104
+ EltW one = lc_.konst(lc_.one());
105
+ EltW gx = lc_.konst(ec_.gx_), gy = lc_.konst(ec_.gy_);
106
+
107
+ // indices for the pre[] table, don't change order
108
+ enum PreIndex {
109
+ GPK_X = 0,
110
+ GPK_Y,
111
+ GR_X,
112
+ GR_Y,
113
+ RPK_X,
114
+ RPK_Y,
115
+ GRPK_X,
116
+ GRPK_Y
117
+ };
118
+
119
+ // These variables hold the (e,r) exponents which are computed from the
120
+ // bits of advice (e,r,-s). They are compared with their expected values.
121
+ EltW est = zero, rst = zero, sst = zero;
122
+
123
+ // initialize at the 0 point, but these indices are reset on each loop
124
+ EltW ax = zero, ay = one, az = zero;
125
+
126
+ // =========
127
+ // Verify the values received in the table are correct.
128
+ // By verifying these values in parallel with using them, we can reduce
129
+ // the depth of the resulting circuit.
130
+ EltW cg_pkx, cg_pky, cg_pkz;
131
+ EltW cr_pkx, cr_pky, cr_pkz;
132
+ EltW cr_gx, cr_gy, cr_gz;
133
+ EltW cr_g_pkx, cr_g_pky, cr_g_pkz;
134
+ addE(cg_pkx, cg_pky, cg_pkz, gx, gy, one, pk_x, pk_y, one);
135
+ addE(cr_gx, cr_gy, cr_gz, w.rx, w.ry, one, gx, gy, one);
136
+ addE(cr_pkx, cr_pky, cr_pkz, w.rx, w.ry, one, pk_x, pk_y, one);
137
+ addE(cr_g_pkx, cr_g_pky, cr_g_pkz, gx, gy, one, w.pre[RPK_X], w.pre[RPK_Y],
138
+ one);
139
+ point_equality(cg_pkx, cg_pky, cg_pkz, w.pre[GPK_X], w.pre[GPK_Y]);
140
+ point_equality(cr_gx, cr_gy, cr_gz, w.pre[GR_X], w.pre[GR_Y]);
141
+ point_equality(cr_pkx, cr_pky, cr_pkz, w.pre[RPK_X], w.pre[RPK_Y]);
142
+ point_equality(cr_g_pkx, cr_g_pky, cr_g_pkz, w.pre[GRPK_X], w.pre[GRPK_Y]);
143
+
144
+ EltW arr_x[] = {zero, gx, pk_x, w.pre[GPK_X],
145
+ w.rx, w.pre[GR_X], w.pre[RPK_X], w.pre[GRPK_X]};
146
+ EltW arr_y[] = {one, gy, pk_y, w.pre[GPK_Y],
147
+ w.ry, w.pre[GR_Y], w.pre[RPK_Y], w.pre[GRPK_Y]};
148
+ EltW arr_z[] = {zero, one, one, one, one, one, one, one};
149
+ EltW arr_e[] = {zero, one, zero, one, zero, one, zero, one};
150
+ EltW arr_r[] = {zero, zero, one, one, zero, zero, one, one};
151
+ EltW arr_s[] = {zero, zero, zero, zero, one, one, one, one};
152
+
153
+ // To verify that the advice bit is in [0,7], we need to mux the point
154
+ // corresponding to the advice bit using degree 8 (9 points). We use the
155
+ // EltMuxer<LogicCircuit, 9, 8> to do this. See comments in EltMuxer.
156
+ EltW arr_v[] = {zero, zero, zero, zero, zero, zero, zero, zero, one};
157
+
158
+ EltMuxer<LogicCircuit, 8> xx(lc_, arr_x);
159
+ EltMuxer<LogicCircuit, 8> yy(lc_, arr_y);
160
+ EltMuxer<LogicCircuit, 8> zz(lc_, arr_z);
161
+ EltMuxer<LogicCircuit, 8> ee(lc_, arr_e);
162
+ EltMuxer<LogicCircuit, 8> rr(lc_, arr_r);
163
+ EltMuxer<LogicCircuit, 8> ss(lc_, arr_s);
164
+ EltMuxer<LogicCircuit, 9, 8> vv(lc_, arr_v);
165
+
166
+ Bitvec r_bits, s_bits;
167
+
168
+ // Traverses the bits of the scalar from high-order to low-order.
169
+ for (size_t i = 0; i < kBits; ++i) {
170
+ // Use the arr{X..V} arrays and the muxer to pick the correct point
171
+ // slice based on the bits of advice in the witness.
172
+ EltW tx = xx.mux(w.bi[i]);
173
+ EltW ty = yy.mux(w.bi[i]);
174
+ EltW tz = zz.mux(w.bi[i]);
175
+
176
+ // Update the exponent.
177
+ EltW e_bi = ee.mux(w.bi[i]);
178
+ EltW r_bi = rr.mux(w.bi[i]);
179
+ EltW s_bi = ss.mux(w.bi[i]);
180
+ auto k2 = lc_.konst(k2_);
181
+ est = lc_.add(e_bi, lc_.mul(k2, est));
182
+ rst = lc_.add(r_bi, lc_.mul(k2, rst));
183
+ sst = lc_.add(s_bi, lc_.mul(k2, sst));
184
+ r_bits[kBits - i - 1] = BitW(r_bi, ec_.f_);
185
+ s_bits[kBits - i - 1] = BitW(s_bi, ec_.f_);
186
+
187
+ // Verify that the advice bit is in [0,7].
188
+ EltW range = vv.mux(w.bi[i]);
189
+ lc_.assert0(range);
190
+
191
+ // Perform the basic add-dbl step in repeated squaring using the
192
+ // muxed point {tx, ty, tz}.
193
+ if (i > 0) {
194
+ doubleE(ax, ay, az, ax, ay, az);
195
+ }
196
+ addE(ax, ay, az, ax, ay, az, tx, ty, tz);
197
+
198
+ if (i < kBits - 1) {
199
+ // Ensure that the resulting point is equal to the intermediate
200
+ // point provided as input. Performing an explicit equality check
201
+ // ensures that all intermediate witness points are on the curve.
202
+ // This follows by induction. The first (ax,ay,az) is on the curve.
203
+ // The addition formula ensures that the i-th (ax,ay,az) is on the
204
+ // curve; equality ensures that the i-th witness is on the curve.
205
+ lc_.assert_eq(ax, w.int_x[i]);
206
+ lc_.assert_eq(ay, w.int_y[i]);
207
+ lc_.assert_eq(az, w.int_z[i]);
208
+
209
+ // Use the intermediate (x,y,z) point as the next input.
210
+ ax = w.int_x[i];
211
+ ay = w.int_y[i];
212
+ az = w.int_z[i];
213
+ }
214
+ }
215
+
216
+ // Check that the aX,aZ points are 0.
217
+ lc_.assert0(ax);
218
+ lc_.assert0(az);
219
+
220
+ // Check that the bits used for {e,rx} correspond to the input {e, rx}.
221
+ lc_.assert_eq(est, e);
222
+ lc_.assert_eq(rst, w.rx);
223
+
224
+ // Check that (pk,py), (rx,ry) satisfy the curve equation.
225
+ is_on_curve(pk_x, pk_y);
226
+ is_on_curve(w.rx, w.ry);
227
+
228
+ // Verify that exponents (r,s) are not zero.
229
+ // A witness is provided to ensure that both values have inverses in F.
230
+ // A bitwise comparison is done to ensure both are < |order| of EC.
231
+ assert_nonzero(w.rx, w.rx_inv);
232
+ assert_nonzero(sst, w.s_inv);
233
+ assert_nonzero(pk_x, w.pk_inv);
234
+ auto r_range = lc_.vlt(r_bits, bits_n_);
235
+ auto s_range = lc_.vlt(s_bits, bits_n_);
236
+ lc_.assert1(r_range);
237
+ lc_.assert1(s_range);
238
+ }
239
+
240
+ private:
241
+ void assert_nonzero(EltW x, EltW witness) const {
242
+ auto maybe_one = lc_.mul(x, witness);
243
+ auto one = lc_.konst(lc_.one());
244
+ lc_.assert_eq(maybe_one, one);
245
+ }
246
+
247
+ void point_equality(EltW x, EltW y, EltW z, EltW p_x, EltW p_y) const {
248
+ lc_.assert_eq(x, lc_.mul(z, p_x));
249
+ lc_.assert_eq(y, lc_.mul(z, p_y));
250
+ }
251
+
252
+ void is_on_curve(EltW x, EltW y) const {
253
+ // Check that y^2 = x^3 + ax + b
254
+ auto yy = lc_.mul(y, y);
255
+ auto xx = lc_.mul(x, x);
256
+ auto xxx = lc_.mul(x, xx);
257
+ auto ax = lc_.mul(ec_.a_, x);
258
+ auto b = lc_.konst(ec_.b_);
259
+ auto axb = lc_.add(ax, b);
260
+ auto rhs = lc_.add(axb, xxx);
261
+ lc_.assert_eq(yy, rhs);
262
+ }
263
+
264
+ void addE(EltW& X3, EltW& Y3, EltW& Z3, EltW X1, EltW Y1, EltW Z1, EltW X2,
265
+ EltW Y2, EltW Z2) const {
266
+ // The general case.
267
+ // Algorithm 1: Complete, projective point addition for arbitrary prime
268
+ // order short Weierstrass curves E/Fq : y^2 = x^3 + ax + b
269
+ // The compiler seems to optimize the cases when Z1,Z2=1.
270
+ EltW t0 = lc_.mul(X1, X2);
271
+ EltW t1 = lc_.mul(Y1, Y2);
272
+ EltW t2 = lc_.mul(Z1, Z2);
273
+ EltW t3 = lc_.add(X1, Y1);
274
+ EltW t4 = lc_.add(X2, Y2);
275
+ t3 = lc_.mul(t3, t4);
276
+ t4 = lc_.add(t0, t1);
277
+ t3 = lc_.sub(t3, t4);
278
+ t4 = lc_.add(X1, Z1);
279
+ EltW t5 = lc_.add(X2, Z2);
280
+ t4 = lc_.mul(t4, t5);
281
+ t5 = lc_.add(t0, t2);
282
+ t4 = lc_.sub(t4, t5);
283
+ t5 = lc_.add(Y1, Z1);
284
+ EltW X3t = lc_.add(Y2, Z2);
285
+ t5 = lc_.mul(t5, X3t);
286
+ X3t = lc_.add(t1, t2);
287
+ t5 = lc_.sub(t5, X3t);
288
+ auto a = lc_.konst(ec_.a_);
289
+ EltW Z3t = lc_.mul(a, t4);
290
+ auto k3b = lc_.konst(ec_.k3b);
291
+ X3t = lc_.mul(k3b, t2);
292
+ Z3t = lc_.add(X3t, Z3t);
293
+ X3t = lc_.sub(t1, Z3t);
294
+ Z3t = lc_.add(t1, Z3t);
295
+ EltW Y3t = lc_.mul(X3t, Z3t);
296
+ t1 = lc_.add(t0, t0);
297
+ t1 = lc_.add(t1, t0);
298
+ t2 = lc_.mul(a, t2);
299
+ t4 = lc_.mul(k3b, t4);
300
+ t1 = lc_.add(t1, t2);
301
+ t2 = lc_.sub(t0, t2);
302
+ t2 = lc_.mul(a, t2);
303
+ t4 = lc_.add(t4, t2);
304
+ t0 = lc_.mul(t1, t4);
305
+ Y3t = lc_.add(Y3t, t0);
306
+ t0 = lc_.mul(t5, t4);
307
+ X3t = lc_.mul(t3, X3t);
308
+ X3t = lc_.sub(X3t, t0);
309
+ t0 = lc_.mul(t3, t1);
310
+ Z3t = lc_.mul(t5, Z3t);
311
+ Z3t = lc_.add(Z3t, t0);
312
+
313
+ X3 = X3t;
314
+ Y3 = Y3t;
315
+ Z3 = Z3t;
316
+ }
317
+
318
+ void doubleE(EltW& X3, EltW& Y3, EltW& Z3, EltW X, EltW Y, EltW Z) const {
319
+ // The general case.
320
+ // Algorithm 3: Exception-free point doubling for arbitrary prime order
321
+ // short Weierstrass curves E/Fq : y^2 = x^3 + ax + b.
322
+ // The compiler will presumably optimize away 0 mults when a=0 and 1
323
+ // mults when Z = 1.
324
+ EltW t0 = lc_.mul(X, X);
325
+ EltW t1 = lc_.mul(Y, Y);
326
+ EltW t2 = lc_.mul(Z, Z);
327
+ EltW t3 = lc_.mul(X, Y);
328
+ t3 = lc_.add(t3, t3);
329
+ EltW Z3t = lc_.mul(X, Z);
330
+ Z3t = lc_.add(Z3t, Z3t);
331
+ auto a = lc_.konst(ec_.a_);
332
+ auto k3b = lc_.konst(ec_.k3b);
333
+ EltW X3t = lc_.mul(a, Z3t);
334
+ EltW Y3t = lc_.mul(k3b, t2);
335
+ Y3t = lc_.add(X3t, Y3t);
336
+ X3t = lc_.sub(t1, Y3t);
337
+ Y3t = lc_.add(t1, Y3t);
338
+ Y3t = lc_.mul(X3t, Y3t);
339
+ X3t = lc_.mul(t3, X3t);
340
+ Z3t = lc_.mul(k3b, Z3t);
341
+ t2 = lc_.mul(a, t2);
342
+ t3 = lc_.sub(t0, t2);
343
+ t3 = lc_.mul(a, t3);
344
+ t3 = lc_.add(t3, Z3t);
345
+ Z3t = lc_.add(t0, t0);
346
+ t0 = lc_.add(Z3t, t0);
347
+ t0 = lc_.add(t0, t2);
348
+ t0 = lc_.mul(t0, t3);
349
+ Y3t = lc_.add(Y3t, t0);
350
+ t2 = lc_.mul(Y, Z);
351
+ t2 = lc_.add(t2, t2);
352
+ t0 = lc_.mul(t2, t3);
353
+ X3t = lc_.sub(X3t, t0);
354
+ Z3t = lc_.mul(t2, t1);
355
+ Z3t = lc_.add(Z3t, Z3t);
356
+ Z3t = lc_.add(Z3t, Z3t);
357
+
358
+ X3 = X3t;
359
+ Y3 = Y3t;
360
+ Z3 = Z3t;
361
+ }
362
+
363
+ const LogicCircuit& lc_;
364
+ const EC& ec_;
365
+
366
+ Elt k2_, k3_;
367
+ Bitvec bits_n_;
368
+ };
369
+ } // namespace proofs
370
+
371
+ #endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_ECDSA_VERIFY_CIRCUIT_H_
@@ -0,0 +1,246 @@
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 <cctype>
16
+ #include <cstddef>
17
+ #include <cstdint>
18
+ #include <cstdio>
19
+ #include <cstring>
20
+
21
+ // This test is meant to run once for 10^k repetitions to "fuzz" for any
22
+ // possible error in completeness or soundness for our ecdsa verification
23
+ // circuit. The test works by generating a random key, message, and signature
24
+ // using openssl, and then verifying the signature using our circuit. Next, we
25
+ // maul the signature by twiddling a single hex digit in the original 5-tuple,
26
+ // and ensure that the resulting signature fails. Allthough this only checks
27
+ // that single edit distance changes cause failures, it is a basic test.
28
+ //
29
+ // $ blaze-bin/ecdsa/verify_external_test \
30
+ // --gunit_repeat 10000
31
+
32
+ #include "circuits/ecdsa/verify_circuit.h"
33
+ #include "circuits/ecdsa/verify_witness.h"
34
+ #include "circuits/logic/evaluation_backend.h"
35
+ #include "circuits/logic/logic.h"
36
+ #include "ec/p256.h"
37
+ #include "util/log.h"
38
+ #include "gtest/gtest.h"
39
+ #include "openssl/evp.h"
40
+ #include "openssl/bn.h"
41
+ #include "openssl/ec.h"
42
+
43
+ #include "openssl/ecdsa.h"
44
+
45
+
46
+ #include "openssl/rand.h"
47
+
48
+ namespace proofs {
49
+ namespace {
50
+
51
+ // This test is specific to P256 via the external openssl dependencies.
52
+ // Therefore the types are globally defined for convenience.
53
+ using Field = Fp256Base;
54
+ using Nat = Field::N;
55
+ using Elt = Field::Elt;
56
+ using EvalBackend = EvaluationBackend<Field>;
57
+ using Logic = Logic<Field, EvalBackend>;
58
+ using Verc = VerifyCircuit<Logic, Field, P256>;
59
+ using Verw = VerifyWitness3<P256, Fp256Scalar>;
60
+
61
+ struct signature_tuple {
62
+ char pkx[67];
63
+ char pky[67];
64
+ char e[67];
65
+ char r[67];
66
+ char s[67];
67
+ };
68
+
69
+ struct circuit_params {
70
+ Elt pkx, pky, e;
71
+ typename Verc::Witness vwc;
72
+ };
73
+
74
+ class ecdsa_params {
75
+ public:
76
+ EC_KEY* eckey_;
77
+ EC_GROUP* group_;
78
+
79
+ ecdsa_params() : eckey_(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)),
80
+ group_(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) { }
81
+
82
+ ~ecdsa_params() {
83
+ EC_KEY_free(eckey_);
84
+ EC_GROUP_free(group_);
85
+ }
86
+ };
87
+
88
+ // Generates a random key (pkx,pky) and a signature (r,s) on a random message e
89
+ // using the openssl ECDSA implementation. These values are written as
90
+ // null-terminated strings in hex format to the buffers passed in. The caller
91
+ // must ensure that the buffers are at least 67 bytes long.
92
+ // The goal is to produce an externally verified testing tuple for our own
93
+ // implementation.
94
+ bool gensig(signature_tuple& st, const ecdsa_params& params) {
95
+ if (!EC_KEY_generate_key(params.eckey_)) {
96
+ return false;
97
+ }
98
+
99
+ // Random message
100
+ unsigned char hash[32];
101
+ RAND_bytes(hash, sizeof(hash));
102
+
103
+ ECDSA_SIG* sig = ECDSA_do_sign(hash, sizeof(hash), params.eckey_);
104
+ if (!sig) {
105
+ return false;
106
+ }
107
+
108
+ // Get the signature components (r and s)
109
+ const BIGNUM* br = ECDSA_SIG_get0_r(sig);
110
+ const BIGNUM* bs = ECDSA_SIG_get0_s(sig);
111
+ char* r_hex = BN_bn2hex(br);
112
+ char* s_hex = BN_bn2hex(bs);
113
+
114
+ // Get the public key
115
+ const EC_POINT* pub_key = EC_KEY_get0_public_key(params.eckey_);
116
+ uint8_t buf[200];
117
+ EC_POINT_point2oct(params.group_, pub_key, POINT_CONVERSION_UNCOMPRESSED, buf,
118
+ sizeof(buf), nullptr);
119
+
120
+ // Easiest interface to our circuit library is via hex-formatted strings.
121
+ // NOLINTBEGIN(runtime/printf)
122
+ snprintf(st.pkx, 3, "0x");
123
+ snprintf(st.pky, 3, "0x");
124
+ snprintf(st.e, 3, "0x");
125
+ for (size_t i = 0; i < 32; ++i) {
126
+ snprintf(&st.pkx[2 + i * 2], 3, "%02x", buf[i + 1]);
127
+ snprintf(&st.pky[2 + i * 2], 3, "%02x", buf[i + 33]);
128
+ snprintf(&st.e[2 + i * 2], 3, "%02x", hash[i]);
129
+ }
130
+ // NOLINTEND(runtime/printf)
131
+
132
+ snprintf(st.r, sizeof(st.r), "0x%.64s", r_hex);
133
+ snprintf(st.s, sizeof(st.s), "0x%.64s", s_hex);
134
+
135
+ // Clean up
136
+ ECDSA_SIG_free(sig);
137
+ OPENSSL_free(r_hex);
138
+ OPENSSL_free(s_hex);
139
+
140
+ return true;
141
+ }
142
+
143
+ char twiddle(char in) {
144
+ char d[] = "0123456789abcdef";
145
+ static size_t cnt = 5;
146
+ while (tolower(in) == d[cnt]) {
147
+ cnt = (cnt + 1) % 16;
148
+ }
149
+ return d[cnt];
150
+ }
151
+
152
+ void maulSignature(const signature_tuple& in, signature_tuple& out) {
153
+ out = in;
154
+
155
+ // Pick a (biased) random spot to twiddle.
156
+ uint8_t pos[2];
157
+ RAND_bytes(pos, 2);
158
+ char* fields[] = {out.r, out.s, out.e, out.pkx, out.pky};
159
+ size_t fi = pos[0] % 5;
160
+ size_t ind = (pos[1] % 62) + 2;
161
+ fields[fi][ind] = twiddle(fields[fi][ind]);
162
+ }
163
+
164
+ void prepare_witness(const signature_tuple& st, circuit_params& in,
165
+ const Logic& l, const Field& F) {
166
+ Verw vw(p256_scalar, p256);
167
+
168
+ in.pkx = F.of_string(st.pkx);
169
+ in.pky = F.of_string(st.pky);
170
+ Nat e = Nat(st.e);
171
+ Nat r = Nat(st.r);
172
+ Nat s = Nat(st.s);
173
+ in.e = F.to_montgomery(e);
174
+
175
+ vw.compute_witness(in.pkx, in.pky, e, r, s);
176
+
177
+ in.vwc.rx = l.konst(vw.rx_);
178
+ in.vwc.ry = l.konst(vw.ry_);
179
+ in.vwc.rx_inv = l.konst(vw.rx_inv_);
180
+ in.vwc.s_inv = l.konst(vw.s_inv_);
181
+ in.vwc.pk_inv = l.konst(vw.pk_inv_);
182
+ for (size_t j = 0; j < 8; ++j) {
183
+ in.vwc.pre[j] = l.konst(vw.pre_[j]);
184
+ }
185
+ for (size_t j = 0; j < p256.kBits; j++) {
186
+ in.vwc.bi[j] = l.konst(vw.bi_[j]);
187
+ if (j < p256.kBits - 1) {
188
+ in.vwc.int_x[j] = l.konst(vw.int_x_[j]);
189
+ in.vwc.int_y[j] = l.konst(vw.int_y_[j]);
190
+ in.vwc.int_z[j] = l.konst(vw.int_z_[j]);
191
+ }
192
+ }
193
+ }
194
+
195
+ // This test verifies our ecdsa signature verification circuit against an
196
+ // external implementation over randomly generated keys and messages.
197
+ TEST(ECDSA, VerifyExternalP256) {
198
+ const Nat order =
199
+ Nat("0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551");
200
+
201
+ const Field& F = p256.f_;
202
+ const EvalBackend ebk(F, false);
203
+ const Logic l(&ebk, F);
204
+
205
+ Verc verc(l, p256, order);
206
+
207
+ ecdsa_params params;
208
+
209
+ for (size_t i = 0; i < 100; ++i) {
210
+ if (i % 10 == 0) {
211
+ log(INFO, "Iteration %zu", i);
212
+ }
213
+ signature_tuple st;
214
+ circuit_params in;
215
+ bool ok = gensig(st, params);
216
+ EXPECT_TRUE(ok);
217
+
218
+ prepare_witness(st, in, l, F);
219
+
220
+ verc.verify_signature3(l.konst(in.pkx), l.konst(in.pky), l.konst(in.e),
221
+ in.vwc);
222
+
223
+ bool failed = ebk.assertion_failed();
224
+ if (failed) {
225
+ log(ERROR,
226
+ "Failed verification on:\npkx:%s\npky:%s\n e:%s\n r:%s\n s:%s",
227
+ st.pkx, st.pky, st.e, st.r, st.s);
228
+ }
229
+ EXPECT_FALSE(failed);
230
+
231
+ // Modify one byte of the signature and ensure that it fails.
232
+ signature_tuple maul_st;
233
+ circuit_params maul_in;
234
+ for (size_t j = 0; j < 100; ++j) {
235
+ maulSignature(st, maul_st);
236
+ prepare_witness(maul_st, maul_in, l, F);
237
+ verc.verify_signature3(l.konst(maul_in.pkx), l.konst(maul_in.pky),
238
+ l.konst(maul_in.e), maul_in.vwc);
239
+ failed = ebk.assertion_failed();
240
+ EXPECT_TRUE(failed);
241
+ }
242
+ }
243
+ }
244
+
245
+ } // namespace
246
+ } // namespace proofs