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,246 @@
|
|
|
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 "gf2k/lch14.h"
|
|
16
|
+
|
|
17
|
+
#include <algorithm>
|
|
18
|
+
#include <cstddef>
|
|
19
|
+
#include <cstdint>
|
|
20
|
+
#include <vector>
|
|
21
|
+
|
|
22
|
+
#include "algebra/interpolation.h"
|
|
23
|
+
#include "algebra/poly.h"
|
|
24
|
+
#include "gf2k/gf2_128.h"
|
|
25
|
+
#include "benchmark/benchmark.h"
|
|
26
|
+
#include "gtest/gtest.h"
|
|
27
|
+
|
|
28
|
+
namespace proofs {
|
|
29
|
+
namespace {
|
|
30
|
+
|
|
31
|
+
using Field = GF2_128<5>;
|
|
32
|
+
using Elt = Field::Elt;
|
|
33
|
+
static const Field F;
|
|
34
|
+
static const LCH14<Field> FFT(F);
|
|
35
|
+
|
|
36
|
+
// The "subspace vanishing polynomial"
|
|
37
|
+
//
|
|
38
|
+
// W_i(X) = PROD_{u \in U_i} (X − u)
|
|
39
|
+
//
|
|
40
|
+
// where we axiomatically identify
|
|
41
|
+
// U_i = { f_.of_scalar(j) : 0 <= j < 2^i }
|
|
42
|
+
|
|
43
|
+
// slow reference implementation
|
|
44
|
+
static Elt WRef(size_t i, const Elt &x) {
|
|
45
|
+
constexpr uint64_t uno = 1; // for the uint64_t type
|
|
46
|
+
Elt prod = F.one();
|
|
47
|
+
for (size_t j = 0; j < (uno << i); ++j) {
|
|
48
|
+
F.mul(prod, F.subf(x, F.of_scalar(j)));
|
|
49
|
+
}
|
|
50
|
+
return prod;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static Elt WHatRef(size_t i, const Elt &x) {
|
|
54
|
+
return F.mulf(WRef(i, x), F.invertf(WRef(i, F.beta(i))));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
TEST(LCH14, WAdditivity) {
|
|
58
|
+
size_t r = 6;
|
|
59
|
+
for (size_t i = 0; i < r; ++i) {
|
|
60
|
+
for (size_t x = 0; x < (1 << r); ++x) {
|
|
61
|
+
Elt xx = F.of_scalar(x);
|
|
62
|
+
Elt wx = WRef(i, xx);
|
|
63
|
+
|
|
64
|
+
// W is supposed to vanish on the i-dimensional
|
|
65
|
+
// subspace and nowhere else:
|
|
66
|
+
if (x < (1 << i)) {
|
|
67
|
+
EXPECT_EQ(wx, F.zero());
|
|
68
|
+
} else {
|
|
69
|
+
EXPECT_NE(wx, F.zero());
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// [LCH14 Lemma 1] W(x + y) = W(x) + W(y)
|
|
73
|
+
for (size_t y = 0; y < (1 << r); ++y) {
|
|
74
|
+
Elt yy = F.of_scalar(y);
|
|
75
|
+
EXPECT_EQ(WRef(i, F.addf(xx, yy)), F.addf(WRef(i, xx), WRef(i, yy)));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// We use the identity
|
|
82
|
+
//
|
|
83
|
+
// W_{i+1}(X) = W_i(X)(W_i(X)+W_i(\beta_i))
|
|
84
|
+
//
|
|
85
|
+
// See Shuhong Gao and Todd Mateer, "Additive Fast Fourier Transforms
|
|
86
|
+
// over Finite Fields", who credit [Cantor 1989]. The same formula is
|
|
87
|
+
// used in twiddle.rs in the Binius source code. See also Todd
|
|
88
|
+
// D. Mateer, "Fast Fourier Transform Algorithms with Applications,"
|
|
89
|
+
// PhD Dissertation, Theorem 15 for an extended discussion.
|
|
90
|
+
//
|
|
91
|
+
// Proof: Because W is zero over the subspace, we have
|
|
92
|
+
// W_{i+1}(X) = W_i(X) * W_i(X + \beta_i)
|
|
93
|
+
// Because W(X+Y) = W(X) + W(Y), we have
|
|
94
|
+
// W_i(X + \beta_i) = W_i(X) + W_i(\beta_i).
|
|
95
|
+
//
|
|
96
|
+
TEST(LCH14, WRecursion) {
|
|
97
|
+
size_t r = 6;
|
|
98
|
+
for (size_t i = 0; i < r; ++i) {
|
|
99
|
+
Elt wibi = WRef(i, F.beta(i));
|
|
100
|
+
for (size_t x = 0; x < (1 << r); ++x) {
|
|
101
|
+
Elt xx = F.of_scalar(x);
|
|
102
|
+
Elt wix = WRef(i, xx);
|
|
103
|
+
Elt wi1x = WRef(i + 1, xx);
|
|
104
|
+
EXPECT_EQ(wi1x, F.mulf(wix, F.addf(wix, wibi)));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
TEST(LCH14, WHat) {
|
|
110
|
+
// limit I because WHatRef() is exponential-time in I.
|
|
111
|
+
for (size_t i = 0; i < std::min<size_t>(FFT.kSubFieldBits, 16); ++i) {
|
|
112
|
+
for (size_t j = 0; j < FFT.kSubFieldBits; ++j) {
|
|
113
|
+
EXPECT_EQ(FFT.WHat_DEBUG(i, j), WHatRef(i, F.beta(j)));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
TEST(LCH14, Twiddle) {
|
|
119
|
+
size_t l = std::min<size_t>(FFT.kSubFieldBits, 20);
|
|
120
|
+
constexpr size_t uno = 1;
|
|
121
|
+
std::vector<Elt> tw(uno << (l - 1));
|
|
122
|
+
for (size_t i = 0; i < l; ++i) {
|
|
123
|
+
FFT.twiddles(i, l, 0, &tw[0]);
|
|
124
|
+
for (size_t u = 0; (u << (i + 1)) < (uno << l); ++u) {
|
|
125
|
+
EXPECT_EQ(tw[u], FFT.twiddle(i, (u << (i + 1))));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
TEST(LCH14, Interpolation) {
|
|
131
|
+
constexpr size_t l = 5;
|
|
132
|
+
constexpr size_t cosets = 7;
|
|
133
|
+
constexpr size_t n = 1 << l;
|
|
134
|
+
|
|
135
|
+
using Interp = Interpolation<n, Field>;
|
|
136
|
+
using Poly = Poly<n, Field>;
|
|
137
|
+
|
|
138
|
+
// check interpolations from all cosets CA to
|
|
139
|
+
// all cosets CB
|
|
140
|
+
for (size_t ca = 0; ca < cosets; ++ca) {
|
|
141
|
+
Poly X, A;
|
|
142
|
+
for (size_t i = 0; i < n; ++i) {
|
|
143
|
+
X[i] = F.of_scalar(i + (ca << l));
|
|
144
|
+
A[i] = F.of_scalar((i * (i + ca)) ^ 42); // "random"
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
Poly Newton = Interp::newton_of_lagrange(A, X, F);
|
|
148
|
+
|
|
149
|
+
FFT.IFFT(l, (ca << l), A.t_);
|
|
150
|
+
|
|
151
|
+
for (size_t cb = 0; cb < cosets; ++cb) {
|
|
152
|
+
Poly B = A;
|
|
153
|
+
|
|
154
|
+
FFT.FFT(l, (cb << l), B.t_);
|
|
155
|
+
for (size_t i = 0; i < n; ++i) {
|
|
156
|
+
EXPECT_EQ(B[i], Interp::eval_newton(Newton, X,
|
|
157
|
+
F.of_scalar(i + (cb << l)), F));
|
|
158
|
+
EXPECT_TRUE(F.in_subfield(B[i]));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
TEST(LCH14, BidirectionalFFT) {
|
|
165
|
+
constexpr size_t l = 10;
|
|
166
|
+
constexpr size_t n = 1 << l;
|
|
167
|
+
|
|
168
|
+
for (size_t k = 0; k <= n; ++k) {
|
|
169
|
+
std::vector<Elt> C(n); // "coefficients"
|
|
170
|
+
std::vector<Elt> E(n); // "evaluations"
|
|
171
|
+
|
|
172
|
+
for (size_t i = 0; i < n; ++i) {
|
|
173
|
+
E[i] = C[i] = F.of_scalar((i * i + 42) & 0xFFFFu);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// forward FFT from "coefficients" to evaluations, in-place
|
|
177
|
+
FFT.FFT(l, 0, &E[0]);
|
|
178
|
+
|
|
179
|
+
std::vector<Elt> B(n);
|
|
180
|
+
|
|
181
|
+
// evaluations in the first half, "coefficients" in the second half
|
|
182
|
+
for (size_t i = 0; i < n; ++i) {
|
|
183
|
+
B[i] = (i < k) ? E[i] : C[i];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
FFT.BidirectionalFFT(l, k, &B[0]);
|
|
187
|
+
|
|
188
|
+
// Expect "coefficients" in the first half, evaluations in the second half
|
|
189
|
+
for (size_t i = 0; i < n; ++i) {
|
|
190
|
+
EXPECT_EQ(B[i], (i < k) ? C[i] : E[i]);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// =============================================================================
|
|
196
|
+
// Benchmarks
|
|
197
|
+
// =============================================================================
|
|
198
|
+
|
|
199
|
+
void BM_LCH14_FFT(benchmark::State& state) {
|
|
200
|
+
size_t l = state.range(0);
|
|
201
|
+
size_t N = 1 << l;
|
|
202
|
+
std::vector<Elt> A(N);
|
|
203
|
+
for (size_t i = 0; i < N; ++i) {
|
|
204
|
+
A[i] = F.x();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
for (auto _ : state) {
|
|
208
|
+
FFT.FFT(l, /*coset=*/0, A.data());
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
BENCHMARK(BM_LCH14_FFT)->DenseRange(10, 22, 2);
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
void BM_LCH14_IFFT(benchmark::State& state) {
|
|
216
|
+
size_t l = state.range(0);
|
|
217
|
+
size_t N = 1 << l;
|
|
218
|
+
std::vector<Elt> A(N);
|
|
219
|
+
for (size_t i = 0; i < N; ++i) {
|
|
220
|
+
A[i] = F.x();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
for (auto _ : state) {
|
|
224
|
+
FFT.IFFT(l, /*coset=*/0, A.data());
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
BENCHMARK(BM_LCH14_IFFT)->DenseRange(10, 22, 2);
|
|
229
|
+
|
|
230
|
+
void BM_LCH14_BidirectionalFFT(benchmark::State& state) {
|
|
231
|
+
size_t l = state.range(0);
|
|
232
|
+
size_t N = 1 << l;
|
|
233
|
+
std::vector<Elt> A(N);
|
|
234
|
+
for (size_t i = 0; i < N; ++i) {
|
|
235
|
+
A[i] = F.x();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
for (auto _ : state) {
|
|
239
|
+
FFT.BidirectionalFFT(l, /*k=*/N - 1, A.data());
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
BENCHMARK(BM_LCH14_BidirectionalFFT)->DenseRange(10, 22, 2);
|
|
244
|
+
|
|
245
|
+
} // namespace
|
|
246
|
+
} // namespace proofs
|
|
@@ -0,0 +1,329 @@
|
|
|
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_SYSDEP_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_GF2K_SYSDEP_H_
|
|
17
|
+
|
|
18
|
+
#include <stddef.h>
|
|
19
|
+
#include <stdint.h>
|
|
20
|
+
|
|
21
|
+
#include <array>
|
|
22
|
+
|
|
23
|
+
// Hardcoded GF(2^128) SIMD arithmetic where
|
|
24
|
+
// GF(2^128) = GF(2)[x] / (x^128 + x^7 + x^2 + x + 1)
|
|
25
|
+
|
|
26
|
+
#if defined(__x86_64__) || defined(__i386__)
|
|
27
|
+
#include <immintrin.h> // IWYU pragma: keep
|
|
28
|
+
|
|
29
|
+
namespace proofs {
|
|
30
|
+
|
|
31
|
+
using gf2_128_elt_t = __m128i;
|
|
32
|
+
|
|
33
|
+
static inline std::array<uint64_t, 2> uint64x2_of_gf2_128(gf2_128_elt_t x) {
|
|
34
|
+
return std::array<uint64_t, 2>{static_cast<uint64_t>(x[0]),
|
|
35
|
+
static_cast<uint64_t>(x[1])};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static inline gf2_128_elt_t gf2_128_of_uint64x2(
|
|
39
|
+
const std::array<uint64_t, 2> &x) {
|
|
40
|
+
// Cast to long long (as opposed to int64_t) is necessary because __m128i is
|
|
41
|
+
// defined in terms of long long.
|
|
42
|
+
return gf2_128_elt_t{static_cast<long long>(x[0]),
|
|
43
|
+
static_cast<long long>(x[1])};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static inline gf2_128_elt_t gf2_128_add(gf2_128_elt_t x, gf2_128_elt_t y) {
|
|
47
|
+
return _mm_xor_si128(x, y);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// return t0 + x^64 * t1
|
|
51
|
+
static inline gf2_128_elt_t gf2_128_reduce(gf2_128_elt_t t0, gf2_128_elt_t t1) {
|
|
52
|
+
const gf2_128_elt_t poly = {0x87};
|
|
53
|
+
t0 = _mm_xor_si128(t0, _mm_slli_si128(t1, 64 /*bits*/ / 8 /*bits/byte*/));
|
|
54
|
+
t0 = _mm_xor_si128(t0, _mm_clmulepi64_si128(t1, poly, 0x01));
|
|
55
|
+
return t0;
|
|
56
|
+
}
|
|
57
|
+
static inline gf2_128_elt_t gf2_128_mul(gf2_128_elt_t x, gf2_128_elt_t y) {
|
|
58
|
+
gf2_128_elt_t t1a = _mm_clmulepi64_si128(x, y, 0x01);
|
|
59
|
+
gf2_128_elt_t t1b = _mm_clmulepi64_si128(x, y, 0x10);
|
|
60
|
+
gf2_128_elt_t t1 = gf2_128_add(t1a, t1b);
|
|
61
|
+
gf2_128_elt_t t2 = _mm_clmulepi64_si128(x, y, 0x11);
|
|
62
|
+
t1 = gf2_128_reduce(t1, t2);
|
|
63
|
+
gf2_128_elt_t t0 = _mm_clmulepi64_si128(x, y, 0x00);
|
|
64
|
+
t0 = gf2_128_reduce(t0, t1);
|
|
65
|
+
return t0;
|
|
66
|
+
}
|
|
67
|
+
} // namespace proofs
|
|
68
|
+
#elif defined(__aarch64__)
|
|
69
|
+
//
|
|
70
|
+
// Implementation for arm/neon with AES instructions.
|
|
71
|
+
// We assume that __aarch64__ implies AES, which isn't necessarily
|
|
72
|
+
// the case. If this is a problem, change the defined(__aarch64__)
|
|
73
|
+
// above and the code will fall back to the non-AES implementation
|
|
74
|
+
// below.
|
|
75
|
+
//
|
|
76
|
+
#include <arm_neon.h> // IWYU pragma: keep
|
|
77
|
+
|
|
78
|
+
namespace proofs {
|
|
79
|
+
using gf2_128_elt_t = poly64x2_t;
|
|
80
|
+
|
|
81
|
+
static inline std::array<uint64_t, 2> uint64x2_of_gf2_128(gf2_128_elt_t x) {
|
|
82
|
+
return std::array<uint64_t, 2>{static_cast<uint64_t>(x[0]),
|
|
83
|
+
static_cast<uint64_t>(x[1])};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static inline gf2_128_elt_t gf2_128_of_uint64x2(
|
|
87
|
+
const std::array<uint64_t, 2>& x) {
|
|
88
|
+
return gf2_128_elt_t{static_cast<poly64_t>(x[0]),
|
|
89
|
+
static_cast<poly64_t>(x[1])};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static inline gf2_128_elt_t vmull_low(gf2_128_elt_t t0, gf2_128_elt_t t1) {
|
|
93
|
+
poly64_t tt0 = vgetq_lane_p64(t0, 0);
|
|
94
|
+
poly64_t tt1 = vgetq_lane_p64(t1, 0);
|
|
95
|
+
return vreinterpretq_p64_p128(vmull_p64(tt0, tt1));
|
|
96
|
+
}
|
|
97
|
+
static inline gf2_128_elt_t vmull_high(gf2_128_elt_t t0, gf2_128_elt_t t1) {
|
|
98
|
+
return vreinterpretq_p64_p128(vmull_high_p64(t0, t1));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// return t0 + x^64 * t1
|
|
102
|
+
static inline gf2_128_elt_t gf2_128_reduce(gf2_128_elt_t t0, gf2_128_elt_t t1) {
|
|
103
|
+
const gf2_128_elt_t poly = {0x0, 0x87};
|
|
104
|
+
const gf2_128_elt_t zero = {0x0, 0x0};
|
|
105
|
+
t0 = vaddq_p64(t0, vextq_p64(zero, t1, 1));
|
|
106
|
+
t0 = vaddq_p64(t0, vmull_high(t1, poly));
|
|
107
|
+
return t0;
|
|
108
|
+
}
|
|
109
|
+
static inline gf2_128_elt_t gf2_128_add(gf2_128_elt_t x, gf2_128_elt_t y) {
|
|
110
|
+
return vaddq_p64(x, y);
|
|
111
|
+
}
|
|
112
|
+
static inline gf2_128_elt_t gf2_128_mul(gf2_128_elt_t x, gf2_128_elt_t y) {
|
|
113
|
+
gf2_128_elt_t swx = vextq_p64(x, x, 1);
|
|
114
|
+
gf2_128_elt_t t1a = vmull_high(swx, y);
|
|
115
|
+
gf2_128_elt_t t1b = vmull_low(swx, y);
|
|
116
|
+
gf2_128_elt_t t1 = vaddq_p64(t1a, t1b);
|
|
117
|
+
gf2_128_elt_t t2 = vmull_high(x, y);
|
|
118
|
+
t1 = gf2_128_reduce(t1, t2);
|
|
119
|
+
gf2_128_elt_t t0 = vmull_low(x, y);
|
|
120
|
+
t0 = gf2_128_reduce(t0, t1);
|
|
121
|
+
return t0;
|
|
122
|
+
}
|
|
123
|
+
} // namespace proofs
|
|
124
|
+
|
|
125
|
+
#elif defined(__arm__) || defined(__aarch64__)
|
|
126
|
+
//
|
|
127
|
+
// Implementation for arm/neon without AES instructions
|
|
128
|
+
//
|
|
129
|
+
#include <arm_neon.h> // IWYU pragma: keep
|
|
130
|
+
|
|
131
|
+
namespace proofs {
|
|
132
|
+
using gf2_128_elt_t = poly64x2_t;
|
|
133
|
+
|
|
134
|
+
static inline std::array<uint64_t, 2> uint64x2_of_gf2_128(gf2_128_elt_t x) {
|
|
135
|
+
return std::array<uint64_t, 2>{static_cast<uint64_t>(x[0]),
|
|
136
|
+
static_cast<uint64_t>(x[1])};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static inline gf2_128_elt_t gf2_128_of_uint64x2(
|
|
140
|
+
const std::array<uint64_t, 2>& x) {
|
|
141
|
+
return gf2_128_elt_t{static_cast<poly64_t>(x[0]),
|
|
142
|
+
static_cast<poly64_t>(x[1])};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static inline gf2_128_elt_t gf2_128_add(gf2_128_elt_t x, gf2_128_elt_t y) {
|
|
146
|
+
return vaddq_p64(x, y);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Emulate vmull_p64() with vmull_p8().
|
|
150
|
+
//
|
|
151
|
+
// This emulation is pretty naive and it performs a lot of permutations.
|
|
152
|
+
//
|
|
153
|
+
// A possibly better alternative appears in Danilo Câmara, Conrado
|
|
154
|
+
// Gouvêa, Julio López, Ricardo Dahab, "Fast Software Polynomial
|
|
155
|
+
// Multiplication on ARM Processors Using the NEON Engine", 1st
|
|
156
|
+
// Cross-Domain Conference and Workshop on Availability, Reliability,
|
|
157
|
+
// and Security in Information Systems (CD-ARES), Sep 2013,
|
|
158
|
+
// Regensburg, Germany. pp.137-154. ⟨hal-01506572⟩
|
|
159
|
+
//
|
|
160
|
+
// However, the code from that paper makes heavy use of type
|
|
161
|
+
// punning of 128-bit registers as two 64-bit registers, which
|
|
162
|
+
// I don't know how to express in C.
|
|
163
|
+
static inline poly8x16_t pmul64x8(poly8x8_t x, poly8_t y) {
|
|
164
|
+
const poly8x16_t zero{};
|
|
165
|
+
poly8x16_t prod = vmull_p8(x, vdup_n_p8(y));
|
|
166
|
+
poly8x16x2_t uzp = vuzpq_p8(prod, zero);
|
|
167
|
+
return vaddq_p8(uzp.val[0], vextq_p8(uzp.val[1], uzp.val[1], 15));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// multiply/add. Return (cout, s) = cin + x * y where the final sum
|
|
171
|
+
// would be (cout << 8) + s.
|
|
172
|
+
static inline poly8x16x2_t pmac64x8(poly8x16_t cin, poly8x8_t x, poly8_t y) {
|
|
173
|
+
const poly8x16_t zero{};
|
|
174
|
+
poly8x16_t prod = vmull_p8(x, vdup_n_p8(y));
|
|
175
|
+
poly8x16x2_t uzp = vuzpq_p8(prod, zero);
|
|
176
|
+
uzp.val[0] = vaddq_p8(uzp.val[0], cin);
|
|
177
|
+
return uzp;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
static inline poly8x16_t pmul64x64(poly8x8_t x, poly8x8_t y) {
|
|
181
|
+
poly8x16_t r{};
|
|
182
|
+
|
|
183
|
+
poly8x16x2_t prod = pmac64x8(r, x, y[0]);
|
|
184
|
+
r = prod.val[0];
|
|
185
|
+
|
|
186
|
+
prod = pmac64x8(prod.val[1], x, y[1]);
|
|
187
|
+
r = vaddq_p8(r, vextq_p8(prod.val[0], prod.val[0], 15));
|
|
188
|
+
|
|
189
|
+
prod = pmac64x8(prod.val[1], x, y[2]);
|
|
190
|
+
r = vaddq_p8(r, vextq_p8(prod.val[0], prod.val[0], 14));
|
|
191
|
+
|
|
192
|
+
prod = pmac64x8(prod.val[1], x, y[3]);
|
|
193
|
+
r = vaddq_p8(r, vextq_p8(prod.val[0], prod.val[0], 13));
|
|
194
|
+
|
|
195
|
+
prod = pmac64x8(prod.val[1], x, y[4]);
|
|
196
|
+
r = vaddq_p8(r, vextq_p8(prod.val[0], prod.val[0], 12));
|
|
197
|
+
|
|
198
|
+
prod = pmac64x8(prod.val[1], x, y[5]);
|
|
199
|
+
r = vaddq_p8(r, vextq_p8(prod.val[0], prod.val[0], 11));
|
|
200
|
+
|
|
201
|
+
prod = pmac64x8(prod.val[1], x, y[6]);
|
|
202
|
+
r = vaddq_p8(r, vextq_p8(prod.val[0], prod.val[0], 10));
|
|
203
|
+
|
|
204
|
+
prod = pmac64x8(prod.val[1], x, y[7]);
|
|
205
|
+
r = vaddq_p8(r, vextq_p8(prod.val[0], prod.val[0], 9));
|
|
206
|
+
r = vaddq_p8(r, vextq_p8(prod.val[1], prod.val[1], 8));
|
|
207
|
+
|
|
208
|
+
return r;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static inline gf2_128_elt_t vmull_low(gf2_128_elt_t t0, gf2_128_elt_t t1) {
|
|
212
|
+
// vreinterpretq_p64_p8() seems not to be defined, use
|
|
213
|
+
// static_cast<poly64x2_t>
|
|
214
|
+
return static_cast<poly64x2_t>(pmul64x64(vget_low_p8(t0), vget_low_p8(t1)));
|
|
215
|
+
}
|
|
216
|
+
static inline gf2_128_elt_t vmull_high(gf2_128_elt_t t0, gf2_128_elt_t t1) {
|
|
217
|
+
return static_cast<poly64x2_t>(pmul64x64(vget_high_p8(t0), vget_high_p8(t1)));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// vextq_p64() seems not to be defined.
|
|
221
|
+
static inline gf2_128_elt_t vextq_p64_1_emul(gf2_128_elt_t t0,
|
|
222
|
+
gf2_128_elt_t t1) {
|
|
223
|
+
return static_cast<poly64x2_t>(
|
|
224
|
+
vextq_p8(static_cast<poly8x16_t>(t0), static_cast<poly8x16_t>(t1), 8));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// return t0 + x^64 * t1
|
|
228
|
+
static inline gf2_128_elt_t gf2_128_reduce(gf2_128_elt_t t0, gf2_128_elt_t t1) {
|
|
229
|
+
const poly8_t poly = static_cast<poly8_t>(0x87);
|
|
230
|
+
const gf2_128_elt_t zero = {0x0, 0x0};
|
|
231
|
+
t0 = vaddq_p64(t0, vextq_p64_1_emul(zero, t1));
|
|
232
|
+
t0 = vaddq_p64(t0, pmul64x8(vget_high_p8(t1), poly));
|
|
233
|
+
return t0;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static inline gf2_128_elt_t gf2_128_mul(gf2_128_elt_t x, gf2_128_elt_t y) {
|
|
237
|
+
gf2_128_elt_t swx = vextq_p64_1_emul(x, x);
|
|
238
|
+
gf2_128_elt_t t1a = vmull_high(swx, y);
|
|
239
|
+
gf2_128_elt_t t1b = vmull_low(swx, y);
|
|
240
|
+
gf2_128_elt_t t1 = vaddq_p64(t1a, t1b);
|
|
241
|
+
gf2_128_elt_t t2 = vmull_high(x, y);
|
|
242
|
+
t1 = gf2_128_reduce(t1, t2);
|
|
243
|
+
gf2_128_elt_t t0 = vmull_low(x, y);
|
|
244
|
+
t0 = gf2_128_reduce(t0, t1);
|
|
245
|
+
return t0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
} // namespace proofs
|
|
249
|
+
#else
|
|
250
|
+
|
|
251
|
+
// Generic implementation assuming a 64x64->64 integer multiplier.
|
|
252
|
+
struct gf2_128_elt_t {
|
|
253
|
+
uint64_t l[2];
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
static inline std::array<uint64_t, 2> uint64x2_of_gf2_128(gf2_128_elt_t x) {
|
|
257
|
+
return std::array<uint64_t, 2>{x.l[0], x.l[1]};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static inline gf2_128_elt_t gf2_128_of_uint64x2(
|
|
261
|
+
const std::array<uint64_t, 2>& x) {
|
|
262
|
+
return gf2_128_elt_t{x[0], x[1]};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
static inline gf2_128_elt_t gf2_128_add(gf2_128_elt_t x, gf2_128_elt_t y) {
|
|
266
|
+
return gf2_128_elt_t{x.l[0] ^ y.l[0], x.l[1] ^ y.l[1]};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// 64x64->64 bit GF(2)[X] multiplication via Kronecker
|
|
270
|
+
// substitution. Modeled after the Highway library
|
|
271
|
+
// https://github.com/google/highway/blob/master/hwy/ops/generic_ops-inl.h
|
|
272
|
+
// and the ghash implementation in BearSSL.
|
|
273
|
+
static inline uint64_t clmul64_lo(uint64_t x, uint64_t y) {
|
|
274
|
+
uint64_t m0 = 0x1111111111111111ull, m1 = 0x2222222222222222ull,
|
|
275
|
+
m2 = 0x4444444444444444ull, m3 = 0x8888888888888888ull;
|
|
276
|
+
uint64_t x0 = x & m0, x1 = x & m1, x2 = x & m2, x3 = x & m3;
|
|
277
|
+
uint64_t y0 = y & m0, y1 = y & m1, y2 = y & m2, y3 = y & m3;
|
|
278
|
+
uint64_t z0 = (x0 * y0) ^ (x1 * y3) ^ (x2 * y2) ^ (x3 * y1);
|
|
279
|
+
uint64_t z1 = (x0 * y1) ^ (x1 * y0) ^ (x2 * y3) ^ (x3 * y2);
|
|
280
|
+
uint64_t z2 = (x0 * y2) ^ (x1 * y1) ^ (x2 * y0) ^ (x3 * y3);
|
|
281
|
+
uint64_t z3 = (x0 * y3) ^ (x1 * y2) ^ (x2 * y1) ^ (x3 * y0);
|
|
282
|
+
return (z0 & m0) | (z1 & m1) | (z2 & m2) | (z3 & m3);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
static inline uint64_t bitrev64(uint64_t n) {
|
|
286
|
+
n = ((n >> 1) & 0x5555555555555555ull) | ((n & 0x5555555555555555ull) << 1);
|
|
287
|
+
n = ((n >> 2) & 0x3333333333333333ull) | ((n & 0x3333333333333333ull) << 2);
|
|
288
|
+
n = ((n >> 4) & 0x0f0f0f0f0f0f0f0full) | ((n & 0x0f0f0f0f0f0f0f0full) << 4);
|
|
289
|
+
n = ((n >> 8) & 0x00ff00ff00ff00ffull) | ((n & 0x00ff00ff00ff00ffull) << 8);
|
|
290
|
+
n = ((n >> 16) & 0x0000ffff0000ffffull) | ((n & 0x0000ffff0000ffffull) << 16);
|
|
291
|
+
return (n << 32) | (n >> 32);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
static inline uint64_t clmul64_hi(uint64_t x, uint64_t y) {
|
|
295
|
+
return bitrev64(clmul64_lo(bitrev64(x), bitrev64(y))) >> 1;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// 64x64 -> 128
|
|
299
|
+
static inline gf2_128_elt_t clmul64(uint64_t x, uint64_t y) {
|
|
300
|
+
return gf2_128_elt_t{clmul64_lo(x, y), clmul64_hi(x, y)};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// return (t0 + x^64 * t1)
|
|
304
|
+
static inline gf2_128_elt_t gf2_128_reduce(gf2_128_elt_t t0, gf2_128_elt_t t1) {
|
|
305
|
+
uint64_t a = t1.l[1];
|
|
306
|
+
t0.l[0] ^= a;
|
|
307
|
+
t0.l[0] ^= a << 1;
|
|
308
|
+
t0.l[1] ^= a >> 63;
|
|
309
|
+
t0.l[0] ^= a << 2;
|
|
310
|
+
t0.l[1] ^= a >> 62;
|
|
311
|
+
t0.l[0] ^= a << 7;
|
|
312
|
+
t0.l[1] ^= a >> 57;
|
|
313
|
+
t0.l[1] ^= t1.l[0];
|
|
314
|
+
return t0;
|
|
315
|
+
}
|
|
316
|
+
static inline gf2_128_elt_t gf2_128_mul(gf2_128_elt_t x, gf2_128_elt_t y) {
|
|
317
|
+
// karatsuba
|
|
318
|
+
gf2_128_elt_t t0 = clmul64(x.l[0], y.l[0]);
|
|
319
|
+
gf2_128_elt_t t2 = clmul64(x.l[1], y.l[1]);
|
|
320
|
+
gf2_128_elt_t t1 = clmul64(x.l[0] ^ x.l[1], y.l[0] ^ y.l[1]);
|
|
321
|
+
t1 = gf2_128_add(t1, gf2_128_add(t0, t2));
|
|
322
|
+
t1 = gf2_128_reduce(t1, t2);
|
|
323
|
+
t0 = gf2_128_reduce(t0, t1);
|
|
324
|
+
return t0;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
#endif
|
|
328
|
+
|
|
329
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_GF2K_SYSDEP_H_
|