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,86 @@
|
|
|
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 "algebra/utility.h"
|
|
16
|
+
|
|
17
|
+
#include <stddef.h>
|
|
18
|
+
|
|
19
|
+
#include "algebra/bogorng.h"
|
|
20
|
+
#include "algebra/fp.h"
|
|
21
|
+
#include "gtest/gtest.h"
|
|
22
|
+
|
|
23
|
+
namespace proofs {
|
|
24
|
+
namespace {
|
|
25
|
+
using Field = Fp<4>;
|
|
26
|
+
using Elt = typename Field::Elt;
|
|
27
|
+
|
|
28
|
+
TEST(Utility, BatchInverse) {
|
|
29
|
+
const Field F(
|
|
30
|
+
"218882428718392752222464057452572750885483644004160343436982041865758084"
|
|
31
|
+
"95617");
|
|
32
|
+
Bogorng<Field> rng(&F);
|
|
33
|
+
|
|
34
|
+
constexpr size_t n = 133, da = 3, db = 5;
|
|
35
|
+
Elt a[n * da], b[n * db];
|
|
36
|
+
for (size_t i = 0; i < n; ++i) {
|
|
37
|
+
b[i * db] = rng.nonzero();
|
|
38
|
+
}
|
|
39
|
+
AlgebraUtil<Fp<4>>::batch_invert(n, a, da, b, db, F);
|
|
40
|
+
for (size_t i = 0; i < n; ++i) {
|
|
41
|
+
EXPECT_EQ(F.mulf(a[i * da], b[i * db]), F.one());
|
|
42
|
+
EXPECT_EQ(a[i * da], F.invertf(b[i * db]));
|
|
43
|
+
EXPECT_EQ(b[i * db], F.invertf(a[i * da]));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
// a[i] /= i!, without doing too many inversions
|
|
50
|
+
void scale_inverse_factorial(size_t n, Elt* a, const Field& F) {
|
|
51
|
+
auto p = F.one();
|
|
52
|
+
auto fi = F.one();
|
|
53
|
+
for (size_t i = 1; i < n; ++i) {
|
|
54
|
+
F.mul(p, fi);
|
|
55
|
+
F.add(fi, F.one());
|
|
56
|
+
}
|
|
57
|
+
// now p=(n-1)!, fi=of_scalar(n)
|
|
58
|
+
|
|
59
|
+
F.invert(p);
|
|
60
|
+
for (size_t i = n; i-- > 1;) {
|
|
61
|
+
F.mul(a[i], p);
|
|
62
|
+
F.sub(fi, F.one());
|
|
63
|
+
F.mul(p, fi);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
TEST(Utility, Factorial) {
|
|
68
|
+
constexpr size_t n = 37;
|
|
69
|
+
const Field F(
|
|
70
|
+
"218882428718392752222464057452572750885483644004160343436982041865758084"
|
|
71
|
+
"95617");
|
|
72
|
+
Bogorng<Field> rng(&F);
|
|
73
|
+
|
|
74
|
+
Elt A[n], B[n];
|
|
75
|
+
for (size_t i = 0; i < n; ++i) {
|
|
76
|
+
A[i] = B[i] = rng.next();
|
|
77
|
+
}
|
|
78
|
+
scale_inverse_factorial(n, A, F);
|
|
79
|
+
for (size_t i = 0; i < n; ++i) {
|
|
80
|
+
Elt fact = AlgebraUtil<Field>::factorial(i, F);
|
|
81
|
+
EXPECT_EQ(B[i], F.mulf(A[i], fact));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
} // namespace
|
|
86
|
+
} // namespace proofs
|
|
@@ -0,0 +1,56 @@
|
|
|
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_ARRAYS_AFFINE_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_ARRAYS_AFFINE_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
|
|
20
|
+
namespace proofs {
|
|
21
|
+
|
|
22
|
+
using corner_t = size_t;
|
|
23
|
+
|
|
24
|
+
// return r * f0 + (1-r) * f1 = f0 + r * (f1 - f0)
|
|
25
|
+
template <typename Field>
|
|
26
|
+
typename Field::Elt affine_interpolation(const typename Field::Elt& r,
|
|
27
|
+
typename Field::Elt f0,
|
|
28
|
+
typename Field::Elt f1,
|
|
29
|
+
const Field& F) {
|
|
30
|
+
F.sub(f1, f0);
|
|
31
|
+
F.mul(f1, r);
|
|
32
|
+
F.add(f0, f1);
|
|
33
|
+
return f0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// special case f0 = 0
|
|
37
|
+
template <typename Field>
|
|
38
|
+
typename Field::Elt affine_interpolation_z_nz(const typename Field::Elt& r,
|
|
39
|
+
typename Field::Elt f1,
|
|
40
|
+
const Field& F) {
|
|
41
|
+
F.mul(f1, r);
|
|
42
|
+
return f1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// special case f1 = 0
|
|
46
|
+
template <typename Field>
|
|
47
|
+
typename Field::Elt affine_interpolation_nz_z(const typename Field::Elt& r,
|
|
48
|
+
typename Field::Elt f0,
|
|
49
|
+
const Field& F) {
|
|
50
|
+
F.sub(f0, F.mulf(f0, r));
|
|
51
|
+
return f0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
} // namespace proofs
|
|
55
|
+
|
|
56
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_ARRAYS_AFFINE_H_
|
|
@@ -0,0 +1,220 @@
|
|
|
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 "arrays/affine.h"
|
|
16
|
+
|
|
17
|
+
#include <stddef.h>
|
|
18
|
+
#include <stdint.h>
|
|
19
|
+
|
|
20
|
+
#include <memory>
|
|
21
|
+
#include <vector>
|
|
22
|
+
|
|
23
|
+
#include "algebra/bogorng.h"
|
|
24
|
+
#include "algebra/fp.h"
|
|
25
|
+
#include "arrays/dense.h"
|
|
26
|
+
#include "arrays/sparse.h"
|
|
27
|
+
#include "gtest/gtest.h"
|
|
28
|
+
|
|
29
|
+
namespace proofs {
|
|
30
|
+
namespace {
|
|
31
|
+
using Field = Fp<4>;
|
|
32
|
+
static const Field F(
|
|
33
|
+
"21888242871839275222246405745257275088548364400416034343698204186575808495"
|
|
34
|
+
"617");
|
|
35
|
+
using Elt = typename Field::Elt;
|
|
36
|
+
using index_t = Sparse<Field>::index_t;
|
|
37
|
+
|
|
38
|
+
class RandomSlice {
|
|
39
|
+
public:
|
|
40
|
+
std::vector<Elt> r_;
|
|
41
|
+
explicit RandomSlice(size_t n) : r_(n) {
|
|
42
|
+
Bogorng<Field> rng(&F);
|
|
43
|
+
for (size_t i = 0; i < n; ++i) {
|
|
44
|
+
r_[i] = rng.next();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
Elt lagrange(corner_t p, size_t logn, const Elt* R) {
|
|
50
|
+
Elt l = F.one();
|
|
51
|
+
for (size_t i = 0; i < logn; i++) {
|
|
52
|
+
if ((p & (corner_t(1) << i)) != 0) {
|
|
53
|
+
F.mul(l, R[i]);
|
|
54
|
+
} else {
|
|
55
|
+
F.mul(l, F.subf(F.one(), R[i]));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return l;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void one_bind3D(corner_t n0, corner_t n1, corner_t n2, size_t logn0,
|
|
62
|
+
size_t logn1, size_t logn2) {
|
|
63
|
+
RandomSlice R0(logn0);
|
|
64
|
+
RandomSlice R1(logn1);
|
|
65
|
+
RandomSlice R2(logn2);
|
|
66
|
+
auto D = Dense<Field>(n0, n2 * n1);
|
|
67
|
+
auto S = Sparse<Field>(n2 * n1 * n0);
|
|
68
|
+
Bogorng<Field> rng(&F);
|
|
69
|
+
Elt s = F.zero();
|
|
70
|
+
index_t i = 0;
|
|
71
|
+
for (corner_t p2 = 0; p2 < n2; p2++) {
|
|
72
|
+
for (corner_t p1 = 0; p1 < n1; p1++) {
|
|
73
|
+
for (corner_t p0 = 0; p0 < n0; p0++) {
|
|
74
|
+
Elt v = rng.next();
|
|
75
|
+
D.v_[p2 * n1 * n0 + p1 * n0 + p0] = v;
|
|
76
|
+
S.c_[i] = Sparse<Field>::corner{.p0 = p0, .p1 = p1, .p2 = p2, .v = v};
|
|
77
|
+
i++;
|
|
78
|
+
|
|
79
|
+
F.add(s, F.mulf(v, F.mulf(lagrange(p2, logn2, R2.r_.data()),
|
|
80
|
+
F.mulf(lagrange(p1, logn1, R1.r_.data()),
|
|
81
|
+
lagrange(p0, logn0, R0.r_.data())))));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// evaluate S, D at R via successive binding
|
|
87
|
+
D.bind_all(logn0, R0.r_.data(), F);
|
|
88
|
+
S.bind_all(logn0, R0.r_.data(), F);
|
|
89
|
+
D.reshape(n1);
|
|
90
|
+
S.reshape();
|
|
91
|
+
|
|
92
|
+
D.bind_all(logn1, R1.r_.data(), F);
|
|
93
|
+
S.bind_all(logn1, R1.r_.data(), F);
|
|
94
|
+
D.reshape(n2);
|
|
95
|
+
S.reshape();
|
|
96
|
+
|
|
97
|
+
D.bind_all(logn2, R2.r_.data(), F);
|
|
98
|
+
S.bind_all(logn2, R2.r_.data(), F);
|
|
99
|
+
EXPECT_EQ(D.scalar(), s);
|
|
100
|
+
EXPECT_EQ(S.scalar(), s);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
void all_bind3D(corner_t n0, corner_t n1, corner_t n2, size_t logn0,
|
|
104
|
+
size_t logn1, size_t logn2) {
|
|
105
|
+
one_bind3D(n0, n1, n2, logn0, logn1, logn2);
|
|
106
|
+
one_bind3D(n1, n2, n0, logn1, logn2, logn0);
|
|
107
|
+
one_bind3D(n2, n0, n1, logn2, logn0, logn1);
|
|
108
|
+
one_bind3D(n2, n1, n0, logn2, logn1, logn0);
|
|
109
|
+
one_bind3D(n1, n0, n2, logn1, logn0, logn2);
|
|
110
|
+
one_bind3D(n0, n2, n1, logn0, logn2, logn1);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
void one_bind(corner_t n, size_t logn) {
|
|
114
|
+
one_bind3D(1, 1, n, 0, 0, logn);
|
|
115
|
+
one_bind3D(1, n, 1, 0, logn, 0);
|
|
116
|
+
one_bind3D(n, 1, 1, logn, 0, 0);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
TEST(Affine, Bind) {
|
|
120
|
+
one_bind(corner_t(666), 10);
|
|
121
|
+
one_bind(corner_t(1), 9);
|
|
122
|
+
one_bind(corner_t(255), 9);
|
|
123
|
+
one_bind(corner_t(256), 9);
|
|
124
|
+
one_bind(corner_t(257), 9);
|
|
125
|
+
one_bind(corner_t(467), 9);
|
|
126
|
+
one_bind(corner_t(512), 9);
|
|
127
|
+
|
|
128
|
+
all_bind3D(corner_t(7), corner_t(13), corner_t(19), 3, 4, 5);
|
|
129
|
+
all_bind3D(corner_t(8), corner_t(16), corner_t(32), 3, 4, 5);
|
|
130
|
+
all_bind3D(corner_t(8), corner_t(13), corner_t(19), 3, 4, 5);
|
|
131
|
+
all_bind3D(corner_t(8), corner_t(13), corner_t(32), 3, 4, 5);
|
|
132
|
+
all_bind3D(corner_t(13), corner_t(13), corner_t(32), 4, 4, 5);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
void one_sparse_bind(index_t n, size_t logn) {
|
|
136
|
+
RandomSlice R(logn);
|
|
137
|
+
RandomSlice R2(logn);
|
|
138
|
+
auto S = Sparse<Field>(n);
|
|
139
|
+
auto D = Dense<Field>(1 << logn, 1);
|
|
140
|
+
D.clear(F);
|
|
141
|
+
Bogorng<Field> rng(&F);
|
|
142
|
+
|
|
143
|
+
Elt s = F.zero();
|
|
144
|
+
Elt s2 = F.zero();
|
|
145
|
+
for (index_t i = 0; i < n; ++i) {
|
|
146
|
+
corner_t p = corner_t(13 * i);
|
|
147
|
+
Elt r = rng.next();
|
|
148
|
+
D.v_[p] = r;
|
|
149
|
+
S.c_[i] = Sparse<Field>::corner{.p0 = p, .v = r};
|
|
150
|
+
F.add(s, F.mulf(r, lagrange(p, logn, R.r_.data())));
|
|
151
|
+
F.add(s2, F.mulf(r, lagrange(p, logn, R2.r_.data())));
|
|
152
|
+
}
|
|
153
|
+
auto S1 = S.clone_testing_only();
|
|
154
|
+
auto SC = S.clone_testing_only();
|
|
155
|
+
auto DC = D.clone();
|
|
156
|
+
|
|
157
|
+
D.bind_all(logn, R.r_.data(), F);
|
|
158
|
+
S.bind_all(logn, R.r_.data(), F);
|
|
159
|
+
EXPECT_EQ(D.scalar(), s);
|
|
160
|
+
EXPECT_EQ(S.scalar(), s);
|
|
161
|
+
|
|
162
|
+
DC->bind_all(logn, R.r_.data(), F);
|
|
163
|
+
SC->bind_all(logn, R.r_.data(), F);
|
|
164
|
+
EXPECT_EQ(DC->scalar(), s);
|
|
165
|
+
EXPECT_EQ(SC->scalar(), s);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
TEST(Affine, SparseBind) {
|
|
169
|
+
one_sparse_bind(index_t(666), 10 + 4);
|
|
170
|
+
one_sparse_bind(index_t(1), 9 + 4);
|
|
171
|
+
for (size_t i = 200; i < 300; i++) {
|
|
172
|
+
one_sparse_bind(index_t(i), 9 + 4);
|
|
173
|
+
}
|
|
174
|
+
one_sparse_bind(index_t(467), 9 + 4);
|
|
175
|
+
one_sparse_bind(index_t(512), 9 + 4);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
TEST(Affine, Canonicalize) {
|
|
179
|
+
constexpr corner_t n0 = 31, n1 = 47, n2 = 128;
|
|
180
|
+
constexpr corner_t d0 = 2, d1 = 5, d2 = 17;
|
|
181
|
+
|
|
182
|
+
// array of expected sums
|
|
183
|
+
uint64_t expected[(n0 + d0 - 1) / d0][(n1 + d1 - 1) / d1]
|
|
184
|
+
[(n2 + d2 - 1) / d2] = {};
|
|
185
|
+
|
|
186
|
+
// create a n0 x n1 x n2 array in the "wrong" order, with duplicates
|
|
187
|
+
auto S = Sparse<Field>(n0 * n1 * n2);
|
|
188
|
+
|
|
189
|
+
index_t wr = 0;
|
|
190
|
+
for (corner_t p0 = 0; p0 < n0; p0++) {
|
|
191
|
+
for (corner_t p1 = 0; p1 < n1; p1++) {
|
|
192
|
+
for (corner_t p2 = 0; p2 < n2; p2++) {
|
|
193
|
+
uint64_t v = p0 + 171 * p1 + 333 * p2;
|
|
194
|
+
expected[p0 / d0][p1 / d1][p2 / d2] += v;
|
|
195
|
+
S.c_[wr] = Sparse<Field>::corner{.p0 = p0 / d0,
|
|
196
|
+
.p1 = p1 / d1,
|
|
197
|
+
.p2 = p2 / d2,
|
|
198
|
+
.v = F.of_scalar(v)};
|
|
199
|
+
wr++;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
S.canonicalize(F);
|
|
205
|
+
|
|
206
|
+
index_t rd = 0;
|
|
207
|
+
for (corner_t p2 = 0; p2 < (n2 + d2 - 1) / d2; p2++) {
|
|
208
|
+
for (corner_t p1 = 0; p1 < (n1 + d1 - 1) / d1; p1++) {
|
|
209
|
+
for (corner_t p0 = 0; p0 < (n0 + d0 - 1) / d0; p0++) {
|
|
210
|
+
Sparse<Field>::corner want = {
|
|
211
|
+
p0, p1, p2, F.of_scalar(expected[p0][p1][p2])};
|
|
212
|
+
EXPECT_EQ(want, S.c_[rd]);
|
|
213
|
+
rd++;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
EXPECT_EQ(S.n_, rd);
|
|
218
|
+
}
|
|
219
|
+
} // namespace
|
|
220
|
+
} // namespace proofs
|
|
@@ -0,0 +1,210 @@
|
|
|
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_ARRAYS_DENSE_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_ARRAYS_DENSE_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
#include <string.h>
|
|
20
|
+
|
|
21
|
+
#include <array>
|
|
22
|
+
#include <cstdint>
|
|
23
|
+
#include <memory>
|
|
24
|
+
#include <vector>
|
|
25
|
+
|
|
26
|
+
#include "algebra/blas.h"
|
|
27
|
+
#include "algebra/poly.h"
|
|
28
|
+
#include "arrays/affine.h"
|
|
29
|
+
#include "util/panic.h"
|
|
30
|
+
|
|
31
|
+
namespace proofs {
|
|
32
|
+
// ------------------------------------------------------------
|
|
33
|
+
// Dense representation of multi-affine function, heap-allocated.
|
|
34
|
+
// The caller is responsible for instantiating const Field throughout call
|
|
35
|
+
// duration.
|
|
36
|
+
template <class Field>
|
|
37
|
+
class Dense {
|
|
38
|
+
using T2 = Poly<2, Field>;
|
|
39
|
+
using Elt = typename Field::Elt;
|
|
40
|
+
|
|
41
|
+
public:
|
|
42
|
+
corner_t n0_, n1_;
|
|
43
|
+
|
|
44
|
+
// Row-major indexing: v_[i1*n0+i0] stores the value at (i0, i1)
|
|
45
|
+
std::vector<Elt> v_;
|
|
46
|
+
|
|
47
|
+
explicit Dense(corner_t n0, corner_t n1) : n0_(n0), n1_(n1), v_(n0 * n1) {}
|
|
48
|
+
|
|
49
|
+
// make0 replacement
|
|
50
|
+
explicit Dense(const Field& F) : n0_(1), n1_(1), v_(1) { v_[0] = F.zero(); }
|
|
51
|
+
|
|
52
|
+
// initialize dense array from P[i1*ldp+i0]
|
|
53
|
+
explicit Dense(corner_t n0, corner_t n1, const Elt p[], size_t ldp)
|
|
54
|
+
: n0_(n0), n1_(n1), v_(n0 * n1) {
|
|
55
|
+
for (corner_t i1 = 0; i1 < n1; ++i1) {
|
|
56
|
+
Blas<Field>::copy(n0, v_[i1 * n0], 1, &p[i1 * ldp], 1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
Dense(const Dense& y) = delete;
|
|
61
|
+
Dense(const Dense&& y) = delete;
|
|
62
|
+
Dense operator=(const Dense& y) = delete;
|
|
63
|
+
|
|
64
|
+
std::unique_ptr<Dense> clone() const {
|
|
65
|
+
auto d = std::make_unique<Dense>(n0_, n1_);
|
|
66
|
+
for (corner_t i = 0; i < n0_ * n1_; ++i) {
|
|
67
|
+
d->v_[i] = v_[i];
|
|
68
|
+
}
|
|
69
|
+
return d;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
void clear(const Field& F) { Blas<Field>::clear(n0_ * n1_, &v_[0], 1, F); }
|
|
73
|
+
|
|
74
|
+
// For a given random number r, the binding operation computes
|
|
75
|
+
// this[i] = (1 - r) * in[2 * i] + r * in[2 * i + 1]
|
|
76
|
+
// = in[2 * i] + r * (in[2 * i + 1] - in[2 * i])
|
|
77
|
+
// This method works even in-place, i.e., if &in == this.
|
|
78
|
+
void bind(const Elt& r, const Dense& in, const Field& F) {
|
|
79
|
+
const corner_t n0_out = (in.n0_ + 1u) / 2u;
|
|
80
|
+
check(n1_ == in.n1_, "n1_ == in.n1_");
|
|
81
|
+
check(n0_ >= n0_out, "n0_ >= n0_out");
|
|
82
|
+
corner_t rd = 0, wr = 0;
|
|
83
|
+
for (corner_t i1 = 0; i1 < n1_; ++i1) {
|
|
84
|
+
corner_t i0 = 0;
|
|
85
|
+
while (2 * i0 + 1 < in.n0_) {
|
|
86
|
+
v_[wr] = affine_interpolation(r, in.v_[rd], in.v_[rd + 1], F);
|
|
87
|
+
i0++, rd += 2, wr += 1;
|
|
88
|
+
}
|
|
89
|
+
if (2 * i0 < in.n0_) {
|
|
90
|
+
v_[wr] = affine_interpolation_nz_z(r, in.v_[rd], F);
|
|
91
|
+
i0++, rd++, wr++;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
n0_ = n0_out;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
void bind(const Elt& r, const Field& F) { bind(r, *this, F); }
|
|
98
|
+
|
|
99
|
+
void bind_all(size_t logv, const Elt r[/*logv*/], const Field& F) {
|
|
100
|
+
for (size_t v = 0; v < logv; ++v) {
|
|
101
|
+
bind(r[v], F);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
Elt at(corner_t j) const { return v_[j]; }
|
|
106
|
+
|
|
107
|
+
// Scale all elements by x, except for the last element in
|
|
108
|
+
// the n0_ dimension, which is scaled by x_last. This "last" quirk
|
|
109
|
+
// is used by EQ.
|
|
110
|
+
void scale(const Elt& x, const Elt& x_last, const Field& F) {
|
|
111
|
+
corner_t ndx = 0;
|
|
112
|
+
for (corner_t i1 = 0; i1 < n1_; ++i1) {
|
|
113
|
+
corner_t i0 = 0;
|
|
114
|
+
for (; i0 + 1 < n0_; ++i0) {
|
|
115
|
+
F.mul(v_[ndx++], x);
|
|
116
|
+
}
|
|
117
|
+
if (i0 < n0_) {
|
|
118
|
+
F.mul(v_[ndx++], x_last);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
Elt at_corners(corner_t p0, corner_t p1, const Field& F) const {
|
|
124
|
+
if (p0 < n0_) {
|
|
125
|
+
return v_[p1 * n0_ + p0];
|
|
126
|
+
} else {
|
|
127
|
+
return F.zero();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
T2 t2_at_corners(corner_t p0, corner_t p1, const Field& F) const {
|
|
132
|
+
return T2{at_corners(p0, p1, F), at_corners(p0 + 1, p1, F)};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// The precondition for reshaping is that the first dimension must be
|
|
136
|
+
// fully bound.
|
|
137
|
+
void reshape(corner_t n0) {
|
|
138
|
+
check(n0_ == 1, "n0_ == 1");
|
|
139
|
+
check(n0 > 0, "n0 > 0");
|
|
140
|
+
corner_t wasn1 = n1_;
|
|
141
|
+
n0_ = n0;
|
|
142
|
+
n1_ = n1_ / n0;
|
|
143
|
+
check(n1_ * n0 == wasn1, "n1_*n0 == wasn1");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// This method can only be called after full binding; the caller
|
|
147
|
+
// is responsible for ensuring that pre-condition.
|
|
148
|
+
Elt scalar() {
|
|
149
|
+
check(n0_ == 1, "n0_ == 1");
|
|
150
|
+
check(n1_ == 1, "n1_ == 1");
|
|
151
|
+
return v_[0];
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// Helper class to fill a dense array a la std::vector<>
|
|
156
|
+
//
|
|
157
|
+
template <class Field>
|
|
158
|
+
class DenseFiller {
|
|
159
|
+
using Elt = typename Field::Elt;
|
|
160
|
+
using CElt = typename Field::CElt;
|
|
161
|
+
|
|
162
|
+
public:
|
|
163
|
+
// Caller must ensure that W remains valid.
|
|
164
|
+
explicit DenseFiller(Dense<Field>& W) : pos_(0), w_(W) {
|
|
165
|
+
// only works in this special case
|
|
166
|
+
check(w_.n0_ == 1, "W_.n0_ == 1");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
DenseFiller& push_back(const Elt& x) {
|
|
170
|
+
check(pos_ < w_.n1_, "pos_ < w_.n1_");
|
|
171
|
+
w_.v_[pos_++] = x;
|
|
172
|
+
return *this;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
DenseFiller& push_back(const CElt& x) { return push_back(x.e); }
|
|
176
|
+
|
|
177
|
+
template <size_t N>
|
|
178
|
+
DenseFiller& push_back(const std::array<Elt, N>& a) {
|
|
179
|
+
for (size_t i = 0; i < N; ++i) {
|
|
180
|
+
push_back(a[i]);
|
|
181
|
+
}
|
|
182
|
+
return *this;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
DenseFiller& push_back(const std::vector<Elt>& a) {
|
|
186
|
+
for (size_t i = 0; i < a.size(); ++i) {
|
|
187
|
+
push_back(a[i]);
|
|
188
|
+
}
|
|
189
|
+
return *this;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Push back a bit string derived from a number. The parameter "bits" is the
|
|
193
|
+
// number of bits in the string, and "x" is the number to be converted. This
|
|
194
|
+
// works for pushing v8, v32, etc.
|
|
195
|
+
DenseFiller& push_back(uint64_t x, size_t bits, const Field& F) {
|
|
196
|
+
for (size_t i = 0; i < bits; ++i) {
|
|
197
|
+
push_back(F.of_scalar((x >> i) & 1));
|
|
198
|
+
}
|
|
199
|
+
return *this;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
size_t size() const { return pos_; }
|
|
203
|
+
|
|
204
|
+
private:
|
|
205
|
+
size_t pos_;
|
|
206
|
+
Dense<Field>& w_;
|
|
207
|
+
};
|
|
208
|
+
} // namespace proofs
|
|
209
|
+
|
|
210
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_ARRAYS_DENSE_H_
|
|
@@ -0,0 +1,75 @@
|
|
|
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_ARRAYS_EQ_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_ARRAYS_EQ_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
|
|
20
|
+
#include "arrays/affine.h"
|
|
21
|
+
|
|
22
|
+
namespace proofs {
|
|
23
|
+
template <class Field>
|
|
24
|
+
// EQ[i,j] is 2D sparse array EQ[i, j] = (i == j).
|
|
25
|
+
// This class contains a state-free version of EQ, which
|
|
26
|
+
// evaluates EQ[i, j] on the fly. See Eqs for a stateful
|
|
27
|
+
// version that stores all the values of EQ[I, j] for fixed I
|
|
28
|
+
// and variable j.
|
|
29
|
+
class Eq {
|
|
30
|
+
using Elt = typename Field::Elt;
|
|
31
|
+
|
|
32
|
+
public:
|
|
33
|
+
/*
|
|
34
|
+
Bind EQ{logn,n} at I, J.
|
|
35
|
+
|
|
36
|
+
We consider the diagonal matrix EQ[i,j] to be composed of
|
|
37
|
+
N-1 diagonal elements A and one last diagonal element B, i.e.,
|
|
38
|
+
EQ=diag([A A A A ... B]). We bind one I variable and one J
|
|
39
|
+
variable in one step, yielding a matrix of the same form
|
|
40
|
+
with ceil(n/2) diagonal entries.
|
|
41
|
+
|
|
42
|
+
Let I1J1=I[0]*J[0] and I0J0=(1-I[0])*(1-J[0]).
|
|
43
|
+
|
|
44
|
+
Binding A is equivalent to binding the 2x2 block [A 0; 0 A],
|
|
45
|
+
yielding A <- A*(I0J0+I1J1).
|
|
46
|
+
|
|
47
|
+
If n is even, then the last 2x2 block is [A 0; 0 B], whose binding
|
|
48
|
+
yields B <- A*I0J0 + B*I1J1.
|
|
49
|
+
|
|
50
|
+
If n is odd, then the last 2x2 block is [B 0; 0 0], whose binding
|
|
51
|
+
yields B <- B*I0J0.
|
|
52
|
+
*/
|
|
53
|
+
static Elt eval(size_t logn, corner_t n, const Elt I[/*logn*/],
|
|
54
|
+
const Elt J[/*logn*/], const Field& F) {
|
|
55
|
+
Elt a = F.one(), b = F.one();
|
|
56
|
+
for (size_t round = 0; round < logn; round++) {
|
|
57
|
+
Elt i1 = I[round], j1 = J[round];
|
|
58
|
+
Elt i0 = F.subf(F.one(), i1), j0 = F.subf(F.one(), j1);
|
|
59
|
+
Elt i0j0 = F.mulf(i0, j0);
|
|
60
|
+
Elt i1j1 = F.mulf(i1, j1);
|
|
61
|
+
if ((n & 1) == 0) {
|
|
62
|
+
F.mul(b, i1j1);
|
|
63
|
+
F.add(b, F.mulf(a, i0j0));
|
|
64
|
+
} else {
|
|
65
|
+
F.mul(b, i0j0);
|
|
66
|
+
}
|
|
67
|
+
F.mul(a, F.addf(i0j0, i1j1));
|
|
68
|
+
n = (n + 1) / 2;
|
|
69
|
+
}
|
|
70
|
+
return b;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
} // namespace proofs
|
|
74
|
+
|
|
75
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_ARRAYS_EQ_H_
|