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,693 @@
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 "circuits/mdoc/mdoc_zk.h"
16
+
17
+ #include <stdint.h>
18
+ #include <sys/types.h>
19
+
20
+ #include <cstddef>
21
+ #include <cstdlib>
22
+ #include <cstring>
23
+ #include <memory>
24
+ #include <vector>
25
+
26
+ #include "algebra/convolution.h"
27
+ #include "algebra/fp2.h"
28
+ #include "algebra/reed_solomon.h"
29
+ #include "arrays/dense.h"
30
+ #include "cbor/host_decoder.h"
31
+ #include "circuits/mac/mac_reference.h"
32
+ #include "circuits/mac/mac_witness.h"
33
+ #include "circuits/mdoc/mdoc_decompress.h"
34
+ #include "circuits/mdoc/mdoc_witness.h"
35
+ #include "ec/p256.h"
36
+ #include "gf2k/gf2_128.h"
37
+ #include "gf2k/lch14_reed_solomon.h"
38
+ #include "proto/circuit.h"
39
+ #include "random/secure_random_engine.h"
40
+ #include "random/transcript.h"
41
+ #include "sumcheck/circuit.h"
42
+ #include "util/log.h"
43
+ #include "util/panic.h"
44
+ #include "util/readbuffer.h"
45
+ #include "zk/zk_proof.h"
46
+ #include "zk/zk_prover.h"
47
+ #include "zk/zk_verifier.h"
48
+ #include "zstd.h"
49
+
50
+ // The result of getHashMacIndex is derived from the circuit layout.
51
+ // It represents the location of the hash MAC wire in the hash verification
52
+ // circuit and must be updated if the public interface of the hash circuit is
53
+ // changed.
54
+ // This index is part of the public input, but it is needed so that the prover
55
+ // can commit the rest of the witness (including its portion of the MAC key),
56
+ // the verifier can then select its a_v half of the mac key, the prover can
57
+ // then compute the MAC and finally place it into the correct part of the
58
+ // dense witness array.
59
+ // ex: numAttrs = 1, this function returns (1*768 + 8) + 161
60
+ size_t getHashMacIndex(size_t numAttrs, size_t version) {
61
+ // The length of the attribute field that is added in version 4.
62
+ return numAttrs * 8 * (96 + (version < 7 ? 1 : 2)) + 160 + 1;
63
+ }
64
+
65
+ namespace proofs {
66
+
67
+ // ======= Global typedefs for convenience ==========
68
+ // P256-related types
69
+ using N = Fp256Base::N;
70
+ using Scalar = Fp256Base::Elt;
71
+ using Elt = Fp256Base::Elt;
72
+ using f2_p256 = Fp2<Fp256Base>;
73
+ using Elt2 = f2_p256::Elt;
74
+ using FftExtConvolutionFactory = FFTExtConvolutionFactory<Fp256Base, f2_p256>;
75
+ using RSFactory_b = ReedSolomonFactory<Fp256Base, FftExtConvolutionFactory>;
76
+ using f_128 = GF2_128<>;
77
+ using gf2k = f_128::Elt;
78
+
79
+ using RSFactory = LCH14ReedSolomonFactory<f_128>;
80
+
81
+ // Root of unity for the f_p256^2 extension field.
82
+ static constexpr char kRootX[] =
83
+ "112649224146410281873500457609690258373018840430489408729223714171582664"
84
+ "680802";
85
+ static constexpr char kRootY[] =
86
+ "84087994358540907695740461427818660560182168997182378749313018254450460212"
87
+ "908";
88
+
89
+ // Magic constant 4 is derived from the circuit layout.
90
+ // It represents the location of the signature MAC wire in the signature
91
+ // verification circuit and must be updated if the public interface of the sig
92
+ // circuit is changed. This index is part of the public input, but it is needed
93
+ // so that the prover can commit the rest of the witness (including its portion
94
+ // of the MAC key), the verifier can then select its a_v half of the mac key,
95
+ // the prover can then compute the MAC and finally place it into the correct
96
+ // part of the dense witness array.
97
+ static constexpr size_t kSigMacIndex = 4;
98
+
99
+ // Flags that indicate whether the prover and/or verifier ought
100
+ // to check the circuit id stored in the circuit itself.
101
+ //
102
+ // In this particular application the ID's of the individual circuits
103
+ // are trusted, and we don't want to incur the performance cost
104
+ // of verifying the ID for every proof or verification.
105
+ //
106
+ // The larger application is expected to contain a hardcoded
107
+ // list of supported circuit IDs. After downloading the circuit
108
+ // (or compiling it locally) the application is expected to
109
+ // check the ID once, and then store the checked circuit in
110
+ // trusted local storage.
111
+ static constexpr bool enforce_circuit_id_in_prover = false;
112
+ static constexpr bool enforce_circuit_id_in_verifier = false;
113
+
114
+ // =========== Helper methods for the main exported C functions.
115
+
116
+ // Specialization for filling the mac when using f_128.
117
+ template <>
118
+ void fill_gf2k<f_128, f_128>(const typename f_128::Elt& m,
119
+ DenseFiller<f_128>& df, const f_128& f) {
120
+ df.push_back(m);
121
+ }
122
+
123
+ void compute_macs(size_t len, const Elt x[], gf2k gmacs[/* 6 */],
124
+ uint8_t macs[/* 2.len.gf2k_size */],
125
+ const gf2k ap[/* 2.len */], gf2k av) {
126
+ // This code relies on the assumption that an Elt can be mac'ed in 2
127
+ // gf2k elements.
128
+ check(f_128::kBits * 2 >= Fp256Base::kBits, "Mac is not large enough");
129
+ f_128 gf;
130
+ MACReference<f_128> mac_ref;
131
+ uint8_t buf[Fp256Base::kBytes];
132
+
133
+ for (size_t i = 0; i < len; ++i) {
134
+ p256_base.to_bytes_field(buf, x[i]);
135
+ mac_ref.compute(&gmacs[2 * i], av, &ap[i * 2], buf);
136
+ gf.to_bytes_field(&macs[2 * i * f_128::kBytes], gmacs[2 * i]);
137
+ gf.to_bytes_field(&macs[(2 * i + 1) * f_128::kBytes], gmacs[2 * i + 1]);
138
+ }
139
+ }
140
+
141
+ struct ProverState {
142
+ Elt common[3]; // e2, dpkx, dpky
143
+ gf2k ap[6]; // mac keys for the above
144
+ using mac_witness = MacGF2Witness;
145
+ mac_witness macs[3];
146
+ };
147
+
148
+ // Fills the hash witness with the attributes and the time input.
149
+ MdocProverErrorCode fill_attributes(DenseFiller<f_128>& hash_filler,
150
+ const RequestedAttribute* attrs,
151
+ size_t attrs_len, const uint8_t* now,
152
+ const f_128& Fs, size_t version) {
153
+ hash_filler.push_back(Fs.one());
154
+ for (size_t ai = 0; ai < attrs_len; ++ai) {
155
+ MdocProverErrorCode err =
156
+ fill_attribute(hash_filler, attrs[ai], Fs, version);
157
+ if (err != MDOC_PROVER_SUCCESS) {
158
+ return err;
159
+ }
160
+ }
161
+ fill_bit_string(hash_filler, now, 20, 20, Fs);
162
+ return MDOC_PROVER_SUCCESS;
163
+ }
164
+
165
+ // Fills the signature witness with the public inputs pkX, pkY, and e.
166
+ void fill_signature_inputs(DenseFiller<Fp256Base>& sig_filler, const Elt& pkX,
167
+ const Elt& pkY, const Elt& e) {
168
+ sig_filler.push_back(p256_base.one());
169
+ sig_filler.push_back(pkX);
170
+ sig_filler.push_back(pkY);
171
+ sig_filler.push_back(e);
172
+ }
173
+
174
+ // Fills the public inputs for the hash and signature circuits.
175
+ // Empty values for the MAC inputs and AV are used.
176
+ bool fill_public_inputs(DenseFiller<Fp256Base>& sig_filler,
177
+ DenseFiller<f_128>& hash_filler, const Elt& pkX,
178
+ const Elt& pkY, const uint8_t* tr, size_t tr_len,
179
+ const RequestedAttribute* attrs, size_t attrs_len,
180
+ const uint8_t* now, const uint8_t* docType,
181
+ size_t dt_len, const gf2k macs[], gf2k av,
182
+ const f_128& Fs, size_t version) {
183
+ if (fill_attributes(hash_filler, attrs, attrs_len, now, Fs, version) !=
184
+ MDOC_PROVER_SUCCESS) {
185
+ return false;
186
+ }
187
+
188
+ for (size_t i = 0; i < 6; ++i) { /* 6 mac + 1 av */
189
+ fill_gf2k<f_128, f_128>(macs[i], hash_filler, Fs);
190
+ }
191
+ fill_gf2k<f_128, f_128>(av, hash_filler, Fs);
192
+
193
+ std::vector<uint8_t> docTypeBytes(docType, docType + dt_len);
194
+
195
+ // The verify_ecdsa circuit requires that e2 != 0. We consider the pr that the
196
+ // adversary produces a SHA-256 preimage of 0 to be negligible. Thus, we
197
+ // satisfy the pre-condition here by directly computing the transcript hash
198
+ // and assume it is not 0.
199
+ Elt e2 = p256_base.to_montgomery(
200
+ compute_transcript_hash<N>(tr, tr_len, &docTypeBytes));
201
+ fill_signature_inputs(sig_filler, pkX, pkY, e2);
202
+
203
+ for (size_t i = 0; i < 6; ++i) {
204
+ fill_gf2k<f_128, Fp256Base>(macs[i], sig_filler, p256_base);
205
+ }
206
+ fill_gf2k<f_128, Fp256Base>(av, sig_filler, p256_base);
207
+ return true;
208
+ }
209
+
210
+ // Fills the hash and signature public inputs and private witnesses.
211
+ MdocProverErrorCode fill_witness(
212
+ DenseFiller<Fp256Base>& fill_b, DenseFiller<f_128>& fill_s,
213
+ const uint8_t* mdoc, size_t mdoc_len, const Elt& pkX, const Elt& pkY,
214
+ const uint8_t* tr, size_t tr_len, const RequestedAttribute* attrs,
215
+ size_t attrs_len, const uint8_t* now, ProverState& state,
216
+ SecureRandomEngine& rng, const f_128& Fs, size_t version) {
217
+ using MdocHW = MdocHashWitness<P256, f_128>;
218
+ using MdocSW = MdocSignatureWitness<P256, Fp256Scalar>;
219
+
220
+ // Allocate these objects on the heap because Android has a small stack.
221
+ auto hw = std::make_unique<MdocHW>(attrs_len, p256, Fs);
222
+ auto sw = std::make_unique<MdocSW>(p256, p256_scalar, Fs);
223
+
224
+ // hash public inputs
225
+ MdocProverErrorCode err =
226
+ fill_attributes(fill_s, attrs, attrs_len, now, Fs, version);
227
+ if (err != MDOC_PROVER_SUCCESS) {
228
+ return err;
229
+ }
230
+
231
+ // init mac+av to 0
232
+ for (size_t i = 0; i < 6 + 1; ++i) { /* 6 mac + 1 av */
233
+ fill_gf2k<f_128, f_128>(Fs.zero(), fill_s, Fs);
234
+ }
235
+
236
+ MdocProverErrorCode ok_h = hw->compute_witness(mdoc, mdoc_len, tr, tr_len,
237
+ attrs, attrs_len, version);
238
+ if (ok_h != MDOC_PROVER_SUCCESS) return ok_h;
239
+
240
+ MdocProverErrorCode ok_s =
241
+ sw->compute_witness(pkX, pkY, mdoc, mdoc_len, tr, tr_len);
242
+ if (ok_s != MDOC_PROVER_SUCCESS) return ok_s;
243
+
244
+ // signature public inputs
245
+ fill_signature_inputs(fill_b, pkX, pkY, sw->e2_);
246
+ for (size_t i = 0; i < 7; ++i) {
247
+ fill_gf2k<f_128, Fp256Base>(Fs.zero(), fill_b, p256_base);
248
+ }
249
+
250
+ // compute macs
251
+ state = {.common = {hw->e_, hw->dpkx_, hw->dpky_}};
252
+ MACReference<f_128> mac_ref;
253
+ mac_ref.sample(state.ap, 6, &rng);
254
+
255
+ uint8_t buf[Fp256Base::kBytes];
256
+
257
+ Fp256Base::Elt tt[3] = {hw->e_, hw->dpkx_, hw->dpky_};
258
+ for (size_t i = 0; i < 3; ++i) {
259
+ p256_base.to_bytes_field(buf, tt[i]);
260
+ sw->macs_[i].compute_witness(&state.ap[2 * i], buf);
261
+ state.macs[i].compute_witness(&state.ap[2 * i]);
262
+ fill_bit_string(fill_s, buf, 32, 32, Fs);
263
+ }
264
+
265
+ // private witnesses
266
+ hw->fill_witness(fill_s, version);
267
+ for (auto& mac : state.macs) {
268
+ mac.fill_witness(fill_s);
269
+ }
270
+
271
+ sw->fill_witness(fill_b);
272
+
273
+ return MDOC_PROVER_SUCCESS;
274
+ }
275
+
276
+ gf2k generate_mac_key(Transcript& t) {
277
+ f_128 gf;
278
+ uint8_t buf[f_128::kBytes];
279
+ t.bytes(buf, f_128::kBytes);
280
+ return gf.of_bytes_field(buf).value();
281
+ }
282
+
283
+ // Updates the dense input array with a mac.The location
284
+ // of the start of the macs+av inputs must be passed in as (si, hi).
285
+ void update_mac_in_dense(Dense<Fp256Base>& W_sig, Dense<f_128>& W_hash,
286
+ size_t& si, size_t& hi, const gf2k mac,
287
+ const f_128& Fs) {
288
+ for (size_t j = 0; j < f_128::kBits; ++j) {
289
+ W_sig.v_[si++] = mac[j] ? p256_base.one() : p256_base.zero();
290
+ }
291
+ W_hash.v_[hi++] = mac;
292
+ }
293
+
294
+ // Updates all macs in both dense arrays. The (si,hi) should be the index
295
+ // of the first mac in the respective dense arrays.
296
+ void update_macs(Dense<Fp256Base>& W_sig, Dense<f_128>& W_hash, size_t si,
297
+ size_t hi, const gf2k macs[], gf2k av, const f_128& Fs) {
298
+ for (size_t mi = 0; mi < 6; ++mi) {
299
+ update_mac_in_dense(W_sig, W_hash, si, hi, macs[mi], Fs);
300
+ }
301
+ update_mac_in_dense(W_sig, W_hash, si, hi, av, Fs);
302
+ }
303
+
304
+ bool parsePk(const char* pkx, const char* pky, Elt& pkX, Elt& pkY) {
305
+ auto maybe_x = p256_base.of_untrusted_string(pkx);
306
+ auto maybe_y = p256_base.of_untrusted_string(pky);
307
+ if (!maybe_x.has_value() || !maybe_y.has_value()) {
308
+ return false;
309
+ }
310
+ pkX = maybe_x.value();
311
+ pkY = maybe_y.value();
312
+ return true;
313
+ }
314
+
315
+ bool sameNamespace(const RequestedAttribute attrs[/*n*/], size_t n) {
316
+ for (size_t i = 1; i < n; ++i) {
317
+ if (attrs[i].namespace_len != attrs[0].namespace_len ||
318
+ memcmp(attrs[i].namespace_id, attrs[0].namespace_id,
319
+ attrs[0].namespace_len) != 0) {
320
+ return false;
321
+ }
322
+ }
323
+ return true;
324
+ }
325
+
326
+ // Validates that the input is a valid CBOR encoding of one of the following:
327
+ // - String (TEXT)
328
+ // - Boolean (PRIMITIVE TRUE/FALSE)
329
+ // - Integer (UNSIGNED/NEGATIVE)
330
+ // - Binary String (BYTES)
331
+ // - Fulldate (TAG 1004) -> must be 14 bytes total
332
+ // - Tdate (TAG 0) -> must be 22 bytes total
333
+ bool cbor_validate(const uint8_t* in, size_t len) {
334
+ uint8_t dummy[1]; // For 0-length checks if needed, though len > 0 usually
335
+ const uint8_t* buf = in ? in : dummy;
336
+ size_t pos = 0;
337
+ CborDoc doc;
338
+
339
+ if (!doc.decode(buf, len, pos, 0)) {
340
+ return false;
341
+ }
342
+
343
+ // Ensure we consumed the entire buffer
344
+ if (pos != len) {
345
+ return false;
346
+ }
347
+
348
+ switch (doc.t_) {
349
+ case TEXT:
350
+ case BYTES:
351
+ case UNSIGNED:
352
+ case NEGATIVE:
353
+ return true;
354
+
355
+ case PRIMITIVE:
356
+ return (doc.u_.p == CTRUE || doc.u_.p == CFALSE);
357
+
358
+ case TAG: {
359
+ // items.n is the tag value
360
+ size_t tag = doc.u_.items.n;
361
+ if (tag == 1004) { // Fulldate
362
+ if (len != 14) return false;
363
+ // Check inner type is TEXT? CborDoc handles valid children decode.
364
+ // host_decoder.h: case 6 (TAG) ... decode_items ...
365
+ // We know it has 1 child.
366
+ if (doc.children_.empty() || doc.children_[0].t_ != TEXT) return false;
367
+ return true;
368
+ }
369
+ if (tag == 0) { // Tdate
370
+ if (len != 22) return false;
371
+ if (doc.children_.empty() || doc.children_[0].t_ != TEXT) return false;
372
+ return true;
373
+ }
374
+ return false;
375
+ }
376
+
377
+ default:
378
+ return false;
379
+ }
380
+ }
381
+
382
+ // =========== End of helper functions =====================
383
+ extern "C" {
384
+ /*
385
+ API version that uses 2 circuits over different fields.
386
+ */
387
+ using MdocSWw = MdocSignatureWitness<P256, Fp256Scalar>;
388
+
389
+ // Main endpoint for producing a ZK proof for mdoc properties.
390
+ // This implementation uses 2 separate circuits over 2 fields to verify
391
+ // the signature and the hash components of the mdoc.
392
+ // It is the caller's job to free the memory pointed to by prf.
393
+ MdocProverErrorCode run_mdoc_prover(
394
+ const uint8_t* bcp, size_t bcsz, /* circuit data */
395
+ const uint8_t* mdoc, size_t mdoc_len, const char* pkx,
396
+ const char* pky, /* string rep of public key */
397
+ const uint8_t* transcript, size_t tr_len, /* session transcript */
398
+ const RequestedAttribute* attrs, size_t attrs_len,
399
+ const char* now, /* time formatted as "2023-11-02T09:00:00Z" */
400
+ uint8_t** prf, size_t* proof_len, const ZkSpecStruct* zk_spec) {
401
+ if (bcp == nullptr || mdoc == nullptr || pkx == nullptr || pky == nullptr ||
402
+ transcript == nullptr || attrs == nullptr || now == nullptr ||
403
+ prf == nullptr || proof_len == nullptr || zk_spec == nullptr) {
404
+ return MDOC_PROVER_NULL_INPUT;
405
+ }
406
+
407
+ Elt pkX, pkY;
408
+ if (!parsePk(pkx, pky, pkX, pkY)) {
409
+ log(ERROR, "invalid pkx, pky");
410
+ return MDOC_PROVER_INVALID_INPUT;
411
+ }
412
+
413
+ if (!sameNamespace(attrs, attrs_len)) {
414
+ log(ERROR, "attributes must all be in the same namespace");
415
+ return MDOC_PROVER_INVALID_INPUT;
416
+ }
417
+
418
+ // Parse circuits from cached byte representation.
419
+ const f2_p256 p256_2(p256_base);
420
+ const f_128 Fs;
421
+
422
+ std::unique_ptr<Circuit<Fp256Base>> c_sig = nullptr;
423
+ std::unique_ptr<Circuit<f_128>> c_hash = nullptr;
424
+ /* scope for the bytes array */ {
425
+ size_t len = kCircuitSizeMax;
426
+ std::vector<uint8_t> bytes(len);
427
+ size_t full_size = decompress(bytes, bcp, bcsz);
428
+
429
+ if (full_size == 0) {
430
+ return MDOC_PROVER_CIRCUIT_PARSING_FAILURE;
431
+ }
432
+
433
+ log(INFO, "bytes len: %zu", full_size);
434
+ ReadBuffer rb_circuit(bytes.data(), full_size);
435
+
436
+ CircuitRep<Fp256Base> cr_s(p256_base, P256_ID);
437
+ c_sig = cr_s.from_bytes(rb_circuit, enforce_circuit_id_in_prover);
438
+ if (c_sig == nullptr) {
439
+ log(ERROR, "signature circuit could not be parsed");
440
+ return MDOC_PROVER_CIRCUIT_PARSING_FAILURE;
441
+ }
442
+ CircuitRep<f_128> cr_h(Fs, GF2_128_ID);
443
+ c_hash = cr_h.from_bytes(rb_circuit, enforce_circuit_id_in_prover);
444
+
445
+ if (c_hash == nullptr) {
446
+ log(ERROR, "hash circuit could not be parsed");
447
+ return MDOC_PROVER_HASH_PARSING_FAILURE;
448
+ }
449
+ log(INFO, "circuit created. h[in:%zu q:%zu], s[in:%zu q:%zu]",
450
+ c_hash->ninputs, c_hash->nl, c_sig->ninputs, c_sig->nl);
451
+ }
452
+
453
+ // ============ Produce zk witness ==============
454
+ auto W_sig = Dense<Fp256Base>(1, c_sig->ninputs);
455
+ auto W_hash = Dense<f_128>(1, c_hash->ninputs);
456
+ DenseFiller<Fp256Base> sig_filler(W_sig);
457
+ DenseFiller<f_128> hash_filler(W_hash);
458
+
459
+ SecureRandomEngine rng;
460
+ ProverState state;
461
+ MdocProverErrorCode ok = fill_witness(
462
+ sig_filler, hash_filler, mdoc, mdoc_len, pkX, pkY, transcript, tr_len,
463
+ attrs, attrs_len, (const uint8_t*)now, state, rng, Fs, zk_spec->version);
464
+ if (ok != MDOC_PROVER_SUCCESS) {
465
+ log(ERROR, "fill_witness failed");
466
+ return ok;
467
+ }
468
+
469
+ // ========= Run prover ==============
470
+ // Use the transcript from the session to select the random oracle.
471
+ Transcript tp(transcript, tr_len, zk_spec->version);
472
+
473
+ const Elt2 omega = p256_2.of_string(kRootX, kRootY);
474
+ const FftExtConvolutionFactory fft_b(p256_base, p256_2, omega, 1ull << 31);
475
+ const RSFactory_b rsf_b(fft_b, p256_base);
476
+ const RSFactory the_reed_solomon_factory(Fs);
477
+
478
+ size_t r = zk_spec->version < 7 ? kLigeroRate : kLigeroRatev7;
479
+ size_t req = zk_spec->version < 7 ? kLigeroNreq : kLigeroNreqv7;
480
+ ZkProof<f_128> h_zk(*c_hash, r, req, zk_spec->block_enc_hash);
481
+ ZkProof<Fp256Base> sig_zk(*c_sig, r, req, zk_spec->block_enc_sig);
482
+
483
+ ZkProver<f_128, RSFactory> hash_p(*c_hash, Fs, the_reed_solomon_factory);
484
+ ZkProver<Fp256Base, RSFactory_b> sig_p(*c_sig, p256_base, rsf_b);
485
+
486
+ hash_p.commit(h_zk, W_hash, tp, rng);
487
+ sig_p.commit(sig_zk, W_sig, tp, rng);
488
+
489
+ log(INFO,
490
+ "commit created. h[nl:%zu, ni:%zu], s[nl:%zu, ni:%zu] hc[b:%zu r:%zu] "
491
+ "sc[b:%zu r:%zu]",
492
+ c_hash->nl, c_hash->ninputs, c_sig->nl, c_sig->ninputs, h_zk.param.block,
493
+ h_zk.param.nrow, sig_zk.param.block, sig_zk.param.nrow);
494
+
495
+ // After prover has committed to the public inputs, compute
496
+ // verifier challenge av, and then compute MACs of the common public
497
+ // inputs.
498
+
499
+ gf2k av = generate_mac_key(tp), macs[6];
500
+ uint8_t macs_b[6 * f_128::kBytes];
501
+ compute_macs(3, state.common, macs, macs_b, state.ap, av);
502
+ update_macs(W_sig, W_hash, kSigMacIndex,
503
+ getHashMacIndex(attrs_len, zk_spec->version), macs, av, Fs);
504
+
505
+ if (!hash_p.prove(h_zk, W_hash, tp)) {
506
+ return MDOC_PROVER_GENERAL_FAILURE;
507
+ };
508
+ log(INFO, "ZK hash proof done");
509
+
510
+ if (!sig_p.prove(sig_zk, W_sig, tp)) {
511
+ return MDOC_PROVER_GENERAL_FAILURE;
512
+ };
513
+ log(INFO, "ZK signature proof done");
514
+
515
+ // Serialize proof to bytes.
516
+ // [6 mac values] [docType] [hash proof] [sig proof]
517
+ std::vector<uint8_t> buf;
518
+ // This sum will not overflow based on constraints of circuit & proof size.
519
+ size_t tt = 6 * f_128::kBytes + h_zk.size() + sig_zk.size();
520
+ buf.reserve(tt);
521
+ buf.insert(buf.begin(), macs_b, macs_b + 6 * f_128::kBytes);
522
+ h_zk.write(buf, Fs);
523
+ sig_zk.write(buf, p256_base);
524
+ *proof_len = buf.size();
525
+ log(INFO, "proof_len: %zu ", *proof_len);
526
+
527
+ // Allocate memory and copy proof bytes.
528
+ *prf = (uint8_t*)malloc(*proof_len);
529
+ if (!*prf) {
530
+ log(ERROR, "malloc failed");
531
+ return MDOC_PROVER_MEMORY_ALLOCATION_FAILURE;
532
+ }
533
+ memcpy(*prf, buf.data(), buf.size());
534
+ return MDOC_PROVER_SUCCESS;
535
+ }
536
+
537
+ MdocVerifierErrorCode run_mdoc_verifier(
538
+ const uint8_t* bcp, size_t bcsz, /* circuit data */
539
+ const char* pkx, const char* pky, /* string rep of public key */
540
+ const uint8_t* transcript, size_t tr_len, /* session Transcript */
541
+ const RequestedAttribute* attrs, size_t attrs_len,
542
+ const char* now, /* time formatted as "2023-11-02T09:00:00Z" */
543
+ const uint8_t* zkproof, size_t proof_len, const char* docType,
544
+ const ZkSpecStruct* zk_spec) {
545
+ if (bcp == nullptr || pkx == nullptr || pky == nullptr ||
546
+ transcript == nullptr || now == nullptr || attrs == nullptr ||
547
+ zkproof == nullptr || docType == nullptr || zk_spec == nullptr) {
548
+ return MDOC_VERIFIER_NULL_INPUT;
549
+ }
550
+
551
+ Elt pkX, pkY;
552
+ if (!parsePk(pkx, pky, pkX, pkY)) {
553
+ log(ERROR, "invalid pkx, pky");
554
+ return MDOC_VERIFIER_INVALID_INPUT;
555
+ }
556
+
557
+ if (!sameNamespace(attrs, attrs_len)) {
558
+ log(ERROR, "attributes must all be in the same namespace");
559
+ return MDOC_VERIFIER_INVALID_INPUT;
560
+ }
561
+
562
+ // Verify that the values in the RequestedAttribute structure are valid cbor.
563
+ for (size_t i = 0; i < attrs_len; ++i) {
564
+ if (!cbor_validate(attrs[i].cbor_value, attrs[i].cbor_value_len)) {
565
+ log(ERROR, "invalid cbor value");
566
+ return MDOC_VERIFIER_INVALID_CBOR;
567
+ }
568
+ }
569
+
570
+ const f_128 Fs;
571
+
572
+ // Sanity check input sizes.
573
+ if (bcsz < 50000 || tr_len < 1 || attrs_len < 1 || proof_len < 20000) {
574
+ return MDOC_VERIFIER_ARGUMENTS_TOO_SMALL;
575
+ }
576
+
577
+ const f2_p256 p256_2(p256_base);
578
+
579
+ // Parse circuits from cached byte representation.
580
+ size_t len = kCircuitSizeMax;
581
+ std::vector<uint8_t> bytes(len);
582
+ size_t full_size = decompress(bytes, bcp, bcsz);
583
+
584
+ // For now, we are not using the ZKSpec version anywhere and assuming no
585
+ // backwards compatibility. As soon as we have a use case for it, we have to
586
+ // pass the ZkSpecStruct to all required downstream functions.
587
+ log(INFO, "bytes len: %zu", full_size);
588
+
589
+ ReadBuffer rb_circuit(bytes.data(), full_size);
590
+ CircuitRep<Fp256Base> cr_s(p256_base, P256_ID);
591
+ auto c_sig = cr_s.from_bytes(rb_circuit, enforce_circuit_id_in_verifier);
592
+ if (c_sig == nullptr) {
593
+ log(ERROR, "signature circuit could not be parsed");
594
+ return MDOC_VERIFIER_CIRCUIT_PARSING_FAILURE;
595
+ }
596
+
597
+ CircuitRep<f_128> cr_h(Fs, GF2_128_ID);
598
+ auto c_hash = cr_h.from_bytes(rb_circuit, enforce_circuit_id_in_verifier);
599
+
600
+ if (c_hash == nullptr) {
601
+ log(ERROR, "circuit could not be parsed");
602
+ return MDOC_VERIFIER_CIRCUIT_PARSING_FAILURE;
603
+ }
604
+ log(INFO, "circuit created. h[in:%zu], s[in:%zu]", c_hash->ninputs,
605
+ c_sig->ninputs);
606
+
607
+ // Parse proofs
608
+ size_t r = zk_spec->version < 7 ? kLigeroRate : kLigeroRatev7;
609
+ size_t req = zk_spec->version < 7 ? kLigeroNreq : kLigeroNreqv7;
610
+ ZkProof<f_128> pr_hash(*c_hash, r, req, zk_spec->block_enc_hash);
611
+ ZkProof<Fp256Base> pr_sig(*c_sig, r, req, zk_spec->block_enc_sig);
612
+
613
+ log(INFO,
614
+ "proof params: h[nl:%zu, ni:%zu], s[nl:%zu, ni:%zu] hc[b:%zu r:%zu] "
615
+ "sc[b:%zu r:%zu]",
616
+ c_hash->nl, c_hash->ninputs, c_sig->nl, c_sig->ninputs,
617
+ pr_hash.param.block, pr_hash.param.nrow, pr_sig.param.block,
618
+ pr_sig.param.nrow);
619
+
620
+ const std::vector<uint8_t> zbuf(zkproof, zkproof + proof_len);
621
+ ReadBuffer rb(zbuf);
622
+
623
+ // Read macs from proof string.
624
+ // The sanity check above ensures that the proof is big enough for the MACs.
625
+ gf2k macs[6];
626
+
627
+ for (size_t i = 0; i < 6; ++i) {
628
+ macs[i] = Fs.of_bytes_field(rb.next(f_128::kBytes)).value();
629
+ }
630
+
631
+ // The proof read methods check proof length internally.
632
+ if (!pr_hash.read(rb, Fs)) {
633
+ log(ERROR, "hash proof could not be parsed");
634
+ return MDOC_VERIFIER_HASH_PARSING_FAILURE;
635
+ };
636
+ if (!pr_sig.read(rb, p256_base)) {
637
+ log(ERROR, "sig proof could not be parsed");
638
+ return MDOC_VERIFIER_SIGNATURE_PARSING_FAILURE;
639
+ }
640
+ if (rb.remaining() != 0) {
641
+ log(ERROR, "proof bytes contains extra data: %zu bytes", rb.remaining());
642
+ return MDOC_VERIFIER_SIGNATURE_PARSING_FAILURE;
643
+ }
644
+
645
+ log(INFO, "proofs read");
646
+
647
+ // =============== Verify
648
+
649
+ const Elt2 omega = p256_2.of_string(kRootX, kRootY);
650
+ const FftExtConvolutionFactory fft_b(p256_base, p256_2, omega, 1ull << 31);
651
+ const RSFactory_b rsf_b(fft_b, p256_base);
652
+ const RSFactory the_reed_solomon_factory(Fs);
653
+
654
+ ZkVerifier<f_128, RSFactory> hash_v(*c_hash, the_reed_solomon_factory, r, req,
655
+ zk_spec->block_enc_hash, Fs);
656
+ ZkVerifier<Fp256Base, RSFactory_b> sig_v(*c_sig, rsf_b, r, req,
657
+ zk_spec->block_enc_sig, p256_base);
658
+
659
+ // Use the transcript from the session to select the random oracle.
660
+ class Transcript tv(transcript, tr_len, zk_spec->version);
661
+
662
+ hash_v.recv_commitment(pr_hash, tv);
663
+ sig_v.recv_commitment(pr_sig, tv);
664
+
665
+ gf2k av = generate_mac_key(tv);
666
+
667
+ // =============== Create public inputs
668
+ auto pub_hash = Dense<f_128>(1, c_hash->npub_in);
669
+ auto pub_sig = Dense<Fp256Base>(1, c_sig->npub_in);
670
+ DenseFiller<f_128> hash_filler(pub_hash);
671
+ DenseFiller<Fp256Base> sig_filler(pub_sig);
672
+
673
+ size_t dlen = strlen(docType);
674
+ if (!fill_public_inputs(sig_filler, hash_filler, pkX, pkY, transcript, tr_len,
675
+ attrs, attrs_len, (const uint8_t*)now,
676
+ (const uint8_t*)docType, dlen, macs, av, Fs,
677
+ zk_spec->version)) {
678
+ return MDOC_VERIFIER_GENERAL_FAILURE;
679
+ }
680
+
681
+ if (hash_filler.size() != c_hash->npub_in ||
682
+ sig_filler.size() != c_sig->npub_in) {
683
+ return MDOC_VERIFIER_ATTRIBUTE_NUMBER_MISMATCH;
684
+ }
685
+
686
+ bool ok = hash_v.verify(pr_hash, pub_hash, tv);
687
+ bool ok2 = sig_v.verify(pr_sig, pub_sig, tv);
688
+
689
+ return ok && ok2 ? MDOC_VERIFIER_SUCCESS : MDOC_VERIFIER_GENERAL_FAILURE;
690
+ }
691
+
692
+ } /* extern "C" */
693
+ } // namespace proofs