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,219 @@
|
|
|
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_ALGEBRA_CONVOLUTION_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CONVOLUTION_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <memory>
|
|
22
|
+
#include <vector>
|
|
23
|
+
|
|
24
|
+
#include "algebra/blas.h"
|
|
25
|
+
#include "algebra/fft.h"
|
|
26
|
+
#include "algebra/rfft.h"
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
All of the classes in this package compute convolutions.
|
|
30
|
+
That is, given inputs arrays of field elements x, y, with |x|=n, |y|=m,
|
|
31
|
+
these methods compute the first m entries of
|
|
32
|
+
|
|
33
|
+
z[k] = \sum_{i=0}^{n-1} x[i] y[k-i]
|
|
34
|
+
|
|
35
|
+
SlowConvolution uses an O(n*m) method for testing validation.
|
|
36
|
+
|
|
37
|
+
FFTConvolution and FFTExtConvolution first pad y to length n and use advanced
|
|
38
|
+
FFT algorithms to compute the same in O(nlogn) time.
|
|
39
|
+
|
|
40
|
+
The const Field& objects that are passed have lifetimes that exceed the call
|
|
41
|
+
durations and can be safely passed by const reference.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
namespace proofs {
|
|
45
|
+
|
|
46
|
+
// Returns the smallest power of 2 that is at least n.
|
|
47
|
+
static size_t choose_padding(const size_t n) {
|
|
48
|
+
size_t p = 1;
|
|
49
|
+
while (p < n) {
|
|
50
|
+
p *= 2;
|
|
51
|
+
}
|
|
52
|
+
return p;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
template <class Field>
|
|
56
|
+
class FFTConvolution {
|
|
57
|
+
using Elt = typename Field::Elt;
|
|
58
|
+
|
|
59
|
+
public:
|
|
60
|
+
FFTConvolution(size_t n, size_t m, const Field& f, const Elt omega,
|
|
61
|
+
uint64_t omega_order, const Elt y[/*m*/])
|
|
62
|
+
: f_(f),
|
|
63
|
+
omega_(omega),
|
|
64
|
+
omega_order_(omega_order),
|
|
65
|
+
n_(n),
|
|
66
|
+
m_(m),
|
|
67
|
+
padding_(choose_padding(m)),
|
|
68
|
+
y_fft_(padding_, f_.zero()) {
|
|
69
|
+
Blas<Field>::copy(m, &y_fft_[0], 1, y, 1);
|
|
70
|
+
FFT<Field>::fftf(&y_fft_[0], padding_, omega_, omega_order_, f_);
|
|
71
|
+
|
|
72
|
+
// Pre-scale Y by 1/N to compensate for the scaling in FFTB(FFTF(.))
|
|
73
|
+
Blas<Field>::scale(padding_, &y_fft_[0], 1,
|
|
74
|
+
f_.invertf(f_.of_scalar(padding_)), f_);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Computes (first m entries of) convolution of x with y, outputs in z:
|
|
78
|
+
// z[k] = \sum_{i=0}^{n-1} x[i] y[k-i].
|
|
79
|
+
// Note that y has already been FFT'd and divided by padding_ in constructor
|
|
80
|
+
void convolution(const Elt x[/*n_*/], Elt z[/*m_*/]) const {
|
|
81
|
+
std::vector<Elt> x_fft(padding_, f_.zero());
|
|
82
|
+
Blas<Field>::copy(n_, &x_fft[0], 1, x, 1);
|
|
83
|
+
FFT<Field>::fftf(&x_fft[0], padding_, omega_, omega_order_, f_);
|
|
84
|
+
// Pointwise multiplication.
|
|
85
|
+
for (size_t i = 0; i < padding_; ++i) {
|
|
86
|
+
f_.mul(x_fft[i], y_fft_[i]);
|
|
87
|
+
}
|
|
88
|
+
// Backward fft.
|
|
89
|
+
FFT<Field>::fftb(&x_fft[0], padding_, omega_, omega_order_, f_);
|
|
90
|
+
Blas<Field>::copy(m_, z, 1, &x_fft[0], 1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private:
|
|
94
|
+
const Field& f_;
|
|
95
|
+
const Elt omega_;
|
|
96
|
+
const uint64_t omega_order_;
|
|
97
|
+
|
|
98
|
+
// n is the number of points input
|
|
99
|
+
size_t n_;
|
|
100
|
+
size_t m_; // total number of points output (points in + new points out)
|
|
101
|
+
size_t padding_;
|
|
102
|
+
|
|
103
|
+
// fft(y[i]) / padding
|
|
104
|
+
// padded with zeroes to the next power of 2 at least m.
|
|
105
|
+
std::vector<Elt> y_fft_;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
template <class Field>
|
|
109
|
+
class FFTConvolutionFactory {
|
|
110
|
+
using Elt = typename Field::Elt;
|
|
111
|
+
|
|
112
|
+
public:
|
|
113
|
+
using Convolver = FFTConvolution<Field>;
|
|
114
|
+
FFTConvolutionFactory(const Field& f, const Elt omega, uint64_t omega_order)
|
|
115
|
+
: f_(f), omega_(omega), omega_order_(omega_order) {}
|
|
116
|
+
|
|
117
|
+
std::unique_ptr<const Convolver> make(size_t n, size_t m,
|
|
118
|
+
const Elt y[/*m*/]) const {
|
|
119
|
+
return std::make_unique<const Convolver>(n, m, f_, omega_, omega_order_, y);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private:
|
|
123
|
+
const Field& f_;
|
|
124
|
+
const Elt omega_;
|
|
125
|
+
const uint64_t omega_order_;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
template <class Field, class FieldExt>
|
|
129
|
+
class FFTExtConvolution {
|
|
130
|
+
using Elt = typename Field::Elt;
|
|
131
|
+
using EltExt = typename FieldExt::Elt;
|
|
132
|
+
|
|
133
|
+
public:
|
|
134
|
+
FFTExtConvolution(size_t n, size_t m, const Field& f, const FieldExt& f_ext,
|
|
135
|
+
const EltExt omega, uint64_t omega_order,
|
|
136
|
+
const Elt y[/*m*/])
|
|
137
|
+
: f_(f),
|
|
138
|
+
f_ext_(f_ext),
|
|
139
|
+
omega_(omega),
|
|
140
|
+
omega_order_(omega_order),
|
|
141
|
+
n_(n),
|
|
142
|
+
m_(m),
|
|
143
|
+
padding_(choose_padding(m)),
|
|
144
|
+
y_fft_(padding_, f_.zero()) {
|
|
145
|
+
Blas<Field>::copy(m, &y_fft_[0], 1, y, 1);
|
|
146
|
+
RFFT<FieldExt>::r2hc(&y_fft_[0], padding_, omega_, omega_order_, f_ext_);
|
|
147
|
+
|
|
148
|
+
// Pre-scale Y by 1/N to compensate for the scaling in HC2R(R2HC(.))
|
|
149
|
+
Blas<Field>::scale(padding_, &y_fft_[0], 1,
|
|
150
|
+
f_.invertf(f_.of_scalar(padding_)), f_);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Computes (first m entries of) convolution of x with y, stores in z:
|
|
154
|
+
// z[k] = \sum_{i=0}^{n-1} x[i] y[k-i].
|
|
155
|
+
// Note that y has already been FFT'd and divided by padding_ in constructor
|
|
156
|
+
void convolution(const Elt x[/*n_*/], Elt z[/*m_*/]) const {
|
|
157
|
+
std::vector<Elt> x_fft(padding_, f_.zero());
|
|
158
|
+
Blas<Field>::copy(n_, &x_fft[0], 1, x, 1);
|
|
159
|
+
RFFT<FieldExt>::r2hc(&x_fft[0], padding_, omega_, omega_order_, f_ext_);
|
|
160
|
+
|
|
161
|
+
// Pointwise multiplication
|
|
162
|
+
{
|
|
163
|
+
size_t i;
|
|
164
|
+
f_.mul(x_fft[0], y_fft_[0]); // DC is real
|
|
165
|
+
for (i = 1; i + i < padding_; ++i) {
|
|
166
|
+
RFFT<FieldExt>::cmul(&x_fft[i], &x_fft[padding_ - i], y_fft_[i],
|
|
167
|
+
y_fft_[padding_ - i], f_);
|
|
168
|
+
}
|
|
169
|
+
f_.mul(x_fft[i], y_fft_[i]); // Nyquist is real
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Backward FFT.
|
|
173
|
+
RFFT<FieldExt>::hc2r(&x_fft[0], padding_, omega_, omega_order_, f_ext_);
|
|
174
|
+
Blas<Field>::copy(m_, z, 1, &x_fft[0], 1);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private:
|
|
178
|
+
const Field& f_;
|
|
179
|
+
const FieldExt& f_ext_;
|
|
180
|
+
const EltExt omega_;
|
|
181
|
+
const uint64_t omega_order_;
|
|
182
|
+
|
|
183
|
+
// n is the number of points input in x
|
|
184
|
+
size_t n_;
|
|
185
|
+
size_t m_; // total number of points output in convolution
|
|
186
|
+
size_t padding_;
|
|
187
|
+
|
|
188
|
+
// fft(y[i]) / padding
|
|
189
|
+
// padded with zeroes to the next power of 2 at least m.
|
|
190
|
+
std::vector<Elt> y_fft_;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
template <class Field, class FieldExt>
|
|
194
|
+
class FFTExtConvolutionFactory {
|
|
195
|
+
using Elt = typename Field::Elt;
|
|
196
|
+
using EltExt = typename FieldExt::Elt;
|
|
197
|
+
|
|
198
|
+
public:
|
|
199
|
+
using Convolver = FFTExtConvolution<Field, FieldExt>;
|
|
200
|
+
|
|
201
|
+
FFTExtConvolutionFactory(const Field& f, const FieldExt& f_ext,
|
|
202
|
+
const EltExt omega, uint64_t omega_order)
|
|
203
|
+
: f_(f), f_ext_(f_ext), omega_(omega), omega_order_(omega_order) {}
|
|
204
|
+
|
|
205
|
+
std::unique_ptr<const Convolver> make(size_t n, size_t m,
|
|
206
|
+
const Elt y[/*m*/]) const {
|
|
207
|
+
return std::make_unique<const Convolver>(n, m, f_, f_ext_, omega_,
|
|
208
|
+
omega_order_, y);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private:
|
|
212
|
+
const Field& f_;
|
|
213
|
+
const FieldExt& f_ext_;
|
|
214
|
+
const EltExt omega_;
|
|
215
|
+
const uint64_t omega_order_;
|
|
216
|
+
};
|
|
217
|
+
} // namespace proofs
|
|
218
|
+
|
|
219
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CONVOLUTION_H_
|
|
@@ -0,0 +1,42 @@
|
|
|
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/crt.h"
|
|
16
|
+
|
|
17
|
+
#include <cstdint>
|
|
18
|
+
|
|
19
|
+
namespace proofs {
|
|
20
|
+
namespace crt {
|
|
21
|
+
|
|
22
|
+
// ==========================================
|
|
23
|
+
// 17 primes for a CRT representation that can support p521.
|
|
24
|
+
// 9 or 13 can be used for smaller fields. Primes are in sorted order.
|
|
25
|
+
const uint64_t kPrimes17[kBasisSize] = {
|
|
26
|
+
18446744072195407873ull, 18446744072237350913ull, 18446744072245739521ull,
|
|
27
|
+
18446744072325431297ull, 18446744072589672449ull, 18446744072623226881ull,
|
|
28
|
+
18446744072790999041ull, 18446744073113960449ull, 18446744073290121217ull,
|
|
29
|
+
18446744073327869953ull, 18446744073332064257ull, 18446744073344647169ull,
|
|
30
|
+
18446744073420144641ull, 18446744073457893377ull, 18446744073516613633ull,
|
|
31
|
+
18446744073520807937ull, 18446744073692774401ull};
|
|
32
|
+
|
|
33
|
+
const uint64_t kOmega17[kBasisSize] = {
|
|
34
|
+
436037131817ull, 2773676930123ull, 2768111518080ull, 34106487772798ull,
|
|
35
|
+
1302264167001ull, 5572414085664ull, 4170236488818ull, 10930506752996ull,
|
|
36
|
+
13447610733542ull, 366878793395ull, 10535270759408ull, 2630106726088ull,
|
|
37
|
+
2766923619799ull, 6957320847870ull, 10540913985379ull, 15095618916269ull,
|
|
38
|
+
3150424293220ull,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
} // namespace crt
|
|
42
|
+
} // namespace proofs
|
|
@@ -0,0 +1,299 @@
|
|
|
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_ALGEBRA_CRT_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CRT_H_
|
|
17
|
+
|
|
18
|
+
#include <cstddef>
|
|
19
|
+
#include <cstdint>
|
|
20
|
+
#include <memory>
|
|
21
|
+
|
|
22
|
+
#include "algebra/fp.h"
|
|
23
|
+
#include "algebra/nat.h"
|
|
24
|
+
#include "util/panic.h"
|
|
25
|
+
|
|
26
|
+
// The idea behind this class is to mimic the Field interface for F_p with
|
|
27
|
+
// an underlying CRT implementation over a basis of primes. Then a
|
|
28
|
+
// convolution template can be instantiated with this class instead of an
|
|
29
|
+
// F_p field, and this convolution can be used by ReedSolomon.
|
|
30
|
+
|
|
31
|
+
namespace proofs {
|
|
32
|
+
|
|
33
|
+
// Every prime field of 1-64b word has the same type, but are different classes.
|
|
34
|
+
using BaseField = Fp<1, false>;
|
|
35
|
+
using BaseNat = typename BaseField::N;
|
|
36
|
+
using BaseElt = typename BaseField::Elt;
|
|
37
|
+
|
|
38
|
+
// constants
|
|
39
|
+
namespace crt {
|
|
40
|
+
static constexpr size_t kBasisSize = 17;
|
|
41
|
+
static constexpr uint64_t kOmegaOrder = 1ull << 22;
|
|
42
|
+
|
|
43
|
+
extern const uint64_t kPrimes17[kBasisSize];
|
|
44
|
+
extern const uint64_t kOmega17[kBasisSize];
|
|
45
|
+
} // namespace crt
|
|
46
|
+
|
|
47
|
+
// ==========================================
|
|
48
|
+
|
|
49
|
+
// Fp_crt implementation of field Field. This implementation works as long
|
|
50
|
+
// as the sequence of field operations that are performed on elements before
|
|
51
|
+
// the from_crt method is called can be range-bounded by the max value that can
|
|
52
|
+
// be represented using the CRT basis formed by the first VS primes defined in
|
|
53
|
+
// kBasis.
|
|
54
|
+
// The initialize of this class computes the auxiliary information needed to
|
|
55
|
+
// efficiently move into and out of the CRT representation. Therefore, this
|
|
56
|
+
// class can be instantiated once and used for many convolutions/etc.
|
|
57
|
+
template <size_t VS, class Field>
|
|
58
|
+
class CRT {
|
|
59
|
+
static constexpr size_t kWField = Field::kU64;
|
|
60
|
+
|
|
61
|
+
public:
|
|
62
|
+
static constexpr size_t kVS = VS;
|
|
63
|
+
const Field& f_;
|
|
64
|
+
|
|
65
|
+
struct Elt {
|
|
66
|
+
BaseElt r[VS];
|
|
67
|
+
bool operator==(const Elt& y) const {
|
|
68
|
+
bool res = true;
|
|
69
|
+
for (size_t i = 0; i < VS; ++i) {
|
|
70
|
+
res = res && (r[i] == y.r[i]);
|
|
71
|
+
}
|
|
72
|
+
return res;
|
|
73
|
+
}
|
|
74
|
+
bool operator!=(const Elt& y) const { return !operator==(y); }
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
explicit CRT(const Field& f) : f_(f) {
|
|
78
|
+
check(VS <= crt::kBasisSize, "VS <= crt::kBasisSize");
|
|
79
|
+
|
|
80
|
+
for (size_t b = 0; b < VS; ++b) {
|
|
81
|
+
bf_[b] = std::make_unique<BaseField>(BaseNat(crt::kPrimes17[b]));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (size_t b = 0; b < VS; ++b) {
|
|
85
|
+
k_[0].r[b] = bf_[b]->zero();
|
|
86
|
+
k_[1].r[b] = bf_[b]->one();
|
|
87
|
+
k_[2].r[b] = bf_[b]->two();
|
|
88
|
+
reduce_scale_[b] = bf_[b]->template reduce_scale<kWField>();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (VS == 1) {
|
|
92
|
+
// ignore the Garner reduction constants, and do not
|
|
93
|
+
// require the field to support dot products.
|
|
94
|
+
} else {
|
|
95
|
+
// Standard CRT integer conversion requires computing a dot-product
|
|
96
|
+
// between the CRT representation and a vector of constants. The
|
|
97
|
+
// reconstruction pre-processing is to compute:
|
|
98
|
+
// 1. Compute P_i = prod_{j neq i} prime_j and
|
|
99
|
+
// P = prod_{j} prime_j
|
|
100
|
+
// 2. Compute inv_i such that inv_i * P_i = 1 mod prime_i
|
|
101
|
+
// The online reconstruction step is then:
|
|
102
|
+
// a. v = (sum_{i} r_i * recon_i) (mod P)) mod f_p
|
|
103
|
+
// for (size_t i = 0; i < VS; ++i) {
|
|
104
|
+
// recon_[i] = ring_.of_string(kRecon[i]);
|
|
105
|
+
// }
|
|
106
|
+
// However, we use the Garner method which requires more pre-processed
|
|
107
|
+
// elements, but produces a result that is guaranteed to be in [0,m] and
|
|
108
|
+
// does so using smaller operations.
|
|
109
|
+
|
|
110
|
+
// garner_[i] are terms prod p_k in CRT formula, prepared for
|
|
111
|
+
// optimized FMA operations by 64-bit scalar vi[i] in to_field.
|
|
112
|
+
for (size_t i = 0; i < VS; ++i) {
|
|
113
|
+
auto g = f.one();
|
|
114
|
+
for (size_t j = 0; j < i; ++j) {
|
|
115
|
+
Nat<1> n(crt::kPrimes17[j]);
|
|
116
|
+
f.mul(g, f.reduce(n));
|
|
117
|
+
}
|
|
118
|
+
garner_[i] = f.prescale_for_dot(g);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Initialize Garner constants Cij.
|
|
122
|
+
for (size_t i = 0; i < VS; ++i) {
|
|
123
|
+
for (size_t j = 0; j < i; ++j) {
|
|
124
|
+
cij_[i][j] = bf_[i]->invertf(bf_[i]->of_scalar(crt::kPrimes17[j]));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
CRT(const CRT&) = delete;
|
|
131
|
+
CRT& operator=(const CRT&) = delete;
|
|
132
|
+
|
|
133
|
+
Elt to_crt(const typename Field::Elt& e) const {
|
|
134
|
+
Elt r;
|
|
135
|
+
auto n = f_.from_montgomery(e);
|
|
136
|
+
for (size_t b = 0; b < VS; ++b) {
|
|
137
|
+
r.r[b] = bf_[b]->reduce(n, reduce_scale_[b]);
|
|
138
|
+
}
|
|
139
|
+
return r;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// The standard CRT reconstruction algorithm to convert
|
|
143
|
+
// from the CRT representation to the BigRing representation involves
|
|
144
|
+
// several operations between "ring-element"-sized values and prime-element
|
|
145
|
+
// sized values. This method is slower, and it produces a result that must
|
|
146
|
+
// also be reduced modulo the ring.
|
|
147
|
+
//
|
|
148
|
+
// result = (sum_{i} x_i * recon_i) (mod P_))
|
|
149
|
+
// CRTRing::Elt from_crt(const Elt& x) const {
|
|
150
|
+
// typename CRTRing::Elt r = ring_.zero();
|
|
151
|
+
// for (size_t i = 0; i < VS; ++i) {
|
|
152
|
+
// Nat<1> xi = kBasis[i].from_montgomery(x.r[i]);
|
|
153
|
+
// ring_.add(r, ring_.mulf(recon_[i], ring_.of_scalar(xi.limb_[0])));
|
|
154
|
+
// }
|
|
155
|
+
// return r;
|
|
156
|
+
// }
|
|
157
|
+
// BM_FromCRT 2.482µ ± ∞ ¹
|
|
158
|
+
// BM_FromCRT 22.08k ± ∞ ¹ (instructions)
|
|
159
|
+
// Instead, we use Garner's method, which can also reduce the returned value
|
|
160
|
+
// by the Field modulus in the same step. This method is roughly 4x faster.
|
|
161
|
+
//
|
|
162
|
+
// BM_ToField 729.6n ± ∞ ¹
|
|
163
|
+
// BM_ToField 6.282k ± ∞ ¹ (instructions)
|
|
164
|
+
//
|
|
165
|
+
// The Garner CRT reconstruction produces a result that lies in 0..m, and
|
|
166
|
+
// only uses single-word arithmetic to produce the intermediate values
|
|
167
|
+
// v1..vn.
|
|
168
|
+
// If the eventual goal is to reconstruct an element in Fp, then the last
|
|
169
|
+
// reconstruction step can be done in Fp, thereby requiring no arithmetic
|
|
170
|
+
// in the Bigring.
|
|
171
|
+
typename Field::Elt to_field(const Elt& x) const {
|
|
172
|
+
if (VS == 1) {
|
|
173
|
+
return f_.reduce(bf_[0]->from_montgomery(x.r[0]));
|
|
174
|
+
} else {
|
|
175
|
+
// Let cij be s.t. c_ij.pi = 1 mod pj
|
|
176
|
+
// v1 = x1
|
|
177
|
+
// v2 = (x2 - v1).c12 mod p2
|
|
178
|
+
// v3 = ((x3 - v1).c13 - v2).c23 mod p3
|
|
179
|
+
// v4 = (((x4 - v1).c14 - v2).c24 - v3).c34 mod p4
|
|
180
|
+
// ...
|
|
181
|
+
// u = vr.p_{r-1}p_{r-2}...p_1 + ... + v4.p3.p2.p1 + v3.p2.p1 + ... + v1
|
|
182
|
+
// Because the goal is to compute u mod F_p, it suffices to maintain
|
|
183
|
+
// each of the p_{r-j}...p1 products modulo F_p.
|
|
184
|
+
BaseNat vi[VS];
|
|
185
|
+
// This inner loop breaks our field abstraction. Instead of maintaining
|
|
186
|
+
// vi in Montgomery form, it is kept as a natural in [0,p-1].
|
|
187
|
+
// The F.sub method works in this form, and because cij_ is in
|
|
188
|
+
// Montgomery form, the last mul operation returns a result that is also
|
|
189
|
+
// "natural." This maneuver saves an of_scalar and a from_montgomery
|
|
190
|
+
// call in the inner-loop.
|
|
191
|
+
for (size_t j = 0; j < VS; ++j) {
|
|
192
|
+
vi[j] = bf_[j]->from_montgomery(x.r[j]);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Change the order of operations to exploit data (in)dependencies. The
|
|
196
|
+
// subtractions and mults can all issue in parallel.
|
|
197
|
+
for (size_t j = 1; j < VS; ++j) {
|
|
198
|
+
for (size_t i = j; i < VS; ++i) {
|
|
199
|
+
const BaseField* Fi = bf_[i].get();
|
|
200
|
+
Fi->sub(vi[i], vi[j - 1]);
|
|
201
|
+
Fi->mul(vi[i], cij_[i][j - 1]);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return f_.dot(VS, vi, garner_);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Returns a root of unity consisting of a root of unity of the same degree
|
|
210
|
+
// for each base prime.
|
|
211
|
+
Elt omega() const {
|
|
212
|
+
Elt r;
|
|
213
|
+
for (size_t b = 0; b < VS; ++b) {
|
|
214
|
+
r.r[b] = bf_[b]->of_scalar(crt::kOmega17[b]);
|
|
215
|
+
}
|
|
216
|
+
return r;
|
|
217
|
+
}
|
|
218
|
+
uint64_t omega_order() const { return crt::kOmegaOrder; }
|
|
219
|
+
|
|
220
|
+
// x += y
|
|
221
|
+
void add(Elt& x, const Elt& y) const {
|
|
222
|
+
for (size_t i = 0; i < VS; ++i) {
|
|
223
|
+
bf_[i]->add(x.r[i], y.r[i]);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// x -= y
|
|
227
|
+
void sub(Elt& x, const Elt& y) const {
|
|
228
|
+
for (size_t i = 0; i < VS; ++i) {
|
|
229
|
+
bf_[i]->sub(x.r[i], y.r[i]);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// x *= y, Montgomery
|
|
234
|
+
void mul(Elt& x, const Elt& y) const {
|
|
235
|
+
for (size_t i = 0; i < VS; ++i) {
|
|
236
|
+
bf_[i]->mul(x.r[i], y.r[i]);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
void neg(Elt& x) const {
|
|
241
|
+
for (size_t i = 0; i < VS; ++i) {
|
|
242
|
+
bf_[i]->neg(x.r[i]);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
void invert(Elt& x) const {
|
|
247
|
+
for (size_t i = 0; i < VS; ++i) {
|
|
248
|
+
check(x.r[i] != bf_[i]->zero(), "Non-invertible element");
|
|
249
|
+
bf_[i]->invert(x.r[i]);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// functional interface
|
|
254
|
+
Elt addf(Elt a, const Elt& y) const {
|
|
255
|
+
add(a, y);
|
|
256
|
+
return a;
|
|
257
|
+
}
|
|
258
|
+
Elt subf(Elt a, const Elt& y) const {
|
|
259
|
+
sub(a, y);
|
|
260
|
+
return a;
|
|
261
|
+
}
|
|
262
|
+
Elt mulf(Elt a, const Elt& y) const {
|
|
263
|
+
mul(a, y);
|
|
264
|
+
return a;
|
|
265
|
+
}
|
|
266
|
+
Elt negf(Elt a) const {
|
|
267
|
+
neg(a);
|
|
268
|
+
return a;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
Elt invertf(Elt a) const {
|
|
272
|
+
invert(a);
|
|
273
|
+
return a;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const Elt& zero() const { return k_[0]; }
|
|
277
|
+
const Elt& one() const { return k_[1]; }
|
|
278
|
+
const Elt& two() const { return k_[2]; }
|
|
279
|
+
|
|
280
|
+
private:
|
|
281
|
+
std::unique_ptr<BaseField> bf_[VS];
|
|
282
|
+
Elt k_[3]; // small constants
|
|
283
|
+
BaseField::template ScaleElt<kWField> reduce_scale_[VS];
|
|
284
|
+
typename Field::NatScaledForDot garner_[VS];
|
|
285
|
+
BaseElt cij_[VS][VS];
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
template <class Field>
|
|
289
|
+
using CRT256 = CRT<9, Field>;
|
|
290
|
+
|
|
291
|
+
template <class Field>
|
|
292
|
+
using CRT384 = CRT<13, Field>;
|
|
293
|
+
|
|
294
|
+
template <class Field>
|
|
295
|
+
using CRT521 = CRT<17, Field>;
|
|
296
|
+
|
|
297
|
+
} // namespace proofs
|
|
298
|
+
|
|
299
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CRT_H_
|
|
@@ -0,0 +1,114 @@
|
|
|
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_ALGEBRA_CRT_CONVOLUTION_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CRT_CONVOLUTION_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <memory>
|
|
22
|
+
#include <vector>
|
|
23
|
+
|
|
24
|
+
#include "algebra/convolution.h"
|
|
25
|
+
#include "algebra/fft.h"
|
|
26
|
+
|
|
27
|
+
namespace proofs {
|
|
28
|
+
|
|
29
|
+
// Uses a fixed basis of primes to compute a convolution for 64--521 bit values.
|
|
30
|
+
// The CRT class must use the same Field in its definition.
|
|
31
|
+
template <class CRT, class Field>
|
|
32
|
+
class CRTConvolution {
|
|
33
|
+
using Elt = typename Field::Elt;
|
|
34
|
+
using CRTElt = typename CRT::Elt;
|
|
35
|
+
|
|
36
|
+
public:
|
|
37
|
+
CRT crt_;
|
|
38
|
+
|
|
39
|
+
CRTConvolution(size_t n, size_t m, const Field& f, const Elt y[/*m*/])
|
|
40
|
+
: crt_(f),
|
|
41
|
+
f_(f),
|
|
42
|
+
n_(n),
|
|
43
|
+
m_(m),
|
|
44
|
+
padding_(choose_padding(m)),
|
|
45
|
+
y_fft_(padding_, crt_.zero()),
|
|
46
|
+
omega_order_(crt_.omega_order()),
|
|
47
|
+
omega_(crt_.omega()) {
|
|
48
|
+
// Pre-compute the y coefficients in crt form.
|
|
49
|
+
// Pre-scale Y by 1/N to compensate for the scaling in FFTB(FFTF(.))
|
|
50
|
+
auto pni = crt_.invertf(crt_.to_crt(f.of_scalar(padding_)));
|
|
51
|
+
for (size_t i = 0; i < m; ++i) {
|
|
52
|
+
y_fft_[i] = crt_.mulf(pni, crt_.to_crt(y[i]));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
FFT<CRT>::fftf(&y_fft_[0], padding_, omega_, omega_order_, crt_);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Computes (first m entries of) convolution of x with y, outputs in z:
|
|
59
|
+
// z[k] = \sum_{i=0}^{n-1} x[i] y[k-i].
|
|
60
|
+
// Note that y has already been FFT'd and divided by padding_ in constructor
|
|
61
|
+
void convolution(const Elt x[/*n_*/], Elt z[/*m_*/]) const {
|
|
62
|
+
std::vector<CRTElt> x_fft(padding_, crt_.zero());
|
|
63
|
+
for (size_t i = 0; i < n_; ++i) {
|
|
64
|
+
x_fft[i] = crt_.to_crt(x[i]);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
FFT<CRT>::fftf(&x_fft[0], padding_, omega_, omega_order_, crt_);
|
|
68
|
+
|
|
69
|
+
// Pointwise multiplication.
|
|
70
|
+
for (size_t i = 0; i < padding_; ++i) {
|
|
71
|
+
crt_.mul(x_fft[i], y_fft_[i]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Backward fft.
|
|
75
|
+
FFT<CRT>::fftb(&x_fft[0], padding_, omega_, omega_order_, crt_);
|
|
76
|
+
|
|
77
|
+
// Convert back to field form
|
|
78
|
+
for (size_t i = 0; i < m_; ++i) {
|
|
79
|
+
z[i] = crt_.to_field(x_fft[i]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private:
|
|
84
|
+
const Field& f_;
|
|
85
|
+
|
|
86
|
+
// n is the number of points input
|
|
87
|
+
size_t n_;
|
|
88
|
+
size_t m_; // total number of points output (points in + new points out)
|
|
89
|
+
size_t padding_;
|
|
90
|
+
std::vector<CRTElt> y_fft_;
|
|
91
|
+
uint64_t omega_order_;
|
|
92
|
+
CRTElt omega_;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
template <class CRT, class Field>
|
|
96
|
+
class CrtConvolutionFactory {
|
|
97
|
+
using Elt = typename Field::Elt;
|
|
98
|
+
|
|
99
|
+
public:
|
|
100
|
+
using Convolver = CRTConvolution<CRT, Field>;
|
|
101
|
+
explicit CrtConvolutionFactory(const Field& f) : f_(f) {}
|
|
102
|
+
|
|
103
|
+
std::unique_ptr<const Convolver> make(size_t n, size_t m,
|
|
104
|
+
const Elt y[/*m*/]) const {
|
|
105
|
+
return std::make_unique<const Convolver>(n, m, f_, y);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private:
|
|
109
|
+
const Field& f_;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
} // namespace proofs
|
|
113
|
+
|
|
114
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_CRT_CONVOLUTION_H_
|