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,60 @@
|
|
|
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_EC_P256K1_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_EC_P256K1_H_
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
This file declares the one instance of the P256k1 curve and its related fields.
|
|
20
|
+
There should be only one instance of this curve in any program due to the
|
|
21
|
+
typing conventions.
|
|
22
|
+
|
|
23
|
+
This curve is also known as secp256k1.
|
|
24
|
+
|
|
25
|
+
It is defined over the base field F_p for
|
|
26
|
+
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
|
|
27
|
+
= 2^256 - 2^32 - 977
|
|
28
|
+
= 115792089237316195423570985008687907853269984665640564039457584007908834671663
|
|
29
|
+
|
|
30
|
+
and has an order of
|
|
31
|
+
n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
|
|
32
|
+
= 115792089237316195423570985008687907852837564279074904382605163141518161494337
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
#include "algebra/fp.h"
|
|
36
|
+
#include "algebra/fp_p256k1.h"
|
|
37
|
+
#include "ec/elliptic_curve.h"
|
|
38
|
+
|
|
39
|
+
namespace proofs {
|
|
40
|
+
|
|
41
|
+
using Fp256k1Base = Fp256k1<true>;
|
|
42
|
+
using Fp256k1Scalar = Fp<4, true>;
|
|
43
|
+
using Fp256k1Nat = Fp256k1Base::N;
|
|
44
|
+
|
|
45
|
+
// This is the base field of the curve.
|
|
46
|
+
extern const Fp256k1Base p256k1_base;
|
|
47
|
+
|
|
48
|
+
// Order of the curve.
|
|
49
|
+
extern const Fp256k1Nat n256k1_order;
|
|
50
|
+
|
|
51
|
+
// This field allows operations mod the order of the curve.
|
|
52
|
+
extern const Fp256k1Scalar p256k1_scalar;
|
|
53
|
+
|
|
54
|
+
typedef EllipticCurve<Fp256k1Base, 4, 256> P256k1;
|
|
55
|
+
|
|
56
|
+
extern const P256k1 p256k1;
|
|
57
|
+
|
|
58
|
+
} // namespace proofs
|
|
59
|
+
|
|
60
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_EC_P256K1_H_
|
|
@@ -0,0 +1,503 @@
|
|
|
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_GF2K_GF2_128_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_GF2K_GF2_128_H_
|
|
17
|
+
|
|
18
|
+
#include <stdio.h>
|
|
19
|
+
|
|
20
|
+
#include <array>
|
|
21
|
+
#include <cstddef>
|
|
22
|
+
#include <cstdint>
|
|
23
|
+
#include <functional>
|
|
24
|
+
#include <optional>
|
|
25
|
+
#include <utility>
|
|
26
|
+
|
|
27
|
+
#include "gf2k/gf2poly.h"
|
|
28
|
+
#include "gf2k/sysdep.h"
|
|
29
|
+
#include "util/panic.h"
|
|
30
|
+
|
|
31
|
+
namespace proofs {
|
|
32
|
+
|
|
33
|
+
struct BinaryFieldTypeTag {};
|
|
34
|
+
|
|
35
|
+
template <size_t subfield_log_bits = 4>
|
|
36
|
+
class GF2_128 {
|
|
37
|
+
// avoid writing static_cast<size_t>(1) all the time.
|
|
38
|
+
static constexpr size_t k1 = 1;
|
|
39
|
+
|
|
40
|
+
public:
|
|
41
|
+
using TypeTag = BinaryFieldTypeTag;
|
|
42
|
+
|
|
43
|
+
// Fast representation of the field element via the system-dependent
|
|
44
|
+
// SIMD type.
|
|
45
|
+
using N = gf2_128_elt_t;
|
|
46
|
+
|
|
47
|
+
// "Slow" representation of the field element as array of
|
|
48
|
+
// C++ integral types.
|
|
49
|
+
using N1 = GF2Poly<2>;
|
|
50
|
+
|
|
51
|
+
static constexpr size_t kNPolyEvaluationPoints = 6;
|
|
52
|
+
static constexpr size_t kLogBits = 7;
|
|
53
|
+
static constexpr size_t kBits = k1 << kLogBits;
|
|
54
|
+
static constexpr size_t kBytes = kBits / 8u;
|
|
55
|
+
|
|
56
|
+
static constexpr size_t kSubFieldLogBits = subfield_log_bits;
|
|
57
|
+
static constexpr size_t kSubFieldBits = k1 << kSubFieldLogBits;
|
|
58
|
+
static constexpr size_t kSubFieldBytes = kSubFieldBits / 8u;
|
|
59
|
+
|
|
60
|
+
static_assert(kBits == 8u * kBytes);
|
|
61
|
+
static_assert(kSubFieldBits == 8u * kSubFieldBytes);
|
|
62
|
+
static constexpr bool kCharacteristicTwo = true;
|
|
63
|
+
|
|
64
|
+
struct Elt {
|
|
65
|
+
N n;
|
|
66
|
+
|
|
67
|
+
Elt() : n{} {}
|
|
68
|
+
explicit Elt(N n_) : n(n_) {}
|
|
69
|
+
|
|
70
|
+
// Don't bother using SIMD instructions for comparisons,
|
|
71
|
+
// otherwise we have to complicate the sysdep API surface.
|
|
72
|
+
// Unpack into uint64[2] and compute manually.
|
|
73
|
+
bool operator==(const Elt& y) const { return unpack() == y.unpack(); }
|
|
74
|
+
bool operator!=(const Elt& y) const { return !operator==(y); }
|
|
75
|
+
|
|
76
|
+
// Returns the coefficient of x^i in the polynomial.
|
|
77
|
+
uint8_t operator[](size_t i) const {
|
|
78
|
+
auto n1 = uint64x2_of_gf2_128(n);
|
|
79
|
+
if (i < 64) {
|
|
80
|
+
return static_cast<uint8_t>((n1[0] >> i) & 0x1);
|
|
81
|
+
} else if (i < 128) {
|
|
82
|
+
return static_cast<uint8_t>((n1[1] >> (i - 64)) & 0x1);
|
|
83
|
+
} else {
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
N1 unpack() const { return N1(uint64x2_of_gf2_128(n)); }
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
explicit GF2_128() {
|
|
92
|
+
kone_ = of_scalar_field(0b1);
|
|
93
|
+
kx_ = of_scalar_field(0b10);
|
|
94
|
+
|
|
95
|
+
// x^{-1} = x^127 + x^6 + x + 1
|
|
96
|
+
std::array<uint64_t, 2> invx = {
|
|
97
|
+
(1ull << 6) | (1ull << 1) | (1ull << 0),
|
|
98
|
+
(1ull << (127 - 64)),
|
|
99
|
+
};
|
|
100
|
+
kinvx_ = of_scalar_field(invx);
|
|
101
|
+
|
|
102
|
+
Elt g = subfield_generator();
|
|
103
|
+
kg_ = g;
|
|
104
|
+
kinvg_ = invertf(g);
|
|
105
|
+
|
|
106
|
+
// basis of the subfield = {1, g, g^2, ...}
|
|
107
|
+
beta_[0] = one();
|
|
108
|
+
for (size_t i = 1; i < kSubFieldBits; ++i) {
|
|
109
|
+
beta_[i] = mulf(beta_[i - 1], g);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Reduce the basis to row-echelon form
|
|
113
|
+
beta_ref();
|
|
114
|
+
|
|
115
|
+
// Evaluation points. We use g^i for these as well
|
|
116
|
+
poly_evaluation_points_[0] = zero();
|
|
117
|
+
Elt gi = one();
|
|
118
|
+
for (size_t i = 1; i < kNPolyEvaluationPoints; ++i) {
|
|
119
|
+
poly_evaluation_points_[i] = gi;
|
|
120
|
+
mul(gi, g);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (size_t i = 1; i < kNPolyEvaluationPoints; i++) {
|
|
124
|
+
for (size_t k = kNPolyEvaluationPoints; k-- > i;) {
|
|
125
|
+
auto dx =
|
|
126
|
+
subf(poly_evaluation_points_[k], poly_evaluation_points_[k - i]);
|
|
127
|
+
check(dx != zero(), "dx != zero()");
|
|
128
|
+
newton_denominators_[k][i] = invertf(dx);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// basis of counters
|
|
133
|
+
Elt cgi(g); // = g ^ {2^i}, initially i = 0
|
|
134
|
+
for (size_t i = 0; i < kSubFieldBits; ++i) {
|
|
135
|
+
counter_beta_[i] = cgi;
|
|
136
|
+
mul(cgi, cgi);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
GF2_128(const GF2_128&) = delete;
|
|
141
|
+
GF2_128& operator=(const GF2_128&) = delete;
|
|
142
|
+
|
|
143
|
+
// The bits of u are the coordinates with respect to the basis
|
|
144
|
+
// beta_[] of the subfield.
|
|
145
|
+
Elt of_scalar(uint64_t u) const {
|
|
146
|
+
Elt t = zero();
|
|
147
|
+
for (size_t k = 0; k < kSubFieldBits; ++k, u >>= 1) {
|
|
148
|
+
if (u & 1) {
|
|
149
|
+
add(t, beta_[k]);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
check(u == 0, "of_scalar(u), too many bits");
|
|
153
|
+
return t;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
Elt of_scalar_field(uint64_t n) const {
|
|
157
|
+
std::array<uint64_t, 2> u = {n, 0};
|
|
158
|
+
return of_scalar_field(u);
|
|
159
|
+
}
|
|
160
|
+
Elt of_scalar_field(const std::array<uint64_t, 2>& u) const {
|
|
161
|
+
return Elt(gf2_128_of_uint64x2(u));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// The base_only flag is a placeholder that takes meaning when F is an
|
|
165
|
+
// extension field.
|
|
166
|
+
std::optional<Elt> of_bytes_field(const uint8_t ab[/* kBytes */],
|
|
167
|
+
bool base_only = true) const {
|
|
168
|
+
N1 an = N1::of_bytes(ab);
|
|
169
|
+
return of_scalar_field(an.u64());
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
void to_bytes_field(uint8_t ab[/* kBytes */], const Elt& x) const {
|
|
173
|
+
x.unpack().to_bytes(ab);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
Elt sample(
|
|
177
|
+
const std::function<void(size_t n, uint8_t buf[])>& fill_bytes) const {
|
|
178
|
+
// Every 128-bit sequence is a valid field element.
|
|
179
|
+
uint8_t buf[kBytes];
|
|
180
|
+
fill_bytes(sizeof(buf), buf);
|
|
181
|
+
std::optional<Elt> maybe = of_bytes_field(buf);
|
|
182
|
+
check(maybe.has_value(), "of_bytes_field failed unexpectedly");
|
|
183
|
+
return maybe.value();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
Elt sample_subfield(
|
|
187
|
+
const std::function<void(size_t n, uint8_t buf[])>& fill_bytes) const {
|
|
188
|
+
uint8_t buf[kSubFieldBytes];
|
|
189
|
+
fill_bytes(sizeof(buf), buf);
|
|
190
|
+
std::optional<Elt> maybe = of_bytes_subfield(buf);
|
|
191
|
+
check(maybe.has_value(), "of_bytes_subfield failed unexpectedly");
|
|
192
|
+
return maybe.value();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
bool in_subfield(Elt e) const {
|
|
196
|
+
auto eu = solve(e);
|
|
197
|
+
return eu.first == N1{};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
std::optional<Elt> of_bytes_subfield(
|
|
201
|
+
const uint8_t ab[/* kSubFieldBytes */]) const {
|
|
202
|
+
uint64_t u = 0;
|
|
203
|
+
for (size_t i = kSubFieldBytes; i-- > 0;) {
|
|
204
|
+
u <<= 8;
|
|
205
|
+
u |= ab[i];
|
|
206
|
+
}
|
|
207
|
+
return of_scalar(u);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
void to_bytes_subfield(uint8_t ab[/* kSubFieldBytes */], const Elt& x) const {
|
|
211
|
+
auto eu = solve(x);
|
|
212
|
+
check(eu.first == N1{}, "eu.first == N1{}");
|
|
213
|
+
uint64_t u = eu.second;
|
|
214
|
+
for (size_t i = 0; i < kSubFieldBytes; ++i) {
|
|
215
|
+
ab[i] = u & 0xFFu;
|
|
216
|
+
u >>= 8;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// functional interface
|
|
221
|
+
Elt addf(const Elt& x, const Elt& y) const {
|
|
222
|
+
return Elt{gf2_128_add(x.n, y.n)};
|
|
223
|
+
}
|
|
224
|
+
Elt subf(const Elt& x, const Elt& y) const {
|
|
225
|
+
return Elt{gf2_128_add(x.n, y.n)};
|
|
226
|
+
}
|
|
227
|
+
Elt mulf(const Elt& x, const Elt& y) const {
|
|
228
|
+
return Elt{gf2_128_mul(x.n, y.n)};
|
|
229
|
+
}
|
|
230
|
+
Elt negf(const Elt& x) const { return x; }
|
|
231
|
+
|
|
232
|
+
// two-operands interface
|
|
233
|
+
void add(Elt& a, const Elt& y) const { a = addf(a, y); }
|
|
234
|
+
void sub(Elt& a, const Elt& y) const { a = subf(a, y); }
|
|
235
|
+
void mul(Elt& a, const Elt& y) const { a = mulf(a, y); }
|
|
236
|
+
void neg(Elt& a) const { /* noop */ }
|
|
237
|
+
void invert(Elt& a) const { a = invertf(a); }
|
|
238
|
+
|
|
239
|
+
Elt zero() const { return Elt{}; }
|
|
240
|
+
Elt one() const { return kone_; }
|
|
241
|
+
Elt mone() const { return kone_; }
|
|
242
|
+
Elt x() const { return kx_; }
|
|
243
|
+
Elt invx() const { return kinvx_; }
|
|
244
|
+
Elt g() const { return kg_; }
|
|
245
|
+
Elt invg() const { return kinvg_; }
|
|
246
|
+
Elt beta(size_t i) const {
|
|
247
|
+
check(i < kSubFieldBits, "i < kSubFieldBits");
|
|
248
|
+
return beta_[i];
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
Elt poly_evaluation_point(size_t i) const {
|
|
252
|
+
check(i < kNPolyEvaluationPoints, "i < kNPolyEvaluationPoints");
|
|
253
|
+
return poly_evaluation_points_[i];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// return (X[k] - X[k - i])^{-1}, were X[i] is the
|
|
257
|
+
// i-th poly evalaluation point.
|
|
258
|
+
Elt newton_denominator(size_t k, size_t i) const {
|
|
259
|
+
check(k < kNPolyEvaluationPoints, "k < kNPolyEvaluationPoints");
|
|
260
|
+
check(i <= k, "i <= k");
|
|
261
|
+
check(k != (k - i), "k != (k - i)");
|
|
262
|
+
return newton_denominators_[k][i];
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
Elt invertf(Elt x) const {
|
|
266
|
+
N1 a = x.unpack();
|
|
267
|
+
// Let POLY be the generator of GF(2^128) as GF(2)[x]/(POLY(x)).
|
|
268
|
+
// The Euclid algorithm would initialize B = POLY, but we cannot
|
|
269
|
+
// store POLY in one N1. Instead, we use the invariant that B is
|
|
270
|
+
// always "odd" throughout the algorithm, and we represent B =
|
|
271
|
+
// BM1OX * X + 1, or BM1OX = (B - 1) / X. For B = POLY, BM1OX =
|
|
272
|
+
// 1/X initially.
|
|
273
|
+
N1 bm1ox = kinvx_.unpack();
|
|
274
|
+
Elt u = one();
|
|
275
|
+
Elt v = zero();
|
|
276
|
+
while (a != N1(0)) {
|
|
277
|
+
if (a.bit(0) == 0) {
|
|
278
|
+
a.shiftr(1);
|
|
279
|
+
byinvx(u);
|
|
280
|
+
} else {
|
|
281
|
+
// Now A is "odd". Write A = AM1OX * X + 1. This operation
|
|
282
|
+
// be done in-place in the A variable, but we use another
|
|
283
|
+
// name for clarity.
|
|
284
|
+
N1 am1ox = a;
|
|
285
|
+
am1ox.shiftr(1);
|
|
286
|
+
|
|
287
|
+
// Normalize to the partial order degree(A) >= degree(B).
|
|
288
|
+
// We use the stronger total order "<" which is consistent
|
|
289
|
+
// with the partial order that we care about.
|
|
290
|
+
if (am1ox < bm1ox) {
|
|
291
|
+
std::swap(am1ox, bm1ox);
|
|
292
|
+
std::swap(u, v);
|
|
293
|
+
}
|
|
294
|
+
am1ox.sub(bm1ox);
|
|
295
|
+
sub(u, v);
|
|
296
|
+
byinvx(u);
|
|
297
|
+
a = am1ox;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return v;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Type for counters. We represent unsigned integer n as g^n
|
|
304
|
+
// where g is the generator of the subfield.
|
|
305
|
+
struct CElt {
|
|
306
|
+
Elt e;
|
|
307
|
+
|
|
308
|
+
bool operator==(const CElt& y) const { return e == y.e; }
|
|
309
|
+
bool operator!=(const CElt& y) const { return !operator==(y); }
|
|
310
|
+
};
|
|
311
|
+
CElt as_counter(uint64_t a) const {
|
|
312
|
+
// 2^{bits} - 2 fits, 2^{bits} - 1 does not
|
|
313
|
+
check((a + 1u) != 0, "as_counter() arg too large");
|
|
314
|
+
check(((a + 1u) >> kSubFieldBits) == 0, "as_counter() arg too large");
|
|
315
|
+
Elt r(one());
|
|
316
|
+
for (size_t i = 0; i < kSubFieldBits; ++i) {
|
|
317
|
+
if ((a >> i) & 1) {
|
|
318
|
+
mul(r, counter_beta(i));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return CElt{r};
|
|
322
|
+
}
|
|
323
|
+
Elt counter_beta(size_t i) const {
|
|
324
|
+
check(i < kSubFieldBits, "i < kSubFieldBits");
|
|
325
|
+
return counter_beta_[i];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Convert a counter into *some* field element such that the counter is
|
|
329
|
+
// zero (as a counter) iff the field element is zero. Since
|
|
330
|
+
// n as a counter is g^n, we have ((g^n - 1) = 0) <=> (n = 0)
|
|
331
|
+
Elt znz_indicator(const CElt& celt) const { return subf(celt.e, one()); }
|
|
332
|
+
|
|
333
|
+
private:
|
|
334
|
+
Elt kone_;
|
|
335
|
+
Elt kx_;
|
|
336
|
+
Elt kinvx_; // x^{-1}
|
|
337
|
+
Elt kg_;
|
|
338
|
+
Elt kinvg_; // g^{-1}
|
|
339
|
+
Elt beta_[kSubFieldBits]; // basis of the subfield viewed as a
|
|
340
|
+
// vector space over GF(2)
|
|
341
|
+
Elt counter_beta_[kSubFieldBits]; // basis of the multiplicative group
|
|
342
|
+
// of counters.
|
|
343
|
+
|
|
344
|
+
// LU decomposition of beta_, in unpacked format. We store L^{-1}
|
|
345
|
+
// instead of L, see comments in beta_ref()
|
|
346
|
+
N1 u_[kSubFieldBits];
|
|
347
|
+
uint64_t linv_[kSubFieldBits];
|
|
348
|
+
|
|
349
|
+
// ldnz_[i] stores the column index of the leading nonzero in u_[i].
|
|
350
|
+
// This array is in principle redundant, since one can always
|
|
351
|
+
// reconstruct it from u_, but we cache it for efficiency.
|
|
352
|
+
size_t ldnz_[kSubFieldBits];
|
|
353
|
+
|
|
354
|
+
Elt poly_evaluation_points_[kNPolyEvaluationPoints];
|
|
355
|
+
Elt newton_denominators_[kNPolyEvaluationPoints][kNPolyEvaluationPoints];
|
|
356
|
+
|
|
357
|
+
void byinvx(Elt& u) const { mul(u, kinvx_); }
|
|
358
|
+
|
|
359
|
+
Elt subfield_generator() {
|
|
360
|
+
// Let k = kSubFieldLogBits and n = kLogBits.
|
|
361
|
+
// Let x be the generator of Field.
|
|
362
|
+
|
|
363
|
+
// The generator r of the subfield is then
|
|
364
|
+
// x^{(2^{2^n}-1)/(2^{2^k}-1)}
|
|
365
|
+
|
|
366
|
+
// Compute r via the identity
|
|
367
|
+
// (2^{2^n}-1)/(2^{2^k}-1) =
|
|
368
|
+
// (2^{2^k}+1)*(2^{2^(k+1)}+1)*...*(2^{2^(n-1)}+1)
|
|
369
|
+
Elt r(kx_);
|
|
370
|
+
for (size_t i = kSubFieldLogBits; i < kLogBits; ++i) {
|
|
371
|
+
// s <- r^{2^(2^i))
|
|
372
|
+
Elt s(r);
|
|
373
|
+
for (size_t j = 0; j < (1u << i); ++j) {
|
|
374
|
+
mul(s, s);
|
|
375
|
+
}
|
|
376
|
+
// r <- r^{2^(2^i)+1)
|
|
377
|
+
mul(r, s);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return r;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// beta_ref() is a just a variant of Gaussian elimination, but
|
|
384
|
+
// because many such variants exist, we now explain the exact
|
|
385
|
+
// mechanics of the algorithm.
|
|
386
|
+
//
|
|
387
|
+
// The problem that we need to solve is the inversion of
|
|
388
|
+
// of_scalar(): given e = of_scalar(u), solve for u. The constraint
|
|
389
|
+
// we have is that e and u are arrays of bits, conveniently stored
|
|
390
|
+
// in uint64_t, and ideally we want to perform parallel bitwise
|
|
391
|
+
// operations, as opposed to extracting individual bits.
|
|
392
|
+
//
|
|
393
|
+
// Consider the following block matrix, or tableau:
|
|
394
|
+
//
|
|
395
|
+
// [ B | -I ]
|
|
396
|
+
// [ ------ ]
|
|
397
|
+
// [ e | u ]
|
|
398
|
+
//
|
|
399
|
+
// Here e and u are reinterpreted as row vectors of GF(2) elements;
|
|
400
|
+
// I is the identity matrix; B is such that B[i] (the i-th row of b)
|
|
401
|
+
// is beta(i) (the i-th element of the basis of the subfield), and
|
|
402
|
+
// beta(i) is interpreted as a row vector of 128 GF(2) elements.
|
|
403
|
+
// (The minus sign in -I is irrelevant over GF(2), but would be
|
|
404
|
+
// necessary over other fields.)
|
|
405
|
+
//
|
|
406
|
+
// We now postulate that the only allowed operation on the tableau
|
|
407
|
+
// is "axpy": add one row to another, which we can do efficiently
|
|
408
|
+
// via bitwise xor.
|
|
409
|
+
//
|
|
410
|
+
// of_scalar(u) can be reinterpreted in terms axpy as follows.
|
|
411
|
+
// Start with a tableau with e=0. Reduce u to 0 via axpy
|
|
412
|
+
// operations, e.g., for all i such that u[i] = 1, add row i to the
|
|
413
|
+
// last row. Because this is exactly what of_scalar() does, at the
|
|
414
|
+
// end of the process we have e = of_scalar(u). Because I is
|
|
415
|
+
// full-rank, any sequence of axpy's that reduces u to 0 produces
|
|
416
|
+
// the same e.
|
|
417
|
+
//
|
|
418
|
+
// We now want to invert the of_scalar() process. We cannot apply
|
|
419
|
+
// the axpy operations in of_scalar() in reverse order, because we
|
|
420
|
+
// don't know u, and thus we don't know which operations
|
|
421
|
+
// of_scalar(u) would apply. However, because B is a basis, any
|
|
422
|
+
// sequence of axpy operations that starts with u=0 and reduces e to
|
|
423
|
+
// 0 reconstructs the same u.
|
|
424
|
+
//
|
|
425
|
+
// For lack of a better idea, we choose the following sequence of
|
|
426
|
+
// axpy operations. First reduce B to row-echelon form via axpy
|
|
427
|
+
// operations on B, and then reduce e to zero via additional axpy
|
|
428
|
+
// operations. A matrix U is in row-echelon form if the following
|
|
429
|
+
// condition holds: i' > i implies that U[i'][ldnz[i]] = 0, where
|
|
430
|
+
// ldnz[i] is the column index of the leading nonzero in row i.
|
|
431
|
+
//
|
|
432
|
+
// Since B is constant, we choose to pre-compute the row-echelon
|
|
433
|
+
// form of B in beta_ref(), and finish the process in solve() when e
|
|
434
|
+
// is known, for multiple values of e.
|
|
435
|
+
//
|
|
436
|
+
// As it happens, reducing B to row-echelon transforms the -I
|
|
437
|
+
// in the upper-right block to -L^{-1}, where B=LU is the LU
|
|
438
|
+
// factorization of B. We don't use this correspondence anywhere
|
|
439
|
+
// in the code other than in the choice of the name Linv for the block.
|
|
440
|
+
//
|
|
441
|
+
void beta_ref() {
|
|
442
|
+
for (size_t i = 0; i < kSubFieldBits; ++i) {
|
|
443
|
+
// B in the tableau, becomes U at the end.
|
|
444
|
+
u_[i] = beta_[i].unpack();
|
|
445
|
+
|
|
446
|
+
// -I in the tableau, becomes -L^{-1} at the end.
|
|
447
|
+
// Ignore the minus sign over GF(2).
|
|
448
|
+
linv_[i] = (static_cast<uint64_t>(1) << i);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Reduce B to row-echelon form.
|
|
452
|
+
//
|
|
453
|
+
// Invariant: B([0,RNK), [0,J)) is already in row-echelon form.
|
|
454
|
+
// The loop body extends this property to J+1 and possibly RNK+1.
|
|
455
|
+
size_t rnk = 0;
|
|
456
|
+
for (size_t j = 0; rnk < kSubFieldBits && j < kBits; ++j) {
|
|
457
|
+
// find pivot at row >= RNK in column J
|
|
458
|
+
for (size_t i = rnk; i < kSubFieldBits; ++i) {
|
|
459
|
+
if (u_[i].bit(j)) {
|
|
460
|
+
std::swap(u_[rnk], u_[i]);
|
|
461
|
+
std::swap(linv_[rnk], linv_[i]);
|
|
462
|
+
goto have_pivot;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
// If we get here there is no pivot. Keep the rank RNK the same
|
|
466
|
+
// and proceed to the next column ++J
|
|
467
|
+
continue;
|
|
468
|
+
|
|
469
|
+
have_pivot:
|
|
470
|
+
ldnz_[rnk] = j;
|
|
471
|
+
|
|
472
|
+
// Pivot on [rnk][j].
|
|
473
|
+
for (size_t i1 = rnk + 1; i1 < kSubFieldBits; ++i1) {
|
|
474
|
+
if (u_[i1].bit(j)) {
|
|
475
|
+
u_[i1].add(u_[rnk]); // axpy on U
|
|
476
|
+
linv_[i1] ^= linv_[rnk]; // axpy on Linv
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
++rnk;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// the basis is indeed a basis:
|
|
483
|
+
check(rnk == kSubFieldBits, "rnk == kSubFieldBits");
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
std::pair<N1, uint64_t> solve(const Elt& e) const {
|
|
487
|
+
uint64_t u = 0;
|
|
488
|
+
N1 ue = e.unpack();
|
|
489
|
+
for (size_t rnk = 0; rnk < kSubFieldBits; ++rnk) {
|
|
490
|
+
size_t j = ldnz_[rnk];
|
|
491
|
+
if (ue.bit(j)) {
|
|
492
|
+
ue.add(u_[rnk]);
|
|
493
|
+
u ^= linv_[rnk];
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return std::pair(ue, u);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
} // namespace proofs
|
|
502
|
+
|
|
503
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_GF2K_GF2_128_H_
|
|
@@ -0,0 +1,48 @@
|
|
|
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 <cstddef>
|
|
16
|
+
|
|
17
|
+
#include "gf2k/gf2_128.h"
|
|
18
|
+
#include "third_party/benchmark/include/benchmark/benchmark.h"
|
|
19
|
+
|
|
20
|
+
namespace proofs {
|
|
21
|
+
using Field = GF2_128<>;
|
|
22
|
+
using Elt = Field::Elt;
|
|
23
|
+
static const Field F;
|
|
24
|
+
|
|
25
|
+
void BM_gf2_128(benchmark::State& state) {
|
|
26
|
+
Elt x = F.of_scalar(2);
|
|
27
|
+
Elt y[1000];
|
|
28
|
+
for (auto _ : state) {
|
|
29
|
+
benchmark::DoNotOptimize(&x);
|
|
30
|
+
for (size_t j = 0; j < 1000; ++j) {
|
|
31
|
+
y[j] = x;
|
|
32
|
+
x = F.mulf(x, x);
|
|
33
|
+
}
|
|
34
|
+
for (size_t i = 0; i < 1000 * 1000; ++i) {
|
|
35
|
+
for (size_t j = 0; j < 1000; ++j) {
|
|
36
|
+
y[j] = F.mulf(y[j], x);
|
|
37
|
+
}
|
|
38
|
+
x = F.mulf(x, x);
|
|
39
|
+
}
|
|
40
|
+
for (size_t j = 0; j < 1000; ++j) {
|
|
41
|
+
x = F.mulf(y[j], x);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
BENCHMARK(BM_gf2_128);
|
|
46
|
+
} // namespace proofs
|
|
47
|
+
|
|
48
|
+
BENCHMARK_MAIN();
|