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,400 @@
|
|
|
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_RFFT_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_RFFT_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
#include <stdint.h>
|
|
20
|
+
|
|
21
|
+
#include "algebra/permutations.h"
|
|
22
|
+
#include "algebra/twiddle.h"
|
|
23
|
+
#include "util/panic.h"
|
|
24
|
+
|
|
25
|
+
namespace proofs {
|
|
26
|
+
|
|
27
|
+
// Real FFT and its inverse.
|
|
28
|
+
//
|
|
29
|
+
// The FFT F[j] of a real input R[k] is complex and
|
|
30
|
+
// conjugate-symmetric: F[j] = conj(F[n - j]).
|
|
31
|
+
//
|
|
32
|
+
// Following the FFTW conventions, to avoid doubling the
|
|
33
|
+
// storage, we store F[j] as a "half-complex" array HC[j] of elements
|
|
34
|
+
// in the base field.
|
|
35
|
+
//
|
|
36
|
+
// HC[j] = (2j <= n) ? real(F[j]) : imag(F[n - j])
|
|
37
|
+
//
|
|
38
|
+
// Thus we have two kinds of transforms: R2HC (real to
|
|
39
|
+
// half-complex) and HC2R (half-complex to real).
|
|
40
|
+
//
|
|
41
|
+
// Again following the FFTW conventions, we say that
|
|
42
|
+
// the R2HC transform is "forward" (minus sign in the exponent)
|
|
43
|
+
// and the HC2R sign is "backward" (plus sign in the exponent).
|
|
44
|
+
// See fft.h for a definition of forward and backward.
|
|
45
|
+
|
|
46
|
+
template <class FieldExt>
|
|
47
|
+
class RFFT {
|
|
48
|
+
using Field = typename FieldExt::BaseField;
|
|
49
|
+
using RElt = typename Field::Elt;
|
|
50
|
+
using CElt = typename FieldExt::Elt;
|
|
51
|
+
|
|
52
|
+
// The machinery in this file only works if the root is
|
|
53
|
+
// on the unit circle, because we multiply by the conjugate
|
|
54
|
+
// instead of by the inverse.
|
|
55
|
+
static void validate_root(const CElt& omega, const FieldExt& C) {
|
|
56
|
+
check(C.mulf(omega, C.conjf(omega)) == C.one(),
|
|
57
|
+
"root of unity not on the unit circle");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// The machinery in this file only works if omega^{n/4} == (0, 1)
|
|
61
|
+
// (== C.i()) as opposed to the conjugate (0, -1). There is nothing
|
|
62
|
+
// wrong with C.conj(C.i()), but we hardcode the positive sign
|
|
63
|
+
// in all the radix-4 butterflies.
|
|
64
|
+
static void validate_I(const CElt& ii, const FieldExt& C) {
|
|
65
|
+
check(ii == C.i(), "wrong sign for i(), need the conjugate root");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ------------------------------------------------------------
|
|
69
|
+
// Main algorithm starts here.
|
|
70
|
+
//
|
|
71
|
+
// The overall algorithm is a radix-4 Cooley-Tukey FFT. Generally
|
|
72
|
+
// speaking, Cooley-Tukey decomposes a problem of size N into R
|
|
73
|
+
// subproblems of size N/R and N/R subproblems of size R, where R is
|
|
74
|
+
// called the "radix". For quadratic field extensions, R=4 is
|
|
75
|
+
// better than R=2 because one can hardcode a size-4 FFT requiring
|
|
76
|
+
// no multiplications, as multiplying by the fourth root of unity I
|
|
77
|
+
// is free. This is true as long as I^2 = -1, which we assume.
|
|
78
|
+
//
|
|
79
|
+
// The main complexity of the code is due to the fact that the input
|
|
80
|
+
// is in the base field of the quadratic extension (henceforth we
|
|
81
|
+
// say that the input is "real"). Under this assumption, the output
|
|
82
|
+
// C is in the extension field ("complex"), but it is conjugate
|
|
83
|
+
// symmetric C[n-i] = conj(C[j]), so it has only n degrees of
|
|
84
|
+
// freedom and not 2n. Note that C[0] is real and, for even n,
|
|
85
|
+
// C[n/2] is also real.
|
|
86
|
+
//
|
|
87
|
+
// One neat way to store a conjugate-symmetric array C[] into a real
|
|
88
|
+
// array A[] is to say that A[j] = real(C[j]) for 2*j<=n, and A[j] =
|
|
89
|
+
// imag(C[j]) otherwise. See H. Sorensen, D. Jones, M. Heideman,
|
|
90
|
+
// and C. Burrus: "Real-valued fast Fourier transform algorithms"
|
|
91
|
+
// IEEE Transactions on Acoustics, Speech, and Signal Processing,
|
|
92
|
+
// Volume: 35, Issue: 6, June 1987. This idea is closely related to
|
|
93
|
+
// the storage layout in the Fast Discrete Hartley Transform.
|
|
94
|
+
// Following the terminology of the GNU Scientific Library, later
|
|
95
|
+
// also adopted by FFTW, we call this format the "half-complex"
|
|
96
|
+
// storage. Even though the implementation in file works only for N
|
|
97
|
+
// = 2^k, the half-complex format works for all N. For even n, a
|
|
98
|
+
// half-complex array contains n/2+1 real elements and n/2-1
|
|
99
|
+
// imaginary elements. This asymmetry requires special handling of
|
|
100
|
+
// the two excess real elements.
|
|
101
|
+
//
|
|
102
|
+
// Because the real input and the half-complex output have different
|
|
103
|
+
// types, we need to distinguish the real->half-complex transform
|
|
104
|
+
// from the half-complex->real transform. We now focus on the
|
|
105
|
+
// real->half-complex transform, with the understanding that the
|
|
106
|
+
// half-complex->real is the same process run backwards.
|
|
107
|
+
//
|
|
108
|
+
// Letting n = 2^k, each radix-4 step reduces k by 2. If k is odd,
|
|
109
|
+
// we must perform a radix-2 step somewhere, one can execute the
|
|
110
|
+
// radix-2 step at an arbitrary butterfly level in the algorithm.
|
|
111
|
+
// We choose to place the radix-2 step in the first butterfly level,
|
|
112
|
+
// which has no twiddle factors. To this end, r2hcI_2() implements
|
|
113
|
+
// a real->half-complex FFT of size 2, and r2hcI_4() implements a
|
|
114
|
+
// real->half-complex FFT of size 4.
|
|
115
|
+
//
|
|
116
|
+
// The remaining radix-4 butterflies are implemented in hc2hcf_4(),
|
|
117
|
+
// which is an ordinary decimation-in-time Cooley-Tukey butterfly
|
|
118
|
+
// hardcoding the fourth root of unity I (as opposed to -I).
|
|
119
|
+
// (Decimation-in-time means that the butterfly applies the twiddle
|
|
120
|
+
// factors first and then it applies the transform.)
|
|
121
|
+
//
|
|
122
|
+
// However, because of the two excess real elements in a
|
|
123
|
+
// half-complex array, hc2hcf_4() alone is not sufficient. The
|
|
124
|
+
// first butterfly of each level always has real inputs and no
|
|
125
|
+
// twiddle factors, and it can therefore be covered by r2hcI_4().
|
|
126
|
+
// The last bufferfly of each level also has real inputs with
|
|
127
|
+
// twiddle factors w_8^j, where w_8 is an eighth root of unity.
|
|
128
|
+
// This is occasionally called a type-II Fourier transform, by
|
|
129
|
+
// analogy with the so-called type-II Discrete Cosine Transform.
|
|
130
|
+
// r2hcII_4() hardcodes this latter case.
|
|
131
|
+
//
|
|
132
|
+
// For the complex FFT, both the decimation-in-time and
|
|
133
|
+
// decimation-in-frequency variants are possible. For
|
|
134
|
+
// real->half-complex, it seems like decimation-in-time is the only
|
|
135
|
+
// possibility.
|
|
136
|
+
// ------------------------------------------------------------
|
|
137
|
+
static void r2hcI_2(RElt* A, size_t s, const Field& R) {
|
|
138
|
+
RElt t = A[s];
|
|
139
|
+
A[s] = A[0];
|
|
140
|
+
R.add(A[0], t);
|
|
141
|
+
R.sub(A[s], t);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static void r2hcI_4(RElt* A, size_t s, const Field& R) {
|
|
145
|
+
RElt x0 = A[0];
|
|
146
|
+
RElt x1 = A[s];
|
|
147
|
+
RElt z0 = R.addf(x0, x1);
|
|
148
|
+
RElt x2 = A[2 * s];
|
|
149
|
+
RElt x3 = A[3 * s];
|
|
150
|
+
RElt z1 = R.addf(x2, x3);
|
|
151
|
+
A[0] = R.addf(z0, z1);
|
|
152
|
+
A[2 * s] = R.subf(z0, z1);
|
|
153
|
+
A[s] = R.subf(x0, x1);
|
|
154
|
+
A[3 * s] = R.subf(x3, x2);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// j = m/2 butterfly in the main loop, where w8^2 = I
|
|
158
|
+
static void r2hcII_4(RElt* A, size_t s, const CElt& w8, const Field& R) {
|
|
159
|
+
RElt x2 = A[2 * s];
|
|
160
|
+
RElt x3 = A[3 * s];
|
|
161
|
+
RElt z0 = R.addf(x2, x3);
|
|
162
|
+
RElt z1 = R.subf(x2, x3);
|
|
163
|
+
R.mul(z0, w8.im);
|
|
164
|
+
R.mul(z1, w8.re);
|
|
165
|
+
RElt x0 = A[0];
|
|
166
|
+
RElt x1 = A[s];
|
|
167
|
+
A[0] = R.addf(x0, z1);
|
|
168
|
+
A[s] = R.subf(x0, z1);
|
|
169
|
+
A[2 * s] = R.subf(x1, z0);
|
|
170
|
+
A[3 * s] = R.addf(x1, z0);
|
|
171
|
+
R.neg(A[3 * s]);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
static void hc2hcf_4(RElt* Ar, RElt* Ai, size_t s, const CElt& tw1,
|
|
175
|
+
const CElt& tw2, const CElt& tw3, const Field& R) {
|
|
176
|
+
cmulj(&Ar[s], &Ai[s], tw2.re, tw2.im, R);
|
|
177
|
+
RElt y0r = R.addf(Ar[0], Ar[s]);
|
|
178
|
+
RElt y0i = R.addf(Ai[0], Ai[s]);
|
|
179
|
+
RElt y1r = R.subf(Ar[0], Ar[s]);
|
|
180
|
+
RElt y1i = R.subf(Ai[0], Ai[s]);
|
|
181
|
+
cmulj(&Ar[2 * s], &Ai[2 * s], tw1.re, tw1.im, R);
|
|
182
|
+
cmulj(&Ar[3 * s], &Ai[3 * s], tw3.re, tw3.im, R);
|
|
183
|
+
RElt y2r = R.addf(Ar[3 * s], Ar[2 * s]);
|
|
184
|
+
RElt y3r = R.subf(Ar[3 * s], Ar[2 * s]);
|
|
185
|
+
RElt y2i = R.addf(Ai[2 * s], Ai[3 * s]);
|
|
186
|
+
RElt y3i = R.subf(Ai[2 * s], Ai[3 * s]);
|
|
187
|
+
Ar[0] = R.addf(y0r, y2r);
|
|
188
|
+
Ai[s] = R.subf(y0r, y2r);
|
|
189
|
+
Ar[s] = R.addf(y1r, y3i);
|
|
190
|
+
Ai[0] = R.subf(y1r, y3i);
|
|
191
|
+
Ai[3 * s] = R.addf(y2i, y0i);
|
|
192
|
+
Ar[2 * s] = R.subf(y2i, y0i);
|
|
193
|
+
Ai[2 * s] = R.addf(y3r, y1i);
|
|
194
|
+
Ar[3 * s] = R.subf(y3r, y1i);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
//------------------------------------------------------------
|
|
198
|
+
// Backward butterflies.
|
|
199
|
+
//
|
|
200
|
+
// "Backward" means sign +1 in the exponent of the twiddle
|
|
201
|
+
// factors.
|
|
202
|
+
//
|
|
203
|
+
// hc2rI_{2,4}: half-complex->real backward transform.
|
|
204
|
+
//
|
|
205
|
+
// hc2rIII_4: half-complex->real backward transform with w_8^j
|
|
206
|
+
// twiddle factors. This is sometimes called a type-III FFT with
|
|
207
|
+
// the understanding that the inverse of a type-II FFT is a
|
|
208
|
+
// type-III. The terminology is what it is.
|
|
209
|
+
//
|
|
210
|
+
// hc2hcb_4(): the main complex->complex backward butterfly. The
|
|
211
|
+
// backward algorithm is decimation-in-frequency, which means that
|
|
212
|
+
// the twiddle factors are applied at the end of the butterfly.
|
|
213
|
+
// ------------------------------------------------------------
|
|
214
|
+
static void hc2rI_2(RElt* A, size_t s, const Field& R) {
|
|
215
|
+
RElt t = A[s];
|
|
216
|
+
A[s] = A[0];
|
|
217
|
+
R.add(A[0], t);
|
|
218
|
+
R.sub(A[s], t);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
static void hc2rI_4(RElt* A, size_t s, const Field& R) {
|
|
222
|
+
RElt y0 = R.addf(A[0], A[2 * s]);
|
|
223
|
+
RElt y1 = R.subf(A[0], A[2 * s]);
|
|
224
|
+
RElt y2 = R.addf(A[s], A[s]);
|
|
225
|
+
RElt y3 = R.addf(A[3 * s], A[3 * s]);
|
|
226
|
+
A[0] = R.addf(y0, y2);
|
|
227
|
+
A[s] = R.subf(y0, y2);
|
|
228
|
+
A[2 * s] = R.subf(y1, y3);
|
|
229
|
+
A[3 * s] = R.addf(y1, y3);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
static void hc2rIII_4(RElt* A, size_t s, const CElt& w8, const Field& R) {
|
|
233
|
+
RElt x0 = R.addf(A[0], A[0]);
|
|
234
|
+
RElt x1 = R.addf(A[s], A[s]);
|
|
235
|
+
RElt x2 = R.addf(A[2 * s], A[2 * s]);
|
|
236
|
+
RElt x3 = R.addf(A[3 * s], A[3 * s]);
|
|
237
|
+
A[0] = R.addf(x0, x1);
|
|
238
|
+
A[s] = R.subf(x2, x3);
|
|
239
|
+
RElt z0 = R.subf(x0, x1);
|
|
240
|
+
R.mul(z0, w8.re);
|
|
241
|
+
RElt z1 = R.addf(x3, x2);
|
|
242
|
+
R.mul(z1, w8.im);
|
|
243
|
+
A[2 * s] = R.subf(z0, z1);
|
|
244
|
+
A[3 * s] = R.addf(z0, z1);
|
|
245
|
+
R.neg(A[3 * s]);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
static void hc2hcb_4(RElt* Ar, RElt* Ai, size_t s, const CElt& tw1,
|
|
249
|
+
const CElt& tw2, const CElt& tw3, const Field& R) {
|
|
250
|
+
RElt z0 = R.addf(Ar[0], Ai[s]);
|
|
251
|
+
RElt z1 = R.subf(Ar[0], Ai[s]);
|
|
252
|
+
RElt z2 = R.addf(Ar[s], Ai[0]);
|
|
253
|
+
RElt z3 = R.subf(Ar[s], Ai[0]);
|
|
254
|
+
RElt z4 = R.addf(Ai[3 * s], Ar[2 * s]);
|
|
255
|
+
RElt z5 = R.subf(Ai[3 * s], Ar[2 * s]);
|
|
256
|
+
RElt z6 = R.addf(Ai[2 * s], Ar[3 * s]);
|
|
257
|
+
RElt z7 = R.subf(Ai[2 * s], Ar[3 * s]);
|
|
258
|
+
Ar[0] = R.addf(z0, z2);
|
|
259
|
+
Ai[0] = R.addf(z5, z7);
|
|
260
|
+
Ar[s] = R.subf(z0, z2);
|
|
261
|
+
Ai[s] = R.subf(z5, z7);
|
|
262
|
+
cmul(&Ar[s], &Ai[s], tw2.re, tw2.im, R);
|
|
263
|
+
Ar[2 * s] = R.subf(z1, z6);
|
|
264
|
+
Ai[2 * s] = R.addf(z4, z3);
|
|
265
|
+
cmul(&Ar[2 * s], &Ai[2 * s], tw1.re, tw1.im, R);
|
|
266
|
+
Ar[3 * s] = R.addf(z1, z6);
|
|
267
|
+
Ai[3 * s] = R.subf(z4, z3);
|
|
268
|
+
cmul(&Ar[3 * s], &Ai[3 * s], tw3.re, tw3.im, R);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
public:
|
|
272
|
+
// Forward real to half-complex in-place transform.
|
|
273
|
+
// N (the length of A) must be a power of 2
|
|
274
|
+
static void r2hc(RElt A[/*n*/], size_t n, const CElt& omega,
|
|
275
|
+
uint64_t omega_order, const FieldExt& C) {
|
|
276
|
+
const Field& R = C.base_field();
|
|
277
|
+
validate_root(omega, C);
|
|
278
|
+
|
|
279
|
+
if (n == 2) {
|
|
280
|
+
r2hcI_2(A, 1, R);
|
|
281
|
+
} else if (n >= 4) {
|
|
282
|
+
CElt omega_n = Twiddle<FieldExt>::reroot(omega, omega_order, n, C);
|
|
283
|
+
Twiddle<FieldExt> roots(n, omega_n, C);
|
|
284
|
+
validate_I(roots.w_[n / 4], C);
|
|
285
|
+
|
|
286
|
+
Permutations<RElt>::bitrev(A, n);
|
|
287
|
+
|
|
288
|
+
size_t m = n;
|
|
289
|
+
while (m > 4) {
|
|
290
|
+
m /= 4;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (m == 2) {
|
|
294
|
+
for (size_t k = 0; k < n; k += 2) {
|
|
295
|
+
r2hcI_2(&A[k], 1, R);
|
|
296
|
+
}
|
|
297
|
+
} else {
|
|
298
|
+
// m == 4
|
|
299
|
+
for (size_t k = 0; k < n; k += 4) {
|
|
300
|
+
r2hcI_4(&A[k], 1, R);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
for (; m < n; m = 4 * m) {
|
|
305
|
+
size_t ws = n / (4 * m);
|
|
306
|
+
for (size_t k = 0; k < n; k += 4 * m) {
|
|
307
|
+
size_t j;
|
|
308
|
+
r2hcI_4(&A[k], m, R); // j==0
|
|
309
|
+
|
|
310
|
+
for (j = 1; j + j < m; ++j) {
|
|
311
|
+
hc2hcf_4(&A[k + j], &A[k + m - j], m, roots.w_[j * ws],
|
|
312
|
+
roots.w_[2 * j * ws], roots.w_[3 * j * ws], R);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
r2hcII_4(&A[k + j], m, roots.w_[j * ws], R); // j==m/2
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Backward half-complex to real in-place transform.
|
|
322
|
+
static void hc2r(RElt A[/*n*/], size_t n, const CElt& omega,
|
|
323
|
+
uint64_t omega_order, const FieldExt& C) {
|
|
324
|
+
const Field& R = C.base_field();
|
|
325
|
+
validate_root(omega, C);
|
|
326
|
+
|
|
327
|
+
if (n == 2) {
|
|
328
|
+
hc2rI_2(A, 1, R);
|
|
329
|
+
} else if (n >= 4) {
|
|
330
|
+
CElt omega_n = Twiddle<FieldExt>::reroot(omega, omega_order, n, C);
|
|
331
|
+
Twiddle<FieldExt> roots(n, omega_n, C);
|
|
332
|
+
validate_I(roots.w_[n / 4], C);
|
|
333
|
+
|
|
334
|
+
size_t m = n;
|
|
335
|
+
|
|
336
|
+
while (m > 4) {
|
|
337
|
+
m /= 4;
|
|
338
|
+
size_t ws = n / (4 * m);
|
|
339
|
+
for (size_t k = 0; k < n; k += 4 * m) {
|
|
340
|
+
size_t j;
|
|
341
|
+
hc2rI_4(&A[k], m, R); // j==0
|
|
342
|
+
|
|
343
|
+
for (j = 1; j + j < m; ++j) {
|
|
344
|
+
hc2hcb_4(&A[k + j], &A[k + m - j], m, roots.w_[j * ws],
|
|
345
|
+
roots.w_[2 * j * ws], roots.w_[3 * j * ws], R);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
hc2rIII_4(&A[k + j], m, roots.w_[j * ws], R); // j==m/2
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (m == 2) {
|
|
353
|
+
for (size_t k = 0; k < n; k += 2) {
|
|
354
|
+
hc2rI_2(&A[k], 1, R);
|
|
355
|
+
}
|
|
356
|
+
} else {
|
|
357
|
+
// m == 4
|
|
358
|
+
for (size_t k = 0; k < n; k += 4) {
|
|
359
|
+
hc2rI_4(&A[k], 1, R);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
Permutations<RElt>::bitrev(A, n);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// X *= B
|
|
368
|
+
static void cmul(RElt* xr, RElt* xi, const RElt& br, const RElt& bi,
|
|
369
|
+
const Field& R) {
|
|
370
|
+
// Karatsuba 3 mul + 5 add
|
|
371
|
+
RElt p0 = R.mulf(*xr, br);
|
|
372
|
+
RElt p1 = R.mulf(*xi, bi);
|
|
373
|
+
RElt a01 = R.addf(*xr, *xi);
|
|
374
|
+
RElt b01 = R.addf(br, bi);
|
|
375
|
+
*xr = R.subf(p0, p1);
|
|
376
|
+
R.mul(a01, b01);
|
|
377
|
+
R.sub(a01, p0);
|
|
378
|
+
R.sub(a01, p1);
|
|
379
|
+
*xi = a01;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// *X *= conj(B)
|
|
383
|
+
static void cmulj(RElt* xr, RElt* xi, const RElt& br, const RElt& bi,
|
|
384
|
+
const Field& R) {
|
|
385
|
+
// Karatsuba 3 mul + 5 add
|
|
386
|
+
RElt p0 = R.mulf(*xr, br);
|
|
387
|
+
RElt p1 = R.mulf(*xi, bi);
|
|
388
|
+
RElt a01 = R.addf(*xr, *xi);
|
|
389
|
+
RElt b01 = R.subf(br, bi);
|
|
390
|
+
*xr = R.addf(p0, p1);
|
|
391
|
+
R.mul(a01, b01);
|
|
392
|
+
R.sub(a01, p0);
|
|
393
|
+
R.add(a01, p1);
|
|
394
|
+
*xi = a01;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
} // namespace proofs
|
|
399
|
+
|
|
400
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_RFFT_H_
|
|
@@ -0,0 +1,102 @@
|
|
|
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
|
+
|
|
16
|
+
#include "algebra/rfft.h"
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <vector>
|
|
22
|
+
|
|
23
|
+
#include "algebra/fft.h"
|
|
24
|
+
#include "algebra/fp2.h"
|
|
25
|
+
#include "algebra/fp_p256.h"
|
|
26
|
+
#include "gtest/gtest.h"
|
|
27
|
+
|
|
28
|
+
namespace proofs {
|
|
29
|
+
namespace {
|
|
30
|
+
TEST(RFFTTest, Simple) {
|
|
31
|
+
using BaseField = Fp256<>;
|
|
32
|
+
using BaseElt = BaseField::Elt;
|
|
33
|
+
using ExtField = Fp2<BaseField>;
|
|
34
|
+
using ExtElt = ExtField::Elt;
|
|
35
|
+
|
|
36
|
+
const BaseField F0; // base field
|
|
37
|
+
const ExtField F_ext(F0); // p^2 field extension
|
|
38
|
+
|
|
39
|
+
ExtElt omega0 = F_ext.of_string(
|
|
40
|
+
"112649224146410281873500457609690258373018840430489408729223714171582664"
|
|
41
|
+
"680802",
|
|
42
|
+
"840879943585409076957404614278186605601821689971823787493130182544504602"
|
|
43
|
+
"12908");
|
|
44
|
+
uint64_t omega_order = 1ull << 31;
|
|
45
|
+
|
|
46
|
+
// Try various roots of unity while maintaining the invariant that
|
|
47
|
+
// omega^{n/4} = I. The goal of this exercise is to make sure that
|
|
48
|
+
// the rfft does not depend on a specific 8-th root of unity.
|
|
49
|
+
//
|
|
50
|
+
// The actual root of unity used in the FFT is (omega^r) for r =
|
|
51
|
+
// omega_order / n, and omega^{r*n/4} = I (as opposed to -I) holds.
|
|
52
|
+
// Thus (omega^{1+4*j})^{r*n/4} = I also holds for all j, but the
|
|
53
|
+
// 8-th roots are different. Since there are only two eight roots
|
|
54
|
+
// of unity under the constraint, two iterations are sufficient.
|
|
55
|
+
//
|
|
56
|
+
ExtElt omega = omega0;
|
|
57
|
+
for (size_t iter = 0; iter < 2; ++iter) {
|
|
58
|
+
ExtElt one = F_ext.mulf(omega, F_ext.conjf(omega));
|
|
59
|
+
EXPECT_EQ(one, F_ext.one());
|
|
60
|
+
|
|
61
|
+
for (size_t n = 1; n < 1024; n *= 2) {
|
|
62
|
+
std::vector<BaseElt> AR0(n);
|
|
63
|
+
std::vector<BaseElt> AR1(n);
|
|
64
|
+
std::vector<ExtElt> AC(n);
|
|
65
|
+
|
|
66
|
+
// Arbitrary coefficients in base field. Keep three copies.
|
|
67
|
+
for (size_t i = 0; i < n; ++i) {
|
|
68
|
+
AR0[i] = F0.of_scalar(i * i * i + (i & 0xF) + (i ^ (i << 2)));
|
|
69
|
+
AR1[i] = AR0[i];
|
|
70
|
+
AC[i] = ExtElt{AR0[i]};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// compare RFFT against FFT
|
|
74
|
+
FFT<ExtField>::fftb(&AC[0], n, omega, omega_order, F_ext);
|
|
75
|
+
RFFT<ExtField>::r2hc(&AR0[0], n, omega, omega_order, F_ext);
|
|
76
|
+
|
|
77
|
+
for (size_t i = 0; i < n; ++i) {
|
|
78
|
+
if (i + i <= n) {
|
|
79
|
+
EXPECT_EQ(AR0[i], AC[i].re);
|
|
80
|
+
} else {
|
|
81
|
+
EXPECT_EQ(AR0[i], AC[i].im);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// invert and compare against AR1
|
|
86
|
+
RFFT<ExtField>::hc2r(&AR0[0], n, omega, omega_order, F_ext);
|
|
87
|
+
BaseElt scale = F0.of_scalar(n);
|
|
88
|
+
for (size_t i = 0; i < n; ++i) {
|
|
89
|
+
EXPECT_EQ(AR0[i], F0.mulf(scale, AR1[i]));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// advance root of unity
|
|
94
|
+
F_ext.mul(omega, omega0);
|
|
95
|
+
F_ext.mul(omega, omega0);
|
|
96
|
+
F_ext.mul(omega, omega0);
|
|
97
|
+
F_ext.mul(omega, omega0);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
} // namespace
|
|
102
|
+
} // namespace proofs
|
|
@@ -0,0 +1,29 @@
|
|
|
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_STATIC_STRING_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_ALGEBRA_STATIC_STRING_H_
|
|
17
|
+
|
|
18
|
+
#include <cstddef>
|
|
19
|
+
|
|
20
|
+
// utility class to wrap pointers to compile-time
|
|
21
|
+
// constant strings
|
|
22
|
+
struct StaticString {
|
|
23
|
+
template <size_t N>
|
|
24
|
+
explicit StaticString(const char (&s)[N]) : as_pointer(s) {}
|
|
25
|
+
|
|
26
|
+
const char* as_pointer;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_ALGEBRA_STATIC_STRING_H_
|