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,201 @@
|
|
|
1
|
+
// Copyright 2026 Google LLC.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
#ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_ECDSA_VERIFY_WITNESS_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_ECDSA_VERIFY_WITNESS_H_
|
|
17
|
+
|
|
18
|
+
#include <cstddef>
|
|
19
|
+
|
|
20
|
+
#include "algebra/utility.h"
|
|
21
|
+
#include "arrays/dense.h"
|
|
22
|
+
#include "util/panic.h"
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
Methods to help prepare witnesses for use in assertions about ecdsa.
|
|
26
|
+
*/
|
|
27
|
+
namespace proofs {
|
|
28
|
+
|
|
29
|
+
template <class EC, class ScalarField>
|
|
30
|
+
class VerifyWitness3 {
|
|
31
|
+
using Field = typename EC::Field;
|
|
32
|
+
using Elt = typename Field::Elt;
|
|
33
|
+
using Nat = typename Field::N;
|
|
34
|
+
using Point = typename EC::ECPoint;
|
|
35
|
+
using Scalar = typename ScalarField::Elt;
|
|
36
|
+
|
|
37
|
+
public:
|
|
38
|
+
constexpr static size_t kBits = EC::kBits;
|
|
39
|
+
const ScalarField& fn_;
|
|
40
|
+
const EC& ec_;
|
|
41
|
+
Elt rx_, ry_;
|
|
42
|
+
Elt rx_inv_;
|
|
43
|
+
Elt s_inv_;
|
|
44
|
+
Elt pk_inv_;
|
|
45
|
+
Elt pre_[8];
|
|
46
|
+
Elt bi_[kBits];
|
|
47
|
+
Elt int_x_[kBits]; /* Intermediate x,y elliptic curve points */
|
|
48
|
+
Elt int_y_[kBits]; /* encountered during the scalar mult loop. */
|
|
49
|
+
Elt int_z_[kBits]; /* z-coordinate of the intermediate points */
|
|
50
|
+
|
|
51
|
+
VerifyWitness3(const ScalarField& Fn, const EC& ec) : fn_(Fn), ec_(ec) {}
|
|
52
|
+
|
|
53
|
+
void fill_witness(DenseFiller<Field>& filler) const {
|
|
54
|
+
filler.push_back(rx_);
|
|
55
|
+
filler.push_back(ry_);
|
|
56
|
+
filler.push_back(rx_inv_);
|
|
57
|
+
filler.push_back(s_inv_);
|
|
58
|
+
filler.push_back(pk_inv_);
|
|
59
|
+
for (size_t i = 0; i < 8; ++i) {
|
|
60
|
+
filler.push_back(pre_[i]);
|
|
61
|
+
}
|
|
62
|
+
for (size_t i = 0; i < kBits; ++i) {
|
|
63
|
+
filler.push_back(bi_[i]);
|
|
64
|
+
if (i < kBits - 1) {
|
|
65
|
+
filler.push_back(int_x_[i]);
|
|
66
|
+
filler.push_back(int_y_[i]);
|
|
67
|
+
filler.push_back(int_z_[i]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Produces witnesses to support the verification of the equation
|
|
73
|
+
// id = g*e + pk*r + (rx,ry)*-s
|
|
74
|
+
// Note that the same rx is interpreted in scalar field as r.
|
|
75
|
+
bool compute_witness(const Elt pkX, const Elt pkY, const Nat e, const Nat r,
|
|
76
|
+
const Nat s) {
|
|
77
|
+
const Field& F = ec_.f_;
|
|
78
|
+
const Scalar _s = fn_.invertf(fn_.to_montgomery(s));
|
|
79
|
+
const Scalar tms = fn_.negf(fn_.to_montgomery(s));
|
|
80
|
+
|
|
81
|
+
// Because Fp does not have a sqrt method, compute ry via the
|
|
82
|
+
// elliptic curve point g*(e/s) + pk*(r/s).
|
|
83
|
+
auto te_s = fn_.mulf(fn_.to_montgomery(e), _s);
|
|
84
|
+
auto tr_s = fn_.mulf(fn_.to_montgomery(r), _s);
|
|
85
|
+
const Nat nes = fn_.from_montgomery(te_s);
|
|
86
|
+
const Nat nrs = fn_.from_montgomery(tr_s);
|
|
87
|
+
Point bases[] = {ec_.generator(), Point(pkX, pkY, F.one())};
|
|
88
|
+
Nat scalars[] = {nes, nrs};
|
|
89
|
+
auto pr = ec_.scalar_multf(2, bases, scalars);
|
|
90
|
+
ec_.normalize(pr);
|
|
91
|
+
|
|
92
|
+
rx_ = F.to_montgomery(r);
|
|
93
|
+
ry_ = pr.y;
|
|
94
|
+
|
|
95
|
+
// In the case of a malicious input with rx=0 or s=0, the proof will fail.
|
|
96
|
+
if (rx_ != F.zero()) {
|
|
97
|
+
rx_inv_ = F.invertf(rx_);
|
|
98
|
+
check(F.mulf(rx_, rx_inv_) == F.one(), "bad inv");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
s_inv_ = F.to_montgomery(fn_.from_montgomery(tms));
|
|
102
|
+
if (s_inv_ != F.zero()) {
|
|
103
|
+
F.invert(s_inv_);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (pkX != F.zero()) {
|
|
107
|
+
pk_inv_ = F.invertf(pkX);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const Nat nms = fn_.from_montgomery(tms); /* -s */
|
|
111
|
+
|
|
112
|
+
// Produce the table of pre-computed g,r,pk sums.
|
|
113
|
+
const Elt one = F.one(), gX = ec_.gx_, gY = ec_.gy_;
|
|
114
|
+
const Elt lh[] = {gX, gY, gX, gY, pkX, pkY};
|
|
115
|
+
const Elt rh[] = {pkX, pkY, rx_, ry_, rx_, ry_};
|
|
116
|
+
Elt zi;
|
|
117
|
+
for (size_t i = 0; i < 3; ++i) {
|
|
118
|
+
ec_.addE(pre_[2 * i], pre_[2 * i + 1], zi,
|
|
119
|
+
lh[2 * i], lh[2 * i + 1], one,
|
|
120
|
+
rh[2 * i], rh[2 * i + 1], one);
|
|
121
|
+
|
|
122
|
+
// This invert cannot fail because both the generator and pk are
|
|
123
|
+
// trusted inputs, so the above addition is not the identity.
|
|
124
|
+
// In the case that it is, the proof will fail (and it should, since
|
|
125
|
+
// the system is unsound with sk=-1).
|
|
126
|
+
if (zi != F.zero()) {
|
|
127
|
+
F.invert(zi);
|
|
128
|
+
}
|
|
129
|
+
F.mul(pre_[2 * i], zi);
|
|
130
|
+
F.mul(pre_[2 * i + 1], zi);
|
|
131
|
+
}
|
|
132
|
+
// rgpk
|
|
133
|
+
ec_.addE(pre_[6], pre_[7], zi, pre_[2], pre_[3], one, pkX, pkY, one);
|
|
134
|
+
if (zi != F.zero()) {
|
|
135
|
+
F.invert(zi);
|
|
136
|
+
}
|
|
137
|
+
F.mul(pre_[6], zi);
|
|
138
|
+
F.mul(pre_[7], zi);
|
|
139
|
+
|
|
140
|
+
Elt aX = F.zero(), aY = one, aZ = F.zero();
|
|
141
|
+
|
|
142
|
+
// Compute b[], and intermediate points, encode b as:
|
|
143
|
+
// 1:g 2:pk 3: gpk 4: r 5: r+g 6: r+pk 7:g+r+pk
|
|
144
|
+
// Elt int_z[kBits];
|
|
145
|
+
size_t b[kBits];
|
|
146
|
+
// bool early_zero = false; /* indicates if any intermediate z is zero */
|
|
147
|
+
for (size_t i = 0; i < kBits; ++i) {
|
|
148
|
+
b[i] = e.bit(kBits - i - 1) + 2 * r.bit(kBits - i - 1) +
|
|
149
|
+
4 * nms.bit(kBits - i - 1);
|
|
150
|
+
|
|
151
|
+
// Manually compute standard (-n...n representation).
|
|
152
|
+
bi_[i] = F.subf(F.of_scalar(2 * b[i]), F.of_scalar(7));
|
|
153
|
+
|
|
154
|
+
if (i > 0) {
|
|
155
|
+
ec_.doubleE(aX, aY, aZ, aX, aY, aZ);
|
|
156
|
+
}
|
|
157
|
+
switch (b[i]) {
|
|
158
|
+
case 0:
|
|
159
|
+
ec_.addE(aX, aY, aZ, aX, aY, aZ, F.zero(), F.one(), F.zero());
|
|
160
|
+
break;
|
|
161
|
+
case 1:
|
|
162
|
+
ec_.addE(aX, aY, aZ, aX, aY, aZ, gX, gY, one);
|
|
163
|
+
break;
|
|
164
|
+
case 2:
|
|
165
|
+
ec_.addE(aX, aY, aZ, aX, aY, aZ, pkX, pkY, one);
|
|
166
|
+
break;
|
|
167
|
+
case 3:
|
|
168
|
+
ec_.addE(aX, aY, aZ, aX, aY, aZ, pre_[0], pre_[1], one);
|
|
169
|
+
break;
|
|
170
|
+
case 4:
|
|
171
|
+
ec_.addE(aX, aY, aZ, aX, aY, aZ, rx_, ry_, one);
|
|
172
|
+
break;
|
|
173
|
+
case 5:
|
|
174
|
+
ec_.addE(aX, aY, aZ, aX, aY, aZ, pre_[2], pre_[3], one);
|
|
175
|
+
break;
|
|
176
|
+
case 6:
|
|
177
|
+
ec_.addE(aX, aY, aZ, aX, aY, aZ, pre_[4], pre_[5], one);
|
|
178
|
+
break;
|
|
179
|
+
case 7:
|
|
180
|
+
ec_.addE(aX, aY, aZ, aX, aY, aZ, pre_[6], pre_[7], one);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
int_x_[i] = aX;
|
|
185
|
+
int_y_[i] = aY;
|
|
186
|
+
int_z_[i] = aZ;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (aX != F.zero()) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
if (aZ != F.zero()) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
} // namespace proofs
|
|
200
|
+
|
|
201
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_ECDSA_VERIFY_WITNESS_H_
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// Copyright 2026 Google LLC.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
#ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_ADDER_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_ADDER_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <initializer_list>
|
|
22
|
+
#include <vector>
|
|
23
|
+
|
|
24
|
+
// Circuit element that maps bitvec<N> V to a field element E
|
|
25
|
+
// in such a way that:
|
|
26
|
+
//
|
|
27
|
+
// 1) addition can be performed efficiently, e.g. as field
|
|
28
|
+
// addition or field multiplication
|
|
29
|
+
// 2) given and E that is the sum of K bitvecs, a simple circuit
|
|
30
|
+
// asserts that E = A mod 2^N
|
|
31
|
+
namespace proofs {
|
|
32
|
+
|
|
33
|
+
template <class Logic, size_t N, bool kCharacteristicTwo>
|
|
34
|
+
class BitAdderAux;
|
|
35
|
+
|
|
36
|
+
// Use the additive group in fields with large characteristic
|
|
37
|
+
template <class Logic, size_t N>
|
|
38
|
+
class BitAdderAux<Logic, N, /*kCharacteristicTwo=*/false> {
|
|
39
|
+
public:
|
|
40
|
+
using Field = typename Logic::Field;
|
|
41
|
+
using BitW = typename Logic::BitW;
|
|
42
|
+
using EltW = typename Logic::EltW;
|
|
43
|
+
using Elt = typename Field::Elt;
|
|
44
|
+
using BV = typename Logic::template bitvec<N>;
|
|
45
|
+
const Logic& l_;
|
|
46
|
+
|
|
47
|
+
explicit BitAdderAux(const Logic& l) : l_(l) {}
|
|
48
|
+
|
|
49
|
+
EltW as_field_element(const BV& v) const {
|
|
50
|
+
constexpr uint64_t uno = 1;
|
|
51
|
+
EltW r = l_.konst(l_.zero());
|
|
52
|
+
for (size_t i = 0; i < N; ++i) {
|
|
53
|
+
r = l_.axpy(r, l_.elt(uno << i), l_.eval(v[i]));
|
|
54
|
+
}
|
|
55
|
+
return r;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
EltW add(const EltW& a, const EltW& b) const { return l_.add(a, b); }
|
|
59
|
+
EltW add(const BV& a, const BV& b) const {
|
|
60
|
+
return add(as_field_element(a), as_field_element(b));
|
|
61
|
+
}
|
|
62
|
+
EltW add(
|
|
63
|
+
std::initializer_list<typename Logic::template bitvec_view<N>> a) const {
|
|
64
|
+
return l_.add(0, a.size(), [&](size_t i) {
|
|
65
|
+
return as_field_element(*(a.begin()[i].ptr));
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// assert that B = A + i*2^N for 0 <= i < k
|
|
70
|
+
void assert_eqmod(const BV& a, const EltW& b, size_t k) const {
|
|
71
|
+
constexpr uint64_t uno = 1;
|
|
72
|
+
EltW z = l_.sub(b, as_field_element(a));
|
|
73
|
+
EltW zz = l_.mul(
|
|
74
|
+
0, k, [&](size_t i) { return l_.sub(z, l_.konst((uno << N) * i)); });
|
|
75
|
+
l_.assert0(zz);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Use the multiplicative group in GF(2^k)
|
|
80
|
+
template <class Logic, size_t N>
|
|
81
|
+
class BitAdderAux<Logic, N, /*kCharacteristicTwo=*/true> {
|
|
82
|
+
public:
|
|
83
|
+
using Field = typename Logic::Field;
|
|
84
|
+
using BitW = typename Logic::BitW;
|
|
85
|
+
using EltW = typename Logic::EltW;
|
|
86
|
+
using Elt = typename Field::Elt;
|
|
87
|
+
using BV = typename Logic::template bitvec<N>;
|
|
88
|
+
const Logic& l_;
|
|
89
|
+
|
|
90
|
+
explicit BitAdderAux(const Logic& l) : l_(l) {
|
|
91
|
+
// assume that X is a root of unity of order large enough.
|
|
92
|
+
Elt alpha = l_.f_.x();
|
|
93
|
+
|
|
94
|
+
for (size_t i = 0; i < N; ++i) {
|
|
95
|
+
alpha_2_i_[i] = alpha;
|
|
96
|
+
alpha = l_.mulf(alpha, alpha);
|
|
97
|
+
}
|
|
98
|
+
alpha_2_n_ = alpha;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
EltW as_field_element(const BV& v) const {
|
|
102
|
+
return l_.mul(0, N, [&](size_t i) {
|
|
103
|
+
return l_.mux(v[i], l_.konst(alpha_2_i_[i]), l_.konst(l_.one()));
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
EltW add(const EltW& a, const EltW& b) const { return l_.mul(a, b); }
|
|
108
|
+
EltW add(const BV& a, const BV& b) const {
|
|
109
|
+
return add(as_field_element(a), as_field_element(b));
|
|
110
|
+
}
|
|
111
|
+
EltW add(
|
|
112
|
+
std::initializer_list<typename Logic::template bitvec_view<N>> a) const {
|
|
113
|
+
return l_.mul(0, a.size(), [&](size_t i) {
|
|
114
|
+
return as_field_element(*(a.begin()[i].ptr));
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// assert that B = A + alpha^(i*2^N) for 0 <= i < k
|
|
119
|
+
void assert_eqmod(const BV& a, const EltW& b, size_t k) const {
|
|
120
|
+
std::vector<Elt> p(k);
|
|
121
|
+
p[0] = l_.f_.one();
|
|
122
|
+
for (size_t i = 1; i < k; ++i) {
|
|
123
|
+
p[i] = l_.f_.mulf(alpha_2_n_, p[i - 1]);
|
|
124
|
+
}
|
|
125
|
+
EltW aa = as_field_element(a);
|
|
126
|
+
EltW prod = l_.mul(
|
|
127
|
+
0, k, [&](size_t i) { return l_.sub(b, l_.mul(l_.konst(p[i]), aa)); });
|
|
128
|
+
l_.assert0(prod);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private:
|
|
132
|
+
Elt alpha_2_i_[N + 1];
|
|
133
|
+
Elt alpha_2_n_;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
template <class Logic, size_t N>
|
|
137
|
+
using BitAdder = BitAdderAux<Logic, N, Logic::Field::kCharacteristicTwo>;
|
|
138
|
+
} // namespace proofs
|
|
139
|
+
|
|
140
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_ADDER_H_
|
|
@@ -0,0 +1,64 @@
|
|
|
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/logic/bit_adder.h"
|
|
16
|
+
|
|
17
|
+
#include <stddef.h>
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
#include "algebra/fp_p128.h"
|
|
21
|
+
#include "circuits/logic/evaluation_backend.h"
|
|
22
|
+
#include "circuits/logic/logic.h"
|
|
23
|
+
#include "gf2k/gf2_128.h"
|
|
24
|
+
#include "gtest/gtest.h"
|
|
25
|
+
|
|
26
|
+
namespace proofs {
|
|
27
|
+
namespace {
|
|
28
|
+
|
|
29
|
+
template <class Field>
|
|
30
|
+
void test_bit_adder() {
|
|
31
|
+
constexpr size_t w = 4;
|
|
32
|
+
constexpr size_t mask = (1 << w) - 1;
|
|
33
|
+
const Field F;
|
|
34
|
+
|
|
35
|
+
using EvalBackend = EvaluationBackend<Field>;
|
|
36
|
+
using Logic = Logic<Field, EvalBackend>;
|
|
37
|
+
using BV = typename Logic::template bitvec<w>;
|
|
38
|
+
for (size_t a = 0; a < (1 << w); ++a) {
|
|
39
|
+
for (size_t b = 0; b < (1 << w); ++b) {
|
|
40
|
+
for (size_t c = 0; c < (1 << w); ++c) {
|
|
41
|
+
for (size_t s = 0; s < (1 << w); ++s) {
|
|
42
|
+
const EvalBackend ebk(F, /* panic_on_assertion_failure=*/false);
|
|
43
|
+
const Logic L(&ebk, F);
|
|
44
|
+
BV ea = L.template vbit<w>(a);
|
|
45
|
+
BV eb = L.template vbit<w>(b);
|
|
46
|
+
BV ec = L.template vbit<w>(c);
|
|
47
|
+
BV es = L.template vbit<w>(s);
|
|
48
|
+
|
|
49
|
+
BitAdder<Logic, w> BA(L);
|
|
50
|
+
BA.assert_eqmod(es, BA.add({ea, eb, ec}), 3);
|
|
51
|
+
EXPECT_EQ(ebk.assertion_failed(), (((a + b + c) ^ s) & mask) != 0);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
TEST(BitAdder, Fields) {
|
|
59
|
+
test_bit_adder<GF2_128<>>();
|
|
60
|
+
test_bit_adder<Fp128<>>();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
} // namespace
|
|
64
|
+
} // namespace proofs
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
// Copyright 2026 Google LLC.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
#ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
|
|
20
|
+
#include <array>
|
|
21
|
+
#include <vector>
|
|
22
|
+
|
|
23
|
+
#include "algebra/interpolation.h"
|
|
24
|
+
#include "algebra/poly.h"
|
|
25
|
+
#include "circuits/logic/bit_plucker_constants.h"
|
|
26
|
+
#include "circuits/logic/polynomial.h"
|
|
27
|
+
|
|
28
|
+
namespace proofs {
|
|
29
|
+
/*
|
|
30
|
+
|
|
31
|
+
Many circuits we design require bit inputs in {0,1} when the field F takes 128+
|
|
32
|
+
bits to represent. Each input to a circuit is an element in F, and must either
|
|
33
|
+
be sent to the verifier or committed, and thus sending several single-bit
|
|
34
|
+
inputs represents an overhead.
|
|
35
|
+
|
|
36
|
+
A bit-plucker is a circuit component that maps a set
|
|
37
|
+
S \subset F of size 2^k into k wires, b_0, ..., b_k-1, that are each in {0,1}.
|
|
38
|
+
Thus, it can reduce the number of inputs that a predicate circuit requires, and
|
|
39
|
+
thus makes the proof smaller or more efficient to compute or verify.
|
|
40
|
+
|
|
41
|
+
The optimal bit-plucker for k bits depends on k. For small k, the simplest
|
|
42
|
+
bit plucker is sufficient. In some cases, bit pluckers can exploit the field
|
|
43
|
+
structure.
|
|
44
|
+
|
|
45
|
+
[ RUN ] BitPlucker.PluckSize
|
|
46
|
+
pluck[1]: depth: 3 wires: 6 in: 2 out:2 use:4 ovh:2 t:6 cse:0 notn:9
|
|
47
|
+
pluck[2]: depth: 4 wires: 14 in: 2 out:4 use:9 ovh:5 t:18 cse:5
|
|
48
|
+
notn:19
|
|
49
|
+
pluck[3]: depth: 5 wires: 25 in: 2 out:6 use:17 ovh:8 t:38 cse:23
|
|
50
|
+
notn:40
|
|
51
|
+
pluck[4]: depth: 6 wires: 40 in: 2 out:8 use:29 ovh:11 t:74 cse:73
|
|
52
|
+
notn:87
|
|
53
|
+
pluck[5]: depth: 7 wires: 61 in: 2 out:10 use:47 ovh:14 t:144 cse:199
|
|
54
|
+
notn:194
|
|
55
|
+
pluck[6]: depth: 8 wires: 92 in: 2 out:12 use:75 ovh:17 t:288 cse:501
|
|
56
|
+
notn:437
|
|
57
|
+
pluck[7]: depth: 9 wires: 141 in: 2 out:14 use:121 ovh:20 t:594
|
|
58
|
+
cse:1203 notn:984
|
|
59
|
+
pluck[8]: depth: 10 wires: 224 in: 2 out:16 use:201 ovh:23 t:1254
|
|
60
|
+
cse:2801 notn:2203
|
|
61
|
+
|
|
62
|
+
Our experiments also considered an O(N)-wires, O(N)-terms bit plucker.
|
|
63
|
+
To pluck a LOGN-bit quantity E, write E = N0*E1 + E0 where E0 is a
|
|
64
|
+
LOGN0-bit quantity and where E1 is a LOGN1-bit quantity, and where
|
|
65
|
+
LOGN0 = ceil(LOGN/2), LOGN1 = floor(LOGN/2). This decomposition
|
|
66
|
+
can be computed by interpolating two Polynomials of length N. Now
|
|
67
|
+
we are left with plucking two quantities E0, E1, which can be done
|
|
68
|
+
by any subquadratic-time plucker.
|
|
69
|
+
|
|
70
|
+
A similar idea for the LOGN -> N binary decoder is in Knuth 7.1.2
|
|
71
|
+
Exercise 39. (A plucker is the moral transpose of the binary
|
|
72
|
+
decoder.)
|
|
73
|
+
|
|
74
|
+
However, this plucker was dominated by the smaller one for our use case, and
|
|
75
|
+
thus removed from the code here. It can be resurrected from experimental if
|
|
76
|
+
needed.
|
|
77
|
+
|
|
78
|
+
[ RUN ] BitPlucker.LargePluckSize
|
|
79
|
+
large_pluck[2] depth: 5 wires: 15 in: 2 out:4 use:9 ovh:6 t:19 cse:9
|
|
80
|
+
notn:27
|
|
81
|
+
large_pluck[3] depth: 7 wires: 31 in: 2 out:5 use:20 ovh:11 t:43
|
|
82
|
+
cse:19 notn:50
|
|
83
|
+
large_pluck[4] depth: 8 wires: 46 in: 2 out:8 use:33 ovh:13 t:70
|
|
84
|
+
cse:33 notn:89
|
|
85
|
+
large_pluck[5] depth: 10 wires: 79 in: 2 out:8 use:60 ovh:19 t:128
|
|
86
|
+
cse:68 notn:164
|
|
87
|
+
large_pluck[6] depth: 11 wires: 119 in: 2 out:12 use:99 ovh:20 t:209
|
|
88
|
+
cse:119 notn:299
|
|
89
|
+
large_pluck[7] depth: 13 wires: 206 in: 2 out:11 use:179 ovh:27 t:381
|
|
90
|
+
cse:234 notn:567
|
|
91
|
+
large_pluck[8] depth: 14 wires: 344 in: 2 out:16 use:317 ovh:27 t:668
|
|
92
|
+
cse:413 notn:1065
|
|
93
|
+
large_pluck[9] depth: 16 wires: 631 in: 2 out:14 use:596 ovh:35 t:1260
|
|
94
|
+
cse:796 notn:2064
|
|
95
|
+
large_pluck[10] depth: 17 wires: 1157 in: 2 out:20 use:1123 ovh:34
|
|
96
|
+
t:2347 cse:1435 notn:3967
|
|
97
|
+
large_pluck[11] depth: 19 wires: 2224 in: 2 out:17 use:2181 ovh:43
|
|
98
|
+
t:4551 cse:2762 notn:7789
|
|
99
|
+
large_pluck[12] depth: 20 wires: 4294 in: 2 out:24 use:4253 ovh:41
|
|
100
|
+
t:8782 cse:5113 notn:15205
|
|
101
|
+
|
|
102
|
+
*/
|
|
103
|
+
template <class Logic, size_t LOGN>
|
|
104
|
+
class BitPlucker {
|
|
105
|
+
public:
|
|
106
|
+
static constexpr size_t kN = 1 << LOGN;
|
|
107
|
+
static constexpr size_t kNv32Elts = (32u + LOGN - 1u) / LOGN;
|
|
108
|
+
static constexpr size_t kNv256Elts = (256u + LOGN - 1u) / LOGN;
|
|
109
|
+
static constexpr size_t kNv128Elts = (128u + LOGN - 1u) / LOGN;
|
|
110
|
+
using Field = typename Logic::Field;
|
|
111
|
+
using BitW = typename Logic::BitW;
|
|
112
|
+
using EltW = typename Logic::EltW;
|
|
113
|
+
using Elt = typename Field::Elt;
|
|
114
|
+
using PolyN = Poly<kN, Field>;
|
|
115
|
+
using InterpolationN = Interpolation<kN, Field>;
|
|
116
|
+
using v32 = typename Logic::v32;
|
|
117
|
+
using v256 = typename Logic::v256;
|
|
118
|
+
using packed_v32 = std::array<EltW, kNv32Elts>;
|
|
119
|
+
using packed_v128 = std::array<EltW, kNv128Elts>;
|
|
120
|
+
using packed_v256 = std::array<EltW, kNv256Elts>;
|
|
121
|
+
|
|
122
|
+
const Logic& l_;
|
|
123
|
+
std::vector<PolyN> plucker_;
|
|
124
|
+
|
|
125
|
+
explicit BitPlucker(const Logic& l) : l_(l), plucker_(LOGN) {
|
|
126
|
+
// evaluation points
|
|
127
|
+
PolyN X;
|
|
128
|
+
for (size_t i = 0; i < kN; ++i) {
|
|
129
|
+
X[i] = bit_plucker_point<Field, kN>()(i, l_.f_);
|
|
130
|
+
}
|
|
131
|
+
for (size_t k = 0; k < LOGN; ++k) {
|
|
132
|
+
PolyN Y;
|
|
133
|
+
for (size_t i = 0; i < kN; ++i) {
|
|
134
|
+
Y[i] = l_.f_.of_scalar((i >> k) & 1);
|
|
135
|
+
}
|
|
136
|
+
plucker_[k] = InterpolationN::monomial_of_lagrange(Y, X, l_.f_);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
typename Logic::template bitvec<LOGN> pluck(const EltW& e) const {
|
|
141
|
+
typename Logic::template bitvec<LOGN> r;
|
|
142
|
+
const Logic& L = l_; // shorthand
|
|
143
|
+
const Polynomial<Logic> P(L);
|
|
144
|
+
|
|
145
|
+
for (size_t k = 0; k < LOGN; ++k) {
|
|
146
|
+
EltW v = P.eval(plucker_[k], e);
|
|
147
|
+
L.assert_is_bit(v);
|
|
148
|
+
r[k] = BitW(v, l_.f_);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return r;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
v32 unpack_v32(const packed_v32& v) const { return unpack<v32>(v); }
|
|
155
|
+
|
|
156
|
+
template <typename T, typename PackedT>
|
|
157
|
+
T unpack(const PackedT& v) const {
|
|
158
|
+
T r;
|
|
159
|
+
for (size_t i = 0; i < v.size(); ++i) {
|
|
160
|
+
auto b = pluck(v[i]);
|
|
161
|
+
for (size_t j = 0; j < LOGN; ++j) {
|
|
162
|
+
if (LOGN * i + j < r.size()) {
|
|
163
|
+
r[LOGN * i + j] = b[j];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return r;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
template <typename T>
|
|
171
|
+
static T packed_input(const Logic& lc) {
|
|
172
|
+
T r;
|
|
173
|
+
for (size_t i = 0; i < r.size(); ++i) {
|
|
174
|
+
r[i] = lc.eltw_input();
|
|
175
|
+
}
|
|
176
|
+
return r;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/*
|
|
181
|
+
On input Elt ind, and Elt arr[], returns arr[ind].
|
|
182
|
+
This muxer is useful when the same array needs to be muxed multiple times
|
|
183
|
+
with different indices. It differs from the above classes in that it
|
|
184
|
+
precomputes the coefficient array, which can depend on EltW inputs.
|
|
185
|
+
|
|
186
|
+
The template parameter N indicates the size of the array.
|
|
187
|
+
The template parameter PP defines the set of points used for the interpolation.
|
|
188
|
+
This value defaults to N, which defines the set of points
|
|
189
|
+
{ -N-1, -N-3, -N-5, ..., N-3, N-1}
|
|
190
|
+
but in some cases, one may want to explicitly specify the set of points.
|
|
191
|
+
*/
|
|
192
|
+
template <class Logic, size_t N, size_t PP = N>
|
|
193
|
+
class EltMuxer {
|
|
194
|
+
static constexpr size_t kN = N;
|
|
195
|
+
static constexpr size_t kPP = PP;
|
|
196
|
+
|
|
197
|
+
public:
|
|
198
|
+
using Field = typename Logic::Field;
|
|
199
|
+
using EltW = typename Logic::EltW;
|
|
200
|
+
using PolyN = Poly<kN, Field>;
|
|
201
|
+
using InterpolationN = Interpolation<kN, Field>;
|
|
202
|
+
|
|
203
|
+
EltMuxer(const Logic& l, const EltW arr[/* kN */]) : l_(l), coeff_(kN) {
|
|
204
|
+
for (size_t i = 0; i < kN; ++i) {
|
|
205
|
+
coeff_[i] = l_.konst(0);
|
|
206
|
+
}
|
|
207
|
+
for (size_t i = 0; i < kN; ++i) {
|
|
208
|
+
PolyN basis_i = even_lagrange_basis(i);
|
|
209
|
+
for (size_t j = 0; j < kN; ++j) {
|
|
210
|
+
auto bi = l_.konst(basis_i[j]);
|
|
211
|
+
auto barr_i = l_.mul(bi, arr[i]);
|
|
212
|
+
coeff_[j] = l_.add(coeff_[j], barr_i);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
EltW mux(const EltW& ind) const {
|
|
218
|
+
const Polynomial<Logic> P(l_);
|
|
219
|
+
|
|
220
|
+
std::array<EltW, kN> xi;
|
|
221
|
+
P.powers_of_x(kN, xi.data(), ind);
|
|
222
|
+
|
|
223
|
+
// dot product with coefficients
|
|
224
|
+
EltW r = l_.konst(0);
|
|
225
|
+
for (size_t i = 0; i < kN; ++i) {
|
|
226
|
+
auto cxi = l_.mul(coeff_[i], xi[i]);
|
|
227
|
+
r = l_.add(r, cxi);
|
|
228
|
+
}
|
|
229
|
+
return r;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private:
|
|
233
|
+
const Logic& l_;
|
|
234
|
+
std::vector<EltW> coeff_;
|
|
235
|
+
|
|
236
|
+
PolyN even_lagrange_basis(size_t k) {
|
|
237
|
+
PolyN X, Y;
|
|
238
|
+
for (size_t i = 0; i < kN; ++i) {
|
|
239
|
+
X[i] = bit_plucker_point<Field, PP>()(i, l_.f_);
|
|
240
|
+
Y[i] = l_.f_.of_scalar((i == k));
|
|
241
|
+
}
|
|
242
|
+
return InterpolationN::monomial_of_lagrange(Y, X, l_.f_);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
} // namespace proofs
|
|
246
|
+
|
|
247
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_H_
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Copyright 2026 Google LLC.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
#ifndef PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_CONSTANTS_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_CONSTANTS_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
#include <stdint.h>
|
|
20
|
+
|
|
21
|
+
namespace proofs {
|
|
22
|
+
// bit-plucker code common to both compiler-time and
|
|
23
|
+
// wire-fill time
|
|
24
|
+
template <class Field, size_t N>
|
|
25
|
+
struct bit_plucker_point {
|
|
26
|
+
using Elt = typename Field::Elt;
|
|
27
|
+
|
|
28
|
+
// packing of bits compatible with even_lagrange_basis():
|
|
29
|
+
Elt operator()(uint64_t bits, const Field& F) const {
|
|
30
|
+
return F.subf(F.of_scalar(2 * bits), F.of_scalar(N - 1));
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
} // namespace proofs
|
|
34
|
+
|
|
35
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_CIRCUITS_LOGIC_BIT_PLUCKER_CONSTANTS_H_
|