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.
- checksums.yaml +7 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +152 -0
- data/ext/longfellow/CMakeLists.txt +76 -0
- data/ext/longfellow/extconf.rb +77 -0
- data/lib/longfellow/attribute.rb +65 -0
- data/lib/longfellow/c.rb +105 -0
- data/lib/longfellow/errors.rb +78 -0
- data/lib/longfellow/version.rb +5 -0
- data/lib/longfellow/zk_spec.rb +40 -0
- data/lib/longfellow.rb +162 -0
- data/sig/longfellow.rbs +74 -0
- data/vendor/longfellow-zk/LICENSE +203 -0
- data/vendor/longfellow-zk/lib/algebra/blas.h +121 -0
- data/vendor/longfellow-zk/lib/algebra/bogorng.h +68 -0
- data/vendor/longfellow-zk/lib/algebra/compare.h +40 -0
- data/vendor/longfellow-zk/lib/algebra/convolution.h +219 -0
- data/vendor/longfellow-zk/lib/algebra/crt.cc +42 -0
- data/vendor/longfellow-zk/lib/algebra/crt.h +299 -0
- data/vendor/longfellow-zk/lib/algebra/crt_convolution.h +114 -0
- data/vendor/longfellow-zk/lib/algebra/crt_test.cc +371 -0
- data/vendor/longfellow-zk/lib/algebra/fft.h +104 -0
- data/vendor/longfellow-zk/lib/algebra/fft_interpolation.h +304 -0
- data/vendor/longfellow-zk/lib/algebra/fft_interpolation_test.cc +168 -0
- data/vendor/longfellow-zk/lib/algebra/fft_test.cc +257 -0
- data/vendor/longfellow-zk/lib/algebra/fp.h +59 -0
- data/vendor/longfellow-zk/lib/algebra/fp2.h +240 -0
- data/vendor/longfellow-zk/lib/algebra/fp24.h +342 -0
- data/vendor/longfellow-zk/lib/algebra/fp24_6.h +305 -0
- data/vendor/longfellow-zk/lib/algebra/fp24_6_test.cc +197 -0
- data/vendor/longfellow-zk/lib/algebra/fp2_test.cc +280 -0
- data/vendor/longfellow-zk/lib/algebra/fp_generic.h +533 -0
- data/vendor/longfellow-zk/lib/algebra/fp_p128.h +91 -0
- data/vendor/longfellow-zk/lib/algebra/fp_p256.h +68 -0
- data/vendor/longfellow-zk/lib/algebra/fp_p256k1.h +123 -0
- data/vendor/longfellow-zk/lib/algebra/fp_p384.h +65 -0
- data/vendor/longfellow-zk/lib/algebra/fp_p521.h +62 -0
- data/vendor/longfellow-zk/lib/algebra/fp_test.cc +522 -0
- data/vendor/longfellow-zk/lib/algebra/hash.h +39 -0
- data/vendor/longfellow-zk/lib/algebra/interpolation.h +117 -0
- data/vendor/longfellow-zk/lib/algebra/interpolation_test.cc +74 -0
- data/vendor/longfellow-zk/lib/algebra/limb.h +153 -0
- data/vendor/longfellow-zk/lib/algebra/limb_test.cc +75 -0
- data/vendor/longfellow-zk/lib/algebra/nat.cc +32 -0
- data/vendor/longfellow-zk/lib/algebra/nat.h +212 -0
- data/vendor/longfellow-zk/lib/algebra/nat_test.cc +183 -0
- data/vendor/longfellow-zk/lib/algebra/nussbaumer.h +400 -0
- data/vendor/longfellow-zk/lib/algebra/nussbaumer_test.cc +138 -0
- data/vendor/longfellow-zk/lib/algebra/nussbaumerfp2_test.cc +139 -0
- data/vendor/longfellow-zk/lib/algebra/permutations.h +79 -0
- data/vendor/longfellow-zk/lib/algebra/poly.h +240 -0
- data/vendor/longfellow-zk/lib/algebra/poly_test.cc +123 -0
- data/vendor/longfellow-zk/lib/algebra/reed_solomon.h +150 -0
- data/vendor/longfellow-zk/lib/algebra/reed_solomon_extension.h +108 -0
- data/vendor/longfellow-zk/lib/algebra/reed_solomon_extension_test.cc +76 -0
- data/vendor/longfellow-zk/lib/algebra/reed_solomon_test.cc +473 -0
- data/vendor/longfellow-zk/lib/algebra/rfft.h +400 -0
- data/vendor/longfellow-zk/lib/algebra/rfft_test.cc +102 -0
- data/vendor/longfellow-zk/lib/algebra/static_string.h +29 -0
- data/vendor/longfellow-zk/lib/algebra/sysdep.h +495 -0
- data/vendor/longfellow-zk/lib/algebra/sysdep_test.cc +41 -0
- data/vendor/longfellow-zk/lib/algebra/twiddle.h +59 -0
- data/vendor/longfellow-zk/lib/algebra/utility.h +86 -0
- data/vendor/longfellow-zk/lib/algebra/utility_test.cc +86 -0
- data/vendor/longfellow-zk/lib/arrays/affine.h +56 -0
- data/vendor/longfellow-zk/lib/arrays/affine_test.cc +220 -0
- data/vendor/longfellow-zk/lib/arrays/dense.h +210 -0
- data/vendor/longfellow-zk/lib/arrays/eq.h +75 -0
- data/vendor/longfellow-zk/lib/arrays/eqs.h +137 -0
- data/vendor/longfellow-zk/lib/arrays/eqs_test.cc +151 -0
- data/vendor/longfellow-zk/lib/arrays/sparse.h +192 -0
- data/vendor/longfellow-zk/lib/cbor/host_decoder.h +323 -0
- data/vendor/longfellow-zk/lib/cbor/host_decoder_test.cc +541 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor.h +594 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_byte_decoder.h +150 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_byte_decoder_test.cc +147 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_constants.h +27 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_pluck.h +110 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_pluck_test.cc +55 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_test.cc +174 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_testing.h +98 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/cbor_witness.h +312 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/mso2_test.cc +662 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/mso_test.cc +485 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/scan.h +104 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser/scan_test.cc +137 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor.h +640 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_byte_decoder.h +150 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_byte_decoder_test.cc +147 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_constants.h +27 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_testing.h +99 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/cbor_witness.h +319 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/lexer_test.cc +120 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/mdoc_examples_test.cc +89 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/parser_circuit_test.cc +506 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/parser_size_test.cc +79 -0
- data/vendor/longfellow-zk/lib/circuits/cbor_parser_v2/parser_test.cc +473 -0
- data/vendor/longfellow-zk/lib/circuits/compiler/canonicalization_test.cc +185 -0
- data/vendor/longfellow-zk/lib/circuits/compiler/circuit_dump.h +65 -0
- data/vendor/longfellow-zk/lib/circuits/compiler/compiler.h +471 -0
- data/vendor/longfellow-zk/lib/circuits/compiler/compiler_test.cc +110 -0
- data/vendor/longfellow-zk/lib/circuits/compiler/node.h +176 -0
- data/vendor/longfellow-zk/lib/circuits/compiler/pdqhash.h +127 -0
- data/vendor/longfellow-zk/lib/circuits/compiler/schedule.h +435 -0
- data/vendor/longfellow-zk/lib/circuits/ecdsa/verify_circuit.h +371 -0
- data/vendor/longfellow-zk/lib/circuits/ecdsa/verify_external_test.cc +246 -0
- data/vendor/longfellow-zk/lib/circuits/ecdsa/verify_test.cc +587 -0
- data/vendor/longfellow-zk/lib/circuits/ecdsa/verify_witness.h +201 -0
- data/vendor/longfellow-zk/lib/circuits/logic/bit_adder.h +140 -0
- data/vendor/longfellow-zk/lib/circuits/logic/bit_adder_test.cc +64 -0
- data/vendor/longfellow-zk/lib/circuits/logic/bit_plucker.h +247 -0
- data/vendor/longfellow-zk/lib/circuits/logic/bit_plucker_constants.h +35 -0
- data/vendor/longfellow-zk/lib/circuits/logic/bit_plucker_encoder.h +72 -0
- data/vendor/longfellow-zk/lib/circuits/logic/bit_plucker_test.cc +183 -0
- data/vendor/longfellow-zk/lib/circuits/logic/compiler_backend.h +62 -0
- data/vendor/longfellow-zk/lib/circuits/logic/counter.h +171 -0
- data/vendor/longfellow-zk/lib/circuits/logic/counter_test.cc +102 -0
- data/vendor/longfellow-zk/lib/circuits/logic/evaluation_backend.h +94 -0
- data/vendor/longfellow-zk/lib/circuits/logic/logic.h +1232 -0
- data/vendor/longfellow-zk/lib/circuits/logic/logic_circuit_test.cc +310 -0
- data/vendor/longfellow-zk/lib/circuits/logic/logic_test.cc +521 -0
- data/vendor/longfellow-zk/lib/circuits/logic/memcmp.h +68 -0
- data/vendor/longfellow-zk/lib/circuits/logic/memcmp_test.cc +148 -0
- data/vendor/longfellow-zk/lib/circuits/logic/polynomial.h +94 -0
- data/vendor/longfellow-zk/lib/circuits/logic/polynomial_test.cc +62 -0
- data/vendor/longfellow-zk/lib/circuits/logic/routing.h +445 -0
- data/vendor/longfellow-zk/lib/circuits/logic/routing_test.cc +241 -0
- data/vendor/longfellow-zk/lib/circuits/logic/unary.h +55 -0
- data/vendor/longfellow-zk/lib/circuits/logic/unary_plucker.h +77 -0
- data/vendor/longfellow-zk/lib/circuits/logic/unary_plucker_constants.h +37 -0
- data/vendor/longfellow-zk/lib/circuits/logic/unary_plucker_test.cc +53 -0
- data/vendor/longfellow-zk/lib/circuits/logic/unary_size_test.cc +69 -0
- data/vendor/longfellow-zk/lib/circuits/logic/unary_test.cc +62 -0
- data/vendor/longfellow-zk/lib/circuits/mac/mac_circuit.h +193 -0
- data/vendor/longfellow-zk/lib/circuits/mac/mac_circuit_test.cc +223 -0
- data/vendor/longfellow-zk/lib/circuits/mac/mac_reference.h +72 -0
- data/vendor/longfellow-zk/lib/circuits/mac/mac_witness.h +94 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/circuit_maker.cc +242 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_attribute_ids.h +311 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_attribute_test.cc +64 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_circuit_id.cc +85 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_constants.h +85 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_decompress.cc +41 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_decompress.h +27 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_examples.h +5232 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_generate_circuit.cc +199 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_hash.h +554 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_signature.h +143 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_signature_test.cc +444 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_test_attributes.h +157 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_witness.h +863 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_zk.cc +693 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_zk.h +216 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/mdoc_zk_test.cc +724 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/zk_spec.cc +100 -0
- data/vendor/longfellow-zk/lib/circuits/mdoc/zk_spec_test.cc +155 -0
- data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_circuit.h +330 -0
- data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_circuit_test.cc +607 -0
- data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_io.h +26 -0
- data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_witness.cc +163 -0
- data/vendor/longfellow-zk/lib/circuits/sha/flatsha256_witness.h +47 -0
- data/vendor/longfellow-zk/lib/circuits/sha/sha256_constants.cc +34 -0
- data/vendor/longfellow-zk/lib/circuits/sha/sha256_constants.h +27 -0
- data/vendor/longfellow-zk/lib/circuits/sha/sha256_test_values.h +389 -0
- data/vendor/longfellow-zk/lib/circuits/tests/anoncred/ptrcred.h +171 -0
- data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small.h +218 -0
- data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small_examples.h +118 -0
- data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small_io.h +25 -0
- data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small_test.cc +208 -0
- data/vendor/longfellow-zk/lib/circuits/tests/anoncred/small_witness.h +130 -0
- data/vendor/longfellow-zk/lib/circuits/tests/base64/decode.h +508 -0
- data/vendor/longfellow-zk/lib/circuits/tests/base64/decode_circuit_test.cc +95 -0
- data/vendor/longfellow-zk/lib/circuits/tests/base64/decode_test.cc +119 -0
- data/vendor/longfellow-zk/lib/circuits/tests/base64/decode_util.cc +47 -0
- data/vendor/longfellow-zk/lib/circuits/tests/base64/decode_util.h +29 -0
- data/vendor/longfellow-zk/lib/circuits/tests/ec/pk_circuit.h +231 -0
- data/vendor/longfellow-zk/lib/circuits/tests/ec/pk_circuit_test.cc +428 -0
- data/vendor/longfellow-zk/lib/circuits/tests/ec/pk_witness.h +102 -0
- data/vendor/longfellow-zk/lib/circuits/tests/jwt/jwt.h +190 -0
- data/vendor/longfellow-zk/lib/circuits/tests/jwt/jwt_constants.h +26 -0
- data/vendor/longfellow-zk/lib/circuits/tests/jwt/jwt_test.cc +559 -0
- data/vendor/longfellow-zk/lib/circuits/tests/jwt/jwt_witness.h +315 -0
- data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_1f.h +411 -0
- data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_1f_io.h +32 -0
- data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_1f_test.cc +364 -0
- data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_1f_witness.h +278 -0
- data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_revocation.h +146 -0
- data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_revocation_constants.h +25 -0
- data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_revocation_test.cc +315 -0
- data/vendor/longfellow-zk/lib/circuits/tests/mdoc/mdoc_revocation_witness.h +136 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/bitaddr/bitaddr.h +250 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/bitaddr/bitaddr_test.cc +333 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/bitaddr/bitaddr_witness.h +152 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44.h +903 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_circuit_test.cc +274 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_eval_test.cc +440 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_examples.cc +8851 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_examples.h +93 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_types.cc +24 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_types.h +118 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_witness.h +453 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_44_witness_test.cc +49 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref.cc +458 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref.h +150 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref_test.cc +398 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref_test_vectors.inc +3618 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref_test_vectors_pkdecode.inc +689 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/ml_dsa_ref_test_vectors_sigdecode.inc +1501 -0
- data/vendor/longfellow-zk/lib/circuits/tests/pq/ml_dsa/sigdecode_test_vectors.inc +540 -0
- data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_circuit.h +394 -0
- data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_circuit_test.cc +577 -0
- data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_constants.h +90 -0
- data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_witness.cc +174 -0
- data/vendor/longfellow-zk/lib/circuits/tests/ripemd/ripemd_witness.h +140 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_circuit.h +351 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_circuit_test.cc +466 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_reference.cc +207 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_reference.h +59 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_reference_test.cc +153 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_round_constants.cc +39 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_round_constants.h +29 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_slicing.h +31 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_witness.cc +83 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/sha3_witness.h +72 -0
- data/vendor/longfellow-zk/lib/circuits/tests/sha3/shake_test_vectors.h +477 -0
- data/vendor/longfellow-zk/lib/ec/elliptic_curve.h +596 -0
- data/vendor/longfellow-zk/lib/ec/elliptic_curve_test.cc +548 -0
- data/vendor/longfellow-zk/lib/ec/p256.cc +36 -0
- data/vendor/longfellow-zk/lib/ec/p256.h +60 -0
- data/vendor/longfellow-zk/lib/ec/p256k1.cc +34 -0
- data/vendor/longfellow-zk/lib/ec/p256k1.h +60 -0
- data/vendor/longfellow-zk/lib/gf2k/gf2_128.h +503 -0
- data/vendor/longfellow-zk/lib/gf2k/gf2_128_bench.cc +48 -0
- data/vendor/longfellow-zk/lib/gf2k/gf2_128_test.cc +416 -0
- data/vendor/longfellow-zk/lib/gf2k/gf2poly.h +74 -0
- data/vendor/longfellow-zk/lib/gf2k/lch14.h +242 -0
- data/vendor/longfellow-zk/lib/gf2k/lch14_bench.cc +75 -0
- data/vendor/longfellow-zk/lib/gf2k/lch14_reed_solomon.h +127 -0
- data/vendor/longfellow-zk/lib/gf2k/lch14_reed_solomon_test.cc +110 -0
- data/vendor/longfellow-zk/lib/gf2k/lch14_test.cc +246 -0
- data/vendor/longfellow-zk/lib/gf2k/sysdep.h +329 -0
- data/vendor/longfellow-zk/lib/ligero/ligero_param.h +449 -0
- data/vendor/longfellow-zk/lib/ligero/ligero_prover.h +354 -0
- data/vendor/longfellow-zk/lib/ligero/ligero_test.cc +136 -0
- data/vendor/longfellow-zk/lib/ligero/ligero_transcript.h +67 -0
- data/vendor/longfellow-zk/lib/ligero/ligero_verifier.h +272 -0
- data/vendor/longfellow-zk/lib/merkle/merkle_commitment.h +104 -0
- data/vendor/longfellow-zk/lib/merkle/merkle_tree.h +216 -0
- data/vendor/longfellow-zk/lib/merkle/merkle_tree_test.cc +240 -0
- data/vendor/longfellow-zk/lib/proto/circuit.h +354 -0
- data/vendor/longfellow-zk/lib/proto/circuit_test.cc +202 -0
- data/vendor/longfellow-zk/lib/random/random.h +119 -0
- data/vendor/longfellow-zk/lib/random/random_test.cc +189 -0
- data/vendor/longfellow-zk/lib/random/secure_random_engine.h +37 -0
- data/vendor/longfellow-zk/lib/random/transcript.h +193 -0
- data/vendor/longfellow-zk/lib/random/transcript_test.cc +344 -0
- data/vendor/longfellow-zk/lib/sumcheck/circuit.h +148 -0
- data/vendor/longfellow-zk/lib/sumcheck/circuit_id.h +71 -0
- data/vendor/longfellow-zk/lib/sumcheck/equad.h +126 -0
- data/vendor/longfellow-zk/lib/sumcheck/hquad.h +115 -0
- data/vendor/longfellow-zk/lib/sumcheck/prover.h +59 -0
- data/vendor/longfellow-zk/lib/sumcheck/prover_layers.h +362 -0
- data/vendor/longfellow-zk/lib/sumcheck/quad.h +227 -0
- data/vendor/longfellow-zk/lib/sumcheck/quad_builder.h +211 -0
- data/vendor/longfellow-zk/lib/sumcheck/quad_test.cc +169 -0
- data/vendor/longfellow-zk/lib/sumcheck/sumcheck_test.cc +324 -0
- data/vendor/longfellow-zk/lib/sumcheck/testing.h +69 -0
- data/vendor/longfellow-zk/lib/sumcheck/transcript_sumcheck.h +85 -0
- data/vendor/longfellow-zk/lib/sumcheck/verifier.h +84 -0
- data/vendor/longfellow-zk/lib/sumcheck/verifier_layers.h +221 -0
- data/vendor/longfellow-zk/lib/testing/test_main.cc +50 -0
- data/vendor/longfellow-zk/lib/util/ceildiv.h +164 -0
- data/vendor/longfellow-zk/lib/util/ceildiv_test.cc +152 -0
- data/vendor/longfellow-zk/lib/util/crc64.h +45 -0
- data/vendor/longfellow-zk/lib/util/crypto.cc +39 -0
- data/vendor/longfellow-zk/lib/util/crypto.h +108 -0
- data/vendor/longfellow-zk/lib/util/log.cc +110 -0
- data/vendor/longfellow-zk/lib/util/log.h +33 -0
- data/vendor/longfellow-zk/lib/util/panic.h +40 -0
- data/vendor/longfellow-zk/lib/util/readbuffer.h +67 -0
- data/vendor/longfellow-zk/lib/util/serialization.h +54 -0
- data/vendor/longfellow-zk/lib/zk/zk_common.h +455 -0
- data/vendor/longfellow-zk/lib/zk/zk_proof.h +378 -0
- data/vendor/longfellow-zk/lib/zk/zk_prover.h +202 -0
- data/vendor/longfellow-zk/lib/zk/zk_test.cc +340 -0
- data/vendor/longfellow-zk/lib/zk/zk_testing.h +154 -0
- data/vendor/longfellow-zk/lib/zk/zk_verifier.h +109 -0
- metadata +347 -0
|
@@ -0,0 +1,272 @@
|
|
|
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_LIGERO_LIGERO_VERIFIER_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_LIGERO_LIGERO_VERIFIER_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
|
|
20
|
+
#include <array>
|
|
21
|
+
#include <vector>
|
|
22
|
+
|
|
23
|
+
#include "algebra/blas.h"
|
|
24
|
+
#include "ligero/ligero_param.h"
|
|
25
|
+
#include "ligero/ligero_transcript.h"
|
|
26
|
+
#include "merkle/merkle_commitment.h"
|
|
27
|
+
#include "random/transcript.h"
|
|
28
|
+
#include "util/crypto.h"
|
|
29
|
+
|
|
30
|
+
namespace proofs {
|
|
31
|
+
template <class Field, class InterpolatorFactory>
|
|
32
|
+
class LigeroVerifier {
|
|
33
|
+
using Elt = typename Field::Elt;
|
|
34
|
+
|
|
35
|
+
public:
|
|
36
|
+
static void receive_commitment(const LigeroCommitment<Field>& commitment,
|
|
37
|
+
Transcript& ts) {
|
|
38
|
+
// P -> V
|
|
39
|
+
LigeroTranscript<Field>::write_commitment(commitment, ts);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static bool verify(const char** why, const LigeroParam<Field>& p,
|
|
43
|
+
const LigeroCommitment<Field>& commitment,
|
|
44
|
+
const LigeroProof<Field>& proof, Transcript& ts, size_t nl,
|
|
45
|
+
size_t nllterm,
|
|
46
|
+
const LigeroLinearConstraint<Field> llterm[/*nllterm*/],
|
|
47
|
+
const LigeroHash& hash_of_llterm, const Elt b[/*nl*/],
|
|
48
|
+
const LigeroQuadraticConstraint lqc[/*nq*/],
|
|
49
|
+
const InterpolatorFactory& interpolator, const Field& F) {
|
|
50
|
+
if (why == nullptr) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
std::vector<Elt> u_ldt(p.nwqrow);
|
|
55
|
+
std::vector<Elt> alphal(nl);
|
|
56
|
+
std::vector<std::array<Elt, 3>> alphaq(p.nq);
|
|
57
|
+
std::vector<Elt> u_quad(p.nqtriples);
|
|
58
|
+
std::vector<size_t> idx(p.nreq);
|
|
59
|
+
|
|
60
|
+
// Replay the protocol first in order to compute all the
|
|
61
|
+
// challenges. In particular, we need IDX before we can do
|
|
62
|
+
// anything useful.
|
|
63
|
+
|
|
64
|
+
// P -> V
|
|
65
|
+
ts.write(hash_of_llterm.bytes, hash_of_llterm.kLength);
|
|
66
|
+
|
|
67
|
+
// V -> P
|
|
68
|
+
LigeroTranscript<Field>::gen_uldt(&u_ldt[0], p, ts, F);
|
|
69
|
+
|
|
70
|
+
// V -> P
|
|
71
|
+
LigeroTranscript<Field>::gen_alphal(nl, &alphal[0], ts, F);
|
|
72
|
+
LigeroTranscript<Field>::gen_alphaq(&alphaq[0], p, ts, F);
|
|
73
|
+
|
|
74
|
+
// V -> P
|
|
75
|
+
LigeroTranscript<Field>::gen_uquad(&u_quad[0], p, ts, F);
|
|
76
|
+
|
|
77
|
+
// P -> V
|
|
78
|
+
ts.write(&proof.y_ldt[0], 1, p.block, F);
|
|
79
|
+
ts.write(&proof.y_dot[0], 1, p.dblock, F);
|
|
80
|
+
ts.write(&proof.y_quad_0[0], 1, p.r, F);
|
|
81
|
+
ts.write(&proof.y_quad_2[0], 1, p.dblock - p.block, F);
|
|
82
|
+
|
|
83
|
+
// V -> P
|
|
84
|
+
LigeroTranscript<Field>::gen_idx(&idx[0], p, ts, F);
|
|
85
|
+
|
|
86
|
+
if (!merkle_check(p, commitment, proof, &idx[0], F)) {
|
|
87
|
+
*why = "merkle_check failed";
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!low_degree_check(p, proof, &idx[0], &u_ldt[0], interpolator, F)) {
|
|
92
|
+
*why = "low_degree_check failed";
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
{
|
|
97
|
+
// linear check
|
|
98
|
+
std::vector<Elt> A(p.nwqrow * p.w);
|
|
99
|
+
|
|
100
|
+
LigeroCommon<Field>::inner_product_vector(&A[0], p, nl, nllterm, llterm,
|
|
101
|
+
&alphal[0], lqc, &alphaq[0], F);
|
|
102
|
+
|
|
103
|
+
if (!dot_check(p, proof, &idx[0], &A[0], interpolator, F)) {
|
|
104
|
+
*why = "dot_check failed";
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// check the putative value of the inner product
|
|
109
|
+
Elt want_dot = Blas<Field>::dot(nl, b, 1, &alphal[0], 1, F);
|
|
110
|
+
Elt proof_dot = Blas<Field>::dot1(p.w, &proof.y_dot[p.r], 1, F);
|
|
111
|
+
if (want_dot != proof_dot) {
|
|
112
|
+
*why = "wrong dot product";
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (!quadratic_check(p, proof, &idx[0], &u_quad[0], interpolator, F)) {
|
|
118
|
+
*why = "quadratic_check failed";
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
*why = "ok";
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private:
|
|
127
|
+
static void interpolate_req_columns(Elt yp[/*nreq*/],
|
|
128
|
+
const LigeroParam<Field>& p, size_t ylen,
|
|
129
|
+
const Elt y[/*ylen*/],
|
|
130
|
+
const size_t idx[/*nreq*/],
|
|
131
|
+
const InterpolatorFactory& interpolator,
|
|
132
|
+
const Field& F) {
|
|
133
|
+
const auto interpy = interpolator.make(ylen, p.block_enc);
|
|
134
|
+
std::vector<Elt> yext(p.block_enc);
|
|
135
|
+
Blas<Field>::copy(ylen, &yext[0], 1, y, 1);
|
|
136
|
+
interpy->interpolate(&yext[0]);
|
|
137
|
+
Blas<Field>::gather(p.nreq, &yp[0], &yext[p.dblock], idx);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static bool merkle_check(const LigeroParam<Field>& p,
|
|
141
|
+
const LigeroCommitment<Field>& commitment,
|
|
142
|
+
const LigeroProof<Field>& proof,
|
|
143
|
+
const size_t idx[/*nreq*/], const Field& F) {
|
|
144
|
+
auto updhash = [&](size_t r, SHA256& sha) {
|
|
145
|
+
LigeroCommon<Field>::column_hash(p.nrow, &proof.req_at(0, r), p.nreq, sha,
|
|
146
|
+
F);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
return MerkleCommitmentVerifier::verify(p.block_enc - p.dblock,
|
|
150
|
+
commitment.root, proof.merkle, idx,
|
|
151
|
+
p.nreq, updhash);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static bool low_degree_check(const LigeroParam<Field>& p,
|
|
155
|
+
const LigeroProof<Field>& proof,
|
|
156
|
+
const size_t idx[/*nreq*/],
|
|
157
|
+
const Elt u_ldt[/*nrow*/],
|
|
158
|
+
const InterpolatorFactory& interpolator,
|
|
159
|
+
const Field& F) {
|
|
160
|
+
std::vector<Elt> yc(p.nreq);
|
|
161
|
+
|
|
162
|
+
// the ILDT blinding row with coefficient 1
|
|
163
|
+
Blas<Field>::copy(p.nreq, &yc[0], 1, &proof.req_at(p.ildt, 0), 1);
|
|
164
|
+
|
|
165
|
+
// all remaining rows with coefficient u_ldt[]
|
|
166
|
+
for (size_t i = 0; i < p.nwqrow; ++i) {
|
|
167
|
+
Blas<Field>::axpy(p.nreq, &yc[0], 1, u_ldt[i], &proof.req_at(i + p.iw, 0),
|
|
168
|
+
1, F);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
std::vector<Elt> yp(p.nreq);
|
|
172
|
+
interpolate_req_columns(&yp[0], p, p.block, &proof.y_ldt[0], idx,
|
|
173
|
+
interpolator, F);
|
|
174
|
+
|
|
175
|
+
if (!Blas<Field>::equal(p.nreq, &yp[0], 1, &yc[0], 1, F)) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
static bool dot_check(const LigeroParam<Field>& p,
|
|
183
|
+
const LigeroProof<Field>& proof,
|
|
184
|
+
const size_t idx[/*nreq*/], const Elt A[/*nwqrow, w*/],
|
|
185
|
+
const InterpolatorFactory& interpolator,
|
|
186
|
+
const Field& F) {
|
|
187
|
+
std::vector<Elt> yc(p.nreq);
|
|
188
|
+
|
|
189
|
+
// the IDOT blinding row with coefficient 1
|
|
190
|
+
Blas<Field>::copy(p.nreq, &yc[0], 1, &proof.req_at(p.idot, 0), 1);
|
|
191
|
+
|
|
192
|
+
{
|
|
193
|
+
const auto interpA = interpolator.make(p.block, p.block_enc);
|
|
194
|
+
|
|
195
|
+
std::vector<Elt> Aext(p.block_enc);
|
|
196
|
+
std::vector<Elt> Areq(p.nreq);
|
|
197
|
+
|
|
198
|
+
for (size_t i = 0; i < p.nwqrow; ++i) {
|
|
199
|
+
LigeroCommon<Field>::layout_Aext(&Aext[0], p, i, &A[0], F);
|
|
200
|
+
interpA->interpolate(&Aext[0]);
|
|
201
|
+
Blas<Field>::gather(p.nreq, &Areq[0], &Aext[p.dblock], idx);
|
|
202
|
+
|
|
203
|
+
// Accumulate z += A[j] \otimes W[j].
|
|
204
|
+
Blas<Field>::vaxpy(p.nreq, &yc[0], 1, &Areq[0], 1,
|
|
205
|
+
&proof.req_at(i + p.iw, 0), 1, F);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
std::vector<Elt> yp(p.nreq);
|
|
210
|
+
interpolate_req_columns(&yp[0], p, p.dblock, &proof.y_dot[0], idx,
|
|
211
|
+
interpolator, F);
|
|
212
|
+
|
|
213
|
+
if (!Blas<Field>::equal(p.nreq, &yp[0], 1, &yc[0], 1, F)) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
static bool quadratic_check(const LigeroParam<Field>& p,
|
|
220
|
+
const LigeroProof<Field>& proof,
|
|
221
|
+
const size_t idx[/*nreq*/],
|
|
222
|
+
const Elt u_quad[/*nqtriples*/],
|
|
223
|
+
const InterpolatorFactory& interpolator,
|
|
224
|
+
const Field& F) {
|
|
225
|
+
std::vector<Elt> yc(p.nreq);
|
|
226
|
+
|
|
227
|
+
// the IQUAD blinding row with coefficient 1
|
|
228
|
+
Blas<Field>::copy(p.nreq, &yc[0], 1, &proof.req_at(p.iquad, 0), 1);
|
|
229
|
+
|
|
230
|
+
{
|
|
231
|
+
std::vector<Elt> tmp(p.nreq);
|
|
232
|
+
size_t iqx = p.iq;
|
|
233
|
+
size_t iqy = iqx + p.nqtriples;
|
|
234
|
+
size_t iqz = iqy + p.nqtriples;
|
|
235
|
+
|
|
236
|
+
// all quadratic triples with coefficient u_ldt[]
|
|
237
|
+
for (size_t i = 0; i < p.nqtriples; ++i) {
|
|
238
|
+
// yc += u_quad[i] * (z[i] - x[i] * y[i])
|
|
239
|
+
|
|
240
|
+
// tmp = z[i]
|
|
241
|
+
Blas<Field>::copy(p.nreq, &tmp[0], 1, &proof.req_at(iqz + i, 0), 1);
|
|
242
|
+
|
|
243
|
+
// tmp -= x[i] \otimes y[i]
|
|
244
|
+
Blas<Field>::vymax(p.nreq, &tmp[0], 1, &proof.req_at(iqx + i, 0), 1,
|
|
245
|
+
&proof.req_at(iqy + i, 0), 1, F);
|
|
246
|
+
|
|
247
|
+
// yc += u_quad[i] * tmp
|
|
248
|
+
Blas<Field>::axpy(p.nreq, &yc[0], 1, u_quad[i], &tmp[0], 1, F);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// reconstruct y_quad from the two parts in the proof
|
|
253
|
+
std::vector<Elt> yquad(p.dblock);
|
|
254
|
+
Blas<Field>::copy(p.r, &yquad[0], 1, &proof.y_quad_0[0], 1);
|
|
255
|
+
Blas<Field>::clear(p.w, &yquad[p.r], 1, F);
|
|
256
|
+
Blas<Field>::copy(p.dblock - p.block, &yquad[p.block], 1,
|
|
257
|
+
&proof.y_quad_2[0], 1);
|
|
258
|
+
|
|
259
|
+
// interpolate y_quad at the opened columns
|
|
260
|
+
std::vector<Elt> yp(p.nreq);
|
|
261
|
+
interpolate_req_columns(&yp[0], p, p.dblock, &yquad[0], idx, interpolator,
|
|
262
|
+
F);
|
|
263
|
+
|
|
264
|
+
if (!Blas<Field>::equal(p.nreq, &yp[0], 1, &yc[0], 1, F)) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
} // namespace proofs
|
|
271
|
+
|
|
272
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_LIGERO_LIGERO_VERIFIER_H_
|
|
@@ -0,0 +1,104 @@
|
|
|
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_MERKLE_MERKLE_COMMITMENT_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_MERKLE_MERKLE_COMMITMENT_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
#include <stdint.h>
|
|
20
|
+
|
|
21
|
+
#include <cstring>
|
|
22
|
+
#include <functional>
|
|
23
|
+
#include <vector>
|
|
24
|
+
|
|
25
|
+
#include "merkle/merkle_tree.h"
|
|
26
|
+
#include "random/random.h"
|
|
27
|
+
#include "util/crypto.h"
|
|
28
|
+
|
|
29
|
+
namespace proofs {
|
|
30
|
+
|
|
31
|
+
struct MerkleNonce {
|
|
32
|
+
static constexpr size_t kLength = kSHA256DigestSize;
|
|
33
|
+
uint8_t bytes[kLength];
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
struct MerkleProof {
|
|
37
|
+
explicit MerkleProof(size_t nreq) : nonce(nreq), path() {}
|
|
38
|
+
|
|
39
|
+
std::vector<MerkleNonce> nonce; // [nreq]
|
|
40
|
+
std::vector<Digest> path; // variable size, but < nreq * mt_pathlen
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
inline size_t merkle_commitment_len(size_t n) { return merkle_tree_len(n); }
|
|
44
|
+
|
|
45
|
+
// prover-side
|
|
46
|
+
class MerkleCommitment {
|
|
47
|
+
public:
|
|
48
|
+
explicit MerkleCommitment(size_t n) : n_(n), mt_(n), nonce_(n) {}
|
|
49
|
+
|
|
50
|
+
Digest commit(const std::function<void(size_t, SHA256 &)> &updhash,
|
|
51
|
+
RandomEngine &rng) {
|
|
52
|
+
for (size_t i = 0; i < n_; ++i) {
|
|
53
|
+
SHA256 sha;
|
|
54
|
+
rng.bytes(nonce_[i].bytes, MerkleNonce::kLength);
|
|
55
|
+
sha.Update(nonce_[i].bytes, MerkleNonce::kLength);
|
|
56
|
+
updhash(i, sha);
|
|
57
|
+
|
|
58
|
+
Digest dig;
|
|
59
|
+
sha.DigestData(dig.data);
|
|
60
|
+
mt_.set_leaf(i, dig);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return mt_.build_tree();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void open(MerkleProof &proof, const size_t pos[/*np*/], size_t np) {
|
|
67
|
+
// fill in the nonces of the opening
|
|
68
|
+
for (size_t i = 0; i < np; ++i) {
|
|
69
|
+
proof.nonce[i] = nonce_[pos[i]];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
(void)mt_.generate_compressed_proof(proof.path, pos, np);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private:
|
|
76
|
+
size_t n_;
|
|
77
|
+
MerkleTree mt_;
|
|
78
|
+
std::vector<MerkleNonce> nonce_;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Declare a class for symmetry, but this class is never instantiated
|
|
82
|
+
class MerkleCommitmentVerifier {
|
|
83
|
+
public:
|
|
84
|
+
static bool verify(size_t n, const Digest &root, const MerkleProof &proof,
|
|
85
|
+
const size_t pos[/*nreq*/], size_t nreq,
|
|
86
|
+
const std::function<void(size_t, SHA256 &)> &updhash) {
|
|
87
|
+
// Assemble the expected leaf values
|
|
88
|
+
std::vector<Digest> leaves(nreq);
|
|
89
|
+
for (size_t r = 0; r < nreq; ++r) {
|
|
90
|
+
SHA256 sha;
|
|
91
|
+
sha.Update(proof.nonce[r].bytes, MerkleNonce::kLength);
|
|
92
|
+
updhash(r, sha);
|
|
93
|
+
sha.DigestData(leaves[r].data);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
MerkleTreeVerifier mtv(n, root);
|
|
97
|
+
return mtv.verify_compressed_proof(proof.path.data(), proof.path.size(),
|
|
98
|
+
&leaves[0], pos, nreq);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
} // namespace proofs
|
|
103
|
+
|
|
104
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_MERKLE_MERKLE_COMMITMENT_H_
|
|
@@ -0,0 +1,216 @@
|
|
|
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_MERKLE_MERKLE_TREE_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_MERKLE_MERKLE_TREE_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
#include <stdint.h>
|
|
20
|
+
|
|
21
|
+
#include <cstring>
|
|
22
|
+
#include <vector>
|
|
23
|
+
|
|
24
|
+
#include "util/crypto.h"
|
|
25
|
+
#include "util/panic.h"
|
|
26
|
+
|
|
27
|
+
namespace proofs {
|
|
28
|
+
|
|
29
|
+
// This package computes and verifies Merkle Tree inclusion claims.
|
|
30
|
+
// The folklore Merkle tree algorithm has been implemented, with the following
|
|
31
|
+
// constraints:
|
|
32
|
+
// 1. A Merkle tree proof must reveal at least one leaf. We do not define
|
|
33
|
+
// empty proofs.
|
|
34
|
+
// 2. The list of leaves must be a set, i.e., with no duplicates. All usage
|
|
35
|
+
// within this library satisfies this requirement because the FS methods
|
|
36
|
+
// that produce the challenge set of indices includes no duplicates.
|
|
37
|
+
// 3. The generated proof of inclusion for a set of leaves is compressed.
|
|
38
|
+
// That is, if a node in the Merkle tree can be deduced, it is not included
|
|
39
|
+
// in the proof. This makes the proof shorter, but the proof length varies
|
|
40
|
+
// depending on the included leaves.
|
|
41
|
+
|
|
42
|
+
// A digest of a Merkle tree.
|
|
43
|
+
struct Digest {
|
|
44
|
+
static constexpr size_t kLength = kSHA256DigestSize;
|
|
45
|
+
uint8_t data[kLength];
|
|
46
|
+
|
|
47
|
+
bool operator==(const Digest& y) const {
|
|
48
|
+
return memcmp(data, y.data, kLength) == 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static Digest hash2(const Digest& L, const Digest& R) {
|
|
52
|
+
SHA256 sha;
|
|
53
|
+
sha.Update(L.data, kLength);
|
|
54
|
+
sha.Update(R.data, kLength);
|
|
55
|
+
Digest output;
|
|
56
|
+
sha.DigestData(output.data);
|
|
57
|
+
return output;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Return the length of the proof for N leaves.
|
|
62
|
+
// Mimic the code in generate_proof() without actually
|
|
63
|
+
// computing the proof
|
|
64
|
+
inline size_t merkle_tree_len(size_t n) {
|
|
65
|
+
size_t r = 1;
|
|
66
|
+
size_t pos = (n - 1); // maximum possible value
|
|
67
|
+
for (pos += n; pos > 1; pos >>= 1) {
|
|
68
|
+
++r;
|
|
69
|
+
}
|
|
70
|
+
return r;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// compute the set of all nodes on the path from the
|
|
74
|
+
// root to any leaf in POS.
|
|
75
|
+
inline std::vector<bool> compressed_merkle_proof_tree(size_t n,
|
|
76
|
+
const size_t pos[/*np*/],
|
|
77
|
+
size_t np) {
|
|
78
|
+
check(np > 0, "A Merkle proof with 0 leaves is not defined.");
|
|
79
|
+
std::vector<bool> tree(2 * n, false);
|
|
80
|
+
|
|
81
|
+
// leaves are in TREE
|
|
82
|
+
for (size_t ip = 0; ip < np; ++ip) {
|
|
83
|
+
check(pos[ip] < n, "Invalid position for leaf in Merkle tree");
|
|
84
|
+
check(tree[pos[ip] + n] == false,
|
|
85
|
+
"duplicate position in merkle tree requested");
|
|
86
|
+
tree[pos[ip] + n] = true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// If a child of an inner node is in TREE, then the parent is in TREE.
|
|
90
|
+
for (size_t i = n; i-- > 1;) {
|
|
91
|
+
tree[i] = (tree[2 * i] || tree[2 * i + 1]);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Assert that the root is in TREE.
|
|
95
|
+
check(tree[1], "tree[1]");
|
|
96
|
+
|
|
97
|
+
return tree;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
class MerkleTree {
|
|
101
|
+
public:
|
|
102
|
+
explicit MerkleTree(size_t n) : n_(n), layers_(2 * n) {}
|
|
103
|
+
|
|
104
|
+
void set_leaf(size_t pos, const Digest& leaf) {
|
|
105
|
+
check(pos < n_, "Invalid position for leaf in Merkle tree");
|
|
106
|
+
layers_[pos + n_] = leaf;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
Digest build_tree() {
|
|
110
|
+
for (size_t i = n_; i-- > 1;) {
|
|
111
|
+
layers_[i] = Digest::hash2(layers_[2 * i], layers_[2 * i + 1]);
|
|
112
|
+
}
|
|
113
|
+
return layers_[1];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Compressed Merkle proofs over a set POS[NP] of leaves.
|
|
117
|
+
//
|
|
118
|
+
// We first compute the set TREE of all nodes that are on the path
|
|
119
|
+
// from the root to any leaf in POS. Then, for each inner node in
|
|
120
|
+
// TREE, we include in the proof the child that is not in TREE, if
|
|
121
|
+
// any. Note, this method requires pos to contain no duplicates.
|
|
122
|
+
size_t generate_compressed_proof(std::vector<Digest>& proof,
|
|
123
|
+
const size_t pos[/*np*/], size_t np) {
|
|
124
|
+
std::vector<bool> tree = compressed_merkle_proof_tree(n_, pos, np);
|
|
125
|
+
|
|
126
|
+
// For each TREE node, include in the proof the
|
|
127
|
+
// child that is not TREE, if any.
|
|
128
|
+
size_t sz = 0;
|
|
129
|
+
for (size_t i = n_; i-- > 1;) {
|
|
130
|
+
if (tree[i]) {
|
|
131
|
+
size_t child = 2 * i;
|
|
132
|
+
if (tree[child]) {
|
|
133
|
+
// try the other child
|
|
134
|
+
child = 2 * i + 1;
|
|
135
|
+
}
|
|
136
|
+
if (!tree[child]) {
|
|
137
|
+
proof.push_back(layers_[child]);
|
|
138
|
+
++sz;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return sz;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
size_t n_;
|
|
146
|
+
// layers_[n, 2 * n) stores the leaves (nodes at layer 0).
|
|
147
|
+
// layers_[n/2, n) stores nodes at layer 1.
|
|
148
|
+
// layers_[n/4, n/2) stores nodes at layer 2, etc.
|
|
149
|
+
// The root is at layers_[1] where layers_[0] is not used.
|
|
150
|
+
std::vector<Digest> layers_;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
class MerkleTreeVerifier {
|
|
154
|
+
public:
|
|
155
|
+
explicit MerkleTreeVerifier(size_t n, const Digest& root)
|
|
156
|
+
: n_(n), root_(root) {}
|
|
157
|
+
|
|
158
|
+
// Verify a compressed Merkle proof.
|
|
159
|
+
// As mentioned above, this method assumes that pos contains no duplicates.
|
|
160
|
+
bool verify_compressed_proof(const Digest* proof, size_t proof_len,
|
|
161
|
+
const Digest leaves[/*np*/],
|
|
162
|
+
const size_t pos[/*np*/], size_t np) const {
|
|
163
|
+
// Reconstructed layers_, where only the DEFINED subset is
|
|
164
|
+
// defined.
|
|
165
|
+
std::vector<Digest> layers(2 * n_, Digest{});
|
|
166
|
+
std::vector<bool> defined(2 * n_, false);
|
|
167
|
+
|
|
168
|
+
/*scope for TREE */ {
|
|
169
|
+
std::vector<bool> tree = compressed_merkle_proof_tree(n_, pos, np);
|
|
170
|
+
|
|
171
|
+
// read the proof
|
|
172
|
+
size_t sz = 0;
|
|
173
|
+
for (size_t i = n_; i-- > 1;) {
|
|
174
|
+
if (tree[i]) {
|
|
175
|
+
size_t child = 2 * i;
|
|
176
|
+
if (tree[child]) {
|
|
177
|
+
// try the other child
|
|
178
|
+
child = 2 * i + 1;
|
|
179
|
+
}
|
|
180
|
+
if (!tree[child]) {
|
|
181
|
+
if (sz >= proof_len) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
layers[child] = proof[sz++];
|
|
185
|
+
defined[child] = true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// set LAYERS at all leaves in POS
|
|
192
|
+
for (size_t ip = 0; ip < np; ++ip) {
|
|
193
|
+
size_t l = pos[ip] + n_;
|
|
194
|
+
layers[l] = leaves[ip];
|
|
195
|
+
defined[l] = true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Recompute as many inner nodes as we can
|
|
199
|
+
for (size_t i = n_; i-- > 1;) {
|
|
200
|
+
if (defined[2 * i] && defined[2 * i + 1]) {
|
|
201
|
+
layers[i] = Digest::hash2(layers[2 * i], layers[2 * i + 1]);
|
|
202
|
+
defined[i] = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return (defined[1] && (root_ == layers[1]));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private:
|
|
210
|
+
size_t n_;
|
|
211
|
+
Digest root_;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
} // namespace proofs
|
|
215
|
+
|
|
216
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_MERKLE_MERKLE_TREE_H_
|