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,596 @@
|
|
|
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_ELLIPTIC_CURVE_H_
|
|
16
|
+
#define PRIVACY_PROOFS_ZK_LIB_EC_ELLIPTIC_CURVE_H_
|
|
17
|
+
|
|
18
|
+
#include <cstddef>
|
|
19
|
+
#include <cstdint>
|
|
20
|
+
|
|
21
|
+
#include "algebra/nat.h"
|
|
22
|
+
#include "util/panic.h"
|
|
23
|
+
|
|
24
|
+
namespace proofs {
|
|
25
|
+
// Elliptic curve class that supports basic operations such as addition,
|
|
26
|
+
// doubling. The algorithms are described in
|
|
27
|
+
// https://eprint.iacr.org/2015/1060.pdf.
|
|
28
|
+
// The const Field parameter is meant as a type check to keep different
|
|
29
|
+
// elliptic curves from interacting. The convention is to use the last 5
|
|
30
|
+
// digits of the coordinate field prime in base-10 to name a curve.
|
|
31
|
+
// The kN template parameter describes the number of bits in the curve
|
|
32
|
+
// order, e.g., to handle curves like P-521, K-283, etc.
|
|
33
|
+
template <class Field_, size_t W, size_t kN>
|
|
34
|
+
class EllipticCurve {
|
|
35
|
+
public:
|
|
36
|
+
using Field = Field_;
|
|
37
|
+
using Elt = typename Field::Elt;
|
|
38
|
+
using N = Nat<W>;
|
|
39
|
+
|
|
40
|
+
static constexpr const size_t kBits = kN; /* # bits in size of the group */
|
|
41
|
+
|
|
42
|
+
const Field& f_;
|
|
43
|
+
Elt a_;
|
|
44
|
+
Elt b_;
|
|
45
|
+
Elt gx_, gy_, gz_; // generator of the group
|
|
46
|
+
const Elt k2, k3, k8, k3b, k9b, k24b;
|
|
47
|
+
|
|
48
|
+
struct ECPoint {
|
|
49
|
+
Elt x;
|
|
50
|
+
Elt y;
|
|
51
|
+
Elt z;
|
|
52
|
+
|
|
53
|
+
ECPoint() = default;
|
|
54
|
+
ECPoint(const Elt& x, const Elt& y, const Elt& z) : x(x), y(y), z(z) {}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
EllipticCurve(const Elt& a, const Elt& b, const Elt& gX, const Elt& gY,
|
|
58
|
+
const Field_& F)
|
|
59
|
+
: f_(F),
|
|
60
|
+
a_(a),
|
|
61
|
+
b_(b),
|
|
62
|
+
gx_(gX),
|
|
63
|
+
gy_(gY),
|
|
64
|
+
gz_(F.one()),
|
|
65
|
+
k2(F.of_scalar(2)),
|
|
66
|
+
k3(F.of_scalar(3)),
|
|
67
|
+
k8(F.of_scalar(8)),
|
|
68
|
+
k3b(F.mulf(k3, b_)),
|
|
69
|
+
k9b(F.mulf(F.of_scalar(9), b_)),
|
|
70
|
+
k24b(F.mulf(F.of_scalar(24), b_)) {
|
|
71
|
+
is_minus_3_a_ = (a_ == F.negf(k3));
|
|
72
|
+
is_zero_a_ = (a_ == F.zero());
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// This equality method makes no assumptions about whether the inputs
|
|
76
|
+
// are valid points on the curve. Just verifying cross-mult is not
|
|
77
|
+
// enough if one of the points is invalid. This method is not constant
|
|
78
|
+
// time and can return early if any point is infinity.
|
|
79
|
+
bool equal(const ECPoint& p, const ECPoint& q) const {
|
|
80
|
+
// handle inf point, then point equality, and finally projective eq
|
|
81
|
+
if (q.x == f_.zero() && q.z == f_.zero() && q.y != f_.zero() &&
|
|
82
|
+
p.x == f_.zero() && p.z == f_.zero() && p.y != f_.zero()) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
if (q.x == p.x && q.z == p.z && q.y == p.y) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return (f_.mulf(p.x, q.z) == f_.mulf(q.x, p.z) &&
|
|
90
|
+
f_.mulf(p.y, q.z) == f_.mulf(q.y, p.z));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// This method assumes a point is either zero or has z=1 coordinate,
|
|
94
|
+
// so it does not implement the full mathematical notion of Jacobian-form
|
|
95
|
+
// ec point.
|
|
96
|
+
bool is_on_curve(const ECPoint& p) const {
|
|
97
|
+
if (equal(p, zero())) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
// Do not support Jacobian coordinate with z != 1"
|
|
101
|
+
if (p.z != f_.one()) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
return is_on_curve(p.x, p.y);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// This caller of the constructor must first verify that (x,y) is on the
|
|
108
|
+
// curve using the isOnCurve() method.
|
|
109
|
+
ECPoint point(const Elt& x, const Elt& y) const {
|
|
110
|
+
ECPoint p(x, y, f_.one());
|
|
111
|
+
check(is_on_curve(p), "Invalid curve point");
|
|
112
|
+
return p;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
void normalize(ECPoint& p) const {
|
|
116
|
+
if (p.z == f_.zero()) return;
|
|
117
|
+
f_.invert(p.z);
|
|
118
|
+
f_.mul(p.x, p.z);
|
|
119
|
+
f_.mul(p.y, p.z);
|
|
120
|
+
p.z = f_.one();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
void addE(ECPoint& p3, const ECPoint& p2) const {
|
|
124
|
+
addE(p3.x, p3.y, p3.z, p3.x, p3.y, p3.z, p2.x, p2.y, p2.z);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
void doubleE(ECPoint& p3) const {
|
|
128
|
+
doubleE(p3.x, p3.y, p3.z, p3.x, p3.y, p3.z);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Functional interface.
|
|
132
|
+
ECPoint addEf(ECPoint p1, const ECPoint& p2) const {
|
|
133
|
+
addE(p1, p2);
|
|
134
|
+
return p1;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
ECPoint doubleEf(ECPoint p1) const {
|
|
138
|
+
doubleE(p1);
|
|
139
|
+
return p1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Computes the elliptic curve point p * scalar.
|
|
143
|
+
// This method is not constant time, but that is not necessary in the current
|
|
144
|
+
// zk implementation.
|
|
145
|
+
ECPoint scalar_multf(const ECPoint& p, const N& scalar) const {
|
|
146
|
+
ECPoint x = p;
|
|
147
|
+
ECPoint p3 = zero();
|
|
148
|
+
for (size_t d = 0; d < N::kLimbs; ++d) {
|
|
149
|
+
auto nd = scalar.limb_[d];
|
|
150
|
+
for (size_t i = 0; i < N::kBitsPerLimb; ++i) {
|
|
151
|
+
if (nd & 1) {
|
|
152
|
+
addE(p3, x);
|
|
153
|
+
}
|
|
154
|
+
doubleE(x);
|
|
155
|
+
nd >>= 1;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return p3;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Computes the multi-scalar elliptic curve point multiplication.
|
|
162
|
+
// Input: p1, p2, ..., pn, and scalars s1, s2, ..., sn
|
|
163
|
+
// Output: p1 * s1 + p2 * s2 + ... + pn * sn
|
|
164
|
+
// This method is not a constant time operation.
|
|
165
|
+
ECPoint scalar_multf(size_t n, ECPoint p[/*n*/], N scalar[/*n*/]) const {
|
|
166
|
+
if (n == 0) {
|
|
167
|
+
return zero();
|
|
168
|
+
} else if (n == 1) {
|
|
169
|
+
return scalar_multf(p[0], scalar[0]);
|
|
170
|
+
} else {
|
|
171
|
+
return bos_coster(n, p, scalar);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
ECPoint zero() const { return ECPoint(f_.zero(), f_.one(), f_.zero()); }
|
|
176
|
+
ECPoint generator() const { return ECPoint(gx_, gy_, gz_); }
|
|
177
|
+
|
|
178
|
+
// Check whether Y^2 = X^3 + aX + b.
|
|
179
|
+
bool is_on_curve(const Elt& X, const Elt& Y) const {
|
|
180
|
+
Elt left = f_.mulf(Y, Y);
|
|
181
|
+
Elt X3 = f_.mulf(X, f_.mulf(X, X));
|
|
182
|
+
Elt right = f_.addf(f_.addf(X3, f_.mulf(a_, X)), b_);
|
|
183
|
+
return left == right;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
void addE(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X1, const Elt& Y1,
|
|
187
|
+
const Elt& Z1, const Elt& X2, const Elt& Y2, const Elt& Z2) const {
|
|
188
|
+
// Optimized special cases.
|
|
189
|
+
if (is_zero_a_) return addEZeroA(X3o, Y3o, Z3o, X1, Y1, Z1, X2, Y2, Z2);
|
|
190
|
+
if (is_minus_3_a_)
|
|
191
|
+
return addEMinus3A(X3o, Y3o, Z3o, X1, Y1, Z1, X2, Y2, Z2);
|
|
192
|
+
|
|
193
|
+
/*
|
|
194
|
+
Source: 1998 Cohen–Miyaji–Ono "Efficient elliptic curve exponentiation using
|
|
195
|
+
mixed coordinates", formula (3), plus common-subexpression elimination.
|
|
196
|
+
These equations are taken from the Hyperelliptic curve formula database.
|
|
197
|
+
This could have special short-cuts for addition with inf and self-addition,
|
|
198
|
+
which speeds up all multi-exponentiation computations that involve a lot of
|
|
199
|
+
small exponents.
|
|
200
|
+
*/
|
|
201
|
+
if (X1 == f_.zero() && Z1 == f_.zero()) {
|
|
202
|
+
X3o = X2;
|
|
203
|
+
Y3o = Y2;
|
|
204
|
+
Z3o = Z2;
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (X2 == f_.zero() && Z2 == f_.zero()) {
|
|
209
|
+
X3o = X1;
|
|
210
|
+
Y3o = Y1;
|
|
211
|
+
Z3o = Z1;
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
Elt Y1Z2 = f_.mulf(Y1, Z2);
|
|
216
|
+
Elt X1Z2 = f_.mulf(X1, Z2);
|
|
217
|
+
Elt u = f_.subf(f_.mulf(Y2, Z1), Y1Z2);
|
|
218
|
+
Elt v = f_.subf(f_.mulf(X2, Z1), X1Z2);
|
|
219
|
+
if (u == f_.zero()) {
|
|
220
|
+
doubleE(X3o, Y3o, Z3o, X1, Y1, Z1);
|
|
221
|
+
return;
|
|
222
|
+
// Self addition, invoke Double method.
|
|
223
|
+
}
|
|
224
|
+
/* This check occurs after the u check.
|
|
225
|
+
If u!=0, but v=0, then the points are inverses.
|
|
226
|
+
*/
|
|
227
|
+
if (v == f_.zero()) {
|
|
228
|
+
X3o = f_.zero();
|
|
229
|
+
Y3o = f_.one();
|
|
230
|
+
Z3o = f_.zero();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
Elt Z1Z2 = f_.mulf(Z1, Z2);
|
|
235
|
+
Elt uu = f_.mulf(u, u);
|
|
236
|
+
Elt vv = f_.mulf(v, v);
|
|
237
|
+
Elt vvv = f_.mulf(v, vv);
|
|
238
|
+
Elt R = f_.mulf(vv, X1Z2);
|
|
239
|
+
Elt A = f_.subf(f_.subf(f_.mulf(uu, Z1Z2), vvv), f_.mulf(k2, R));
|
|
240
|
+
Elt X3 = f_.mulf(v, A);
|
|
241
|
+
Elt Y3 = f_.subf(f_.mulf(u, f_.subf(R, A)), f_.mulf(vvv, Y1Z2));
|
|
242
|
+
Elt Z3 = f_.mulf(vvv, Z1Z2);
|
|
243
|
+
|
|
244
|
+
X3o = X3;
|
|
245
|
+
Y3o = Y3;
|
|
246
|
+
Z3o = Z3;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
void doubleE(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X, const Elt& Y,
|
|
250
|
+
const Elt& Z) const {
|
|
251
|
+
// Optimized special cases.
|
|
252
|
+
if (is_zero_a_) return doubleEZeroA(X3o, Y3o, Z3o, X, Y, Z);
|
|
253
|
+
if (is_minus_3_a_) return doubleEMinus3A(X3o, Y3o, Z3o, X, Y, Z);
|
|
254
|
+
|
|
255
|
+
/*
|
|
256
|
+
// 1998 Cohen–Miyaji–Ono "Efficient elliptic curve exponentiation using
|
|
257
|
+
mixed coordinates", formula (4), This version of the double formula trades
|
|
258
|
+
general mults for mults by 2,4,8 which can be implemented with additions.
|
|
259
|
+
This results in savings of 200ns on double.
|
|
260
|
+
*/
|
|
261
|
+
if (X == f_.zero() && Z == f_.zero()) {
|
|
262
|
+
X3o = X;
|
|
263
|
+
Y3o = f_.one();
|
|
264
|
+
Z3o = Z;
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
Elt Z2 = f_.mulf(Z, Z);
|
|
269
|
+
Elt X2 = f_.mulf(X, X);
|
|
270
|
+
Elt X2_3 = f_.addf(f_.addf(X2, X2), X2);
|
|
271
|
+
Elt s = f_.mulf(Y, Z);
|
|
272
|
+
Elt ss = f_.mulf(s, s);
|
|
273
|
+
Elt sss = f_.mulf(s, ss);
|
|
274
|
+
Elt sss_2 = f_.addf(sss, sss);
|
|
275
|
+
Elt w = f_.addf(f_.mulf(a_, Z2), X2_3);
|
|
276
|
+
Elt R = f_.mulf(Y, s);
|
|
277
|
+
Elt sss_4 = f_.addf(sss_2, sss_2);
|
|
278
|
+
Elt B = f_.mulf(X, R);
|
|
279
|
+
Elt sss_8 = f_.addf(sss_4, sss_4);
|
|
280
|
+
Elt B_2 = f_.addf(B, B);
|
|
281
|
+
Elt R2 = f_.mulf(R, R);
|
|
282
|
+
Elt B_4 = f_.addf(B_2, B_2);
|
|
283
|
+
Elt B_8 = f_.addf(B_4, B_4);
|
|
284
|
+
Elt w2 = f_.mulf(w, w);
|
|
285
|
+
Elt h = f_.subf(w2, B_8);
|
|
286
|
+
Elt s_2 = f_.addf(s, s);
|
|
287
|
+
Elt X3 = f_.mulf(h, s_2);
|
|
288
|
+
Elt R2_2 = f_.addf(R2, R2);
|
|
289
|
+
Elt R2_4 = f_.addf(R2_2, R2_2);
|
|
290
|
+
Elt R2_8 = f_.addf(R2_4, R2_4);
|
|
291
|
+
Elt Y3 = f_.subf(f_.mulf(w, f_.subf(B_4, h)), R2_8);
|
|
292
|
+
Elt Z3 = sss_8;
|
|
293
|
+
|
|
294
|
+
X3o = X3;
|
|
295
|
+
Y3o = Y3;
|
|
296
|
+
Z3o = Z3;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
private:
|
|
300
|
+
/* From Algorithm 7: Complete, projective point addition for prime order
|
|
301
|
+
j-invariant 0 short Weierstrass curves E/Fq : y^2 = x^3 + b.
|
|
302
|
+
|
|
303
|
+
X3 = (X1 Y2 + X2 Y1)(Y1 Y2 - 3b Z1 Z2) - 3b(Y1 Z2 + Y2 Z1)(X1 Z2 + X2 Z1)
|
|
304
|
+
Y3 = (Y1 Y2 + 3b Z1 Z2)(Y1 Y2 - 3b Z1 Z2) + 9b X1 X2 (X1 Z2 + X2 Z1)
|
|
305
|
+
Z3 = (Y1 Z2 + Y2 Z1)(Y1 Y2 + 3b Z1 Z2) + 3 X1 X2(X1 Y2 + X2 Y1)
|
|
306
|
+
*/
|
|
307
|
+
void addEZeroA(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X1, const Elt& Y1,
|
|
308
|
+
const Elt& Z1, const Elt& X2, const Elt& Y2,
|
|
309
|
+
const Elt& Z2) const {
|
|
310
|
+
Elt t0 = f_.mulf(X2, Y1);
|
|
311
|
+
Elt t1 = f_.mulf(X1, Y2);
|
|
312
|
+
Elt t2 = f_.addf(t1, t0);
|
|
313
|
+
Elt t3 = f_.mulf(Y1, Y2);
|
|
314
|
+
Elt t4 = f_.mulf(Z1, Z2);
|
|
315
|
+
Elt t5 = f_.mulf(Y1, Z2);
|
|
316
|
+
Elt t6 = f_.mulf(Y2, Z1);
|
|
317
|
+
Elt t7 = f_.addf(t5, t6);
|
|
318
|
+
Elt t8 = f_.mulf(X1, Z2);
|
|
319
|
+
Elt t9 = f_.mulf(X2, Z1);
|
|
320
|
+
Elt t10 = f_.addf(t8, t9);
|
|
321
|
+
Elt t11 = f_.mulf(X1, X2);
|
|
322
|
+
Elt t12 = f_.mulf(k3b, t4);
|
|
323
|
+
Elt t13 = f_.addf(t3, t12);
|
|
324
|
+
Elt t14 = f_.subf(t3, t12);
|
|
325
|
+
|
|
326
|
+
X3o = f_.subf(f_.mulf(t2, t14), f_.mulf(k3b, f_.mulf(t7, t10)));
|
|
327
|
+
Y3o = f_.addf(f_.mulf(t13, t14), f_.mulf(k9b, f_.mulf(t11, t10)));
|
|
328
|
+
Z3o = f_.addf(f_.mulf(t7, t13), f_.mulf(k3, f_.mulf(t11, t2)));
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/*Algorithm 4: Complete, projective point addition for prime order short
|
|
332
|
+
* Weierstrass curves E/Fq : y^2 = x^33 + ax + b with a = −3.
|
|
333
|
+
*/
|
|
334
|
+
void addEMinus3A(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X1, const Elt& Y1,
|
|
335
|
+
const Elt& Z1, const Elt& X2, const Elt& Y2,
|
|
336
|
+
const Elt& Z2) const {
|
|
337
|
+
Elt t0 = f_.mulf(X1, X2);
|
|
338
|
+
Elt t1 = f_.mulf(Y1, Y2);
|
|
339
|
+
Elt t2 = f_.mulf(Z1, Z2);
|
|
340
|
+
Elt t3 = f_.addf(X1, Y1);
|
|
341
|
+
Elt t4 = f_.addf(X2, Y2);
|
|
342
|
+
t3 = f_.mulf(t3, t4);
|
|
343
|
+
t4 = f_.addf(t0, t1);
|
|
344
|
+
t3 = f_.subf(t3, t4);
|
|
345
|
+
t4 = f_.addf(Y1, Z1);
|
|
346
|
+
Elt X3 = f_.addf(Y2, Z2);
|
|
347
|
+
t4 = f_.mulf(t4, X3);
|
|
348
|
+
X3 = f_.addf(t1, t2);
|
|
349
|
+
t4 = f_.subf(t4, X3);
|
|
350
|
+
X3 = f_.addf(X1, Z1);
|
|
351
|
+
Elt Y3 = f_.addf(X2, Z2);
|
|
352
|
+
X3 = f_.mulf(X3, Y3);
|
|
353
|
+
Y3 = f_.addf(t0, t2);
|
|
354
|
+
Y3 = f_.subf(X3, Y3);
|
|
355
|
+
Elt Z3 = f_.mulf(b_, t2);
|
|
356
|
+
X3 = f_.subf(Y3, Z3);
|
|
357
|
+
Z3 = f_.addf(X3, X3);
|
|
358
|
+
X3 = f_.addf(X3, Z3);
|
|
359
|
+
Z3 = f_.subf(t1, X3);
|
|
360
|
+
X3 = f_.addf(t1, X3);
|
|
361
|
+
Y3 = f_.mulf(b_, Y3);
|
|
362
|
+
t1 = f_.addf(t2, t2);
|
|
363
|
+
t2 = f_.addf(t1, t2);
|
|
364
|
+
Y3 = f_.subf(Y3, t2);
|
|
365
|
+
Y3 = f_.subf(Y3, t0);
|
|
366
|
+
t1 = f_.addf(Y3, Y3);
|
|
367
|
+
Y3 = f_.addf(t1, Y3);
|
|
368
|
+
t1 = f_.addf(t0, t0);
|
|
369
|
+
t0 = f_.addf(t1, t0);
|
|
370
|
+
t0 = f_.subf(t0, t2);
|
|
371
|
+
t1 = f_.mulf(t4, Y3);
|
|
372
|
+
t2 = f_.mulf(t0, Y3);
|
|
373
|
+
Y3 = f_.mulf(X3, Z3);
|
|
374
|
+
Y3 = f_.addf(Y3, t2);
|
|
375
|
+
X3 = f_.mulf(t3, X3);
|
|
376
|
+
X3 = f_.subf(X3, t1);
|
|
377
|
+
Z3 = f_.mulf(t4, Z3);
|
|
378
|
+
t1 = f_.mulf(t3, t0);
|
|
379
|
+
Z3 = f_.addf(Z3, t1);
|
|
380
|
+
|
|
381
|
+
X3o = X3;
|
|
382
|
+
Y3o = Y3;
|
|
383
|
+
Z3o = Z3;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/* From Algorithm 6: Exception-free point doubling for prime order short
|
|
387
|
+
* Weierstrass curves E/Fq : y^2 = x^3 + ax + b with a = −3.
|
|
388
|
+
*/
|
|
389
|
+
void doubleEMinus3A(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X, const Elt& Y,
|
|
390
|
+
const Elt& Z) const {
|
|
391
|
+
Elt t0 = f_.mulf(X, X);
|
|
392
|
+
Elt t1 = f_.mulf(Y, Y);
|
|
393
|
+
Elt t2 = f_.mulf(Z, Z);
|
|
394
|
+
Elt t3 = f_.mulf(X, Y);
|
|
395
|
+
t3 = f_.addf(t3, t3);
|
|
396
|
+
Elt Z3 = f_.mulf(X, Z);
|
|
397
|
+
Z3 = f_.addf(Z3, Z3);
|
|
398
|
+
Elt Y3 = f_.mulf(b_, t2);
|
|
399
|
+
Y3 = f_.subf(Y3, Z3);
|
|
400
|
+
Elt X3 = f_.addf(Y3, Y3);
|
|
401
|
+
Y3 = f_.addf(X3, Y3);
|
|
402
|
+
X3 = f_.subf(t1, Y3);
|
|
403
|
+
Y3 = f_.addf(t1, Y3);
|
|
404
|
+
Y3 = f_.mulf(X3, Y3);
|
|
405
|
+
X3 = f_.mulf(X3, t3);
|
|
406
|
+
t3 = f_.addf(t2, t2);
|
|
407
|
+
t2 = f_.addf(t2, t3);
|
|
408
|
+
Z3 = f_.mulf(b_, Z3);
|
|
409
|
+
Z3 = f_.subf(Z3, t2);
|
|
410
|
+
Z3 = f_.subf(Z3, t0);
|
|
411
|
+
t3 = f_.addf(Z3, Z3);
|
|
412
|
+
Z3 = f_.addf(Z3, t3);
|
|
413
|
+
t3 = f_.addf(t0, t0);
|
|
414
|
+
t0 = f_.addf(t3, t0);
|
|
415
|
+
t0 = f_.subf(t0, t2);
|
|
416
|
+
t0 = f_.mulf(t0, Z3);
|
|
417
|
+
Y3 = f_.addf(Y3, t0);
|
|
418
|
+
t0 = f_.mulf(Y, Z);
|
|
419
|
+
t0 = f_.addf(t0, t0);
|
|
420
|
+
Z3 = f_.mulf(t0, Z3);
|
|
421
|
+
X3 = f_.subf(X3, Z3);
|
|
422
|
+
Z3 = f_.mulf(t0, t1);
|
|
423
|
+
Z3 = f_.addf(Z3, Z3);
|
|
424
|
+
Z3 = f_.addf(Z3, Z3);
|
|
425
|
+
|
|
426
|
+
X3o = X3;
|
|
427
|
+
Y3o = Y3;
|
|
428
|
+
Z3o = Z3;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/* From Algorithm 9: Exception-free point doubling for prime order
|
|
432
|
+
j-invariant 0 short Weierstrass curves E/Fq y^2 = x^3 + b
|
|
433
|
+
|
|
434
|
+
X3 = 2XY (YY − 9bZZ)
|
|
435
|
+
Y3 = (YY − 9bZZ)(YY + 3bZZ) + 24bYYZZ
|
|
436
|
+
Z3 = 8YYYZ.
|
|
437
|
+
*/
|
|
438
|
+
void doubleEZeroA(Elt& X3o, Elt& Y3o, Elt& Z3o, const Elt& X, const Elt& Y,
|
|
439
|
+
const Elt& Z) const {
|
|
440
|
+
Elt t0 = f_.mulf(X, Y);
|
|
441
|
+
Elt t1 = f_.mulf(Y, Y);
|
|
442
|
+
Elt t2 = f_.mulf(Z, Z);
|
|
443
|
+
Elt t4 = f_.mulf(Y, Z);
|
|
444
|
+
Elt t5 = f_.mulf(k9b, t2); // 9bZZ
|
|
445
|
+
Elt t6 = f_.subf(t1, t5); // YY - 9bZZ
|
|
446
|
+
Elt t7 = f_.mulf(k3b, t2); // 3bZZ
|
|
447
|
+
Elt t8 = f_.addf(t1, t7); // YY + 3bZZ
|
|
448
|
+
X3o = f_.mulf(k2, f_.mulf(t0, t6));
|
|
449
|
+
Y3o = f_.addf(f_.mulf(t6, t8), f_.mulf(k24b, f_.mulf(t1, t2)));
|
|
450
|
+
Z3o = f_.mulf(k8, f_.mulf(t1, t4));
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
//------------------------------------------------------------
|
|
454
|
+
// Multi-exponentiation SUM_i scalarMult(p[i], s[i])
|
|
455
|
+
|
|
456
|
+
// We follow the basic strategy outlined in Daniel J. Bernstein,
|
|
457
|
+
// Niels Duif, Tanja Lange, Peter Schwabe, and Bo-Yin Yang,
|
|
458
|
+
// "High-speed high-security signatures",
|
|
459
|
+
// https://eprint.iacr.org/2011/368, where Bernstein et al. credit
|
|
460
|
+
// the method to Bos and Coster via a reference to Peter de Rooij,
|
|
461
|
+
// "Efficient exponentiation using precomputation and vector
|
|
462
|
+
// addition chains", in Eurocrypt ’94. In my opinion [matteof@]
|
|
463
|
+
// the method of Bernstein et al. is not quite the same as the papers
|
|
464
|
+
// that they reference, but either way we follow Bernstein et al.
|
|
465
|
+
// with a few modifications, and call the method bos_coster() in
|
|
466
|
+
// this file.
|
|
467
|
+
|
|
468
|
+
// The basic idea is to keep the list (p[i], s[i]) of pairs
|
|
469
|
+
// (point, scalar) in descending order of scalar, so that s[0]
|
|
470
|
+
// is the maximum.
|
|
471
|
+
|
|
472
|
+
// Bernstein's method repeatedly replaces p[0]*s[0]+p[1]*s[1]
|
|
473
|
+
// by p[0]*(s[0]-s[1])+(p[0]+p[1])*s[1], where now the first
|
|
474
|
+
// scalar becomes smaller. Eventually all the scalars s[i] become
|
|
475
|
+
// 0 for i>=1.
|
|
476
|
+
|
|
477
|
+
// For random scalars, one can roughly expect s[0]-s[1] to be
|
|
478
|
+
// about |F|/n, so the method can be expected to set approximately
|
|
479
|
+
// log n scalar bits to zero in each iteration. However, its worst
|
|
480
|
+
// case is horrific. E.g., if s[1]=1 and s[0] is O(2**256), the
|
|
481
|
+
// method will require O(2**256) iterations to converge.
|
|
482
|
+
|
|
483
|
+
// To avoid this worst-case behavior, we depart from Bernstein and
|
|
484
|
+
// perform either a Bernstein step or a double-and-add step,
|
|
485
|
+
// whichever one decreases s[0] the most. A double-and-add writes
|
|
486
|
+
// s[0] = 2*a+b and replaces p[0]*s[0] with (2*p[0])*(s[0]/2) *
|
|
487
|
+
// b*p[0], where the second multiplication is trivial because b \in
|
|
488
|
+
// {0,1}. With this choice, we are guaranteed to eliminate at least
|
|
489
|
+
// one scalar bit per iteration, so the method is no worse than a
|
|
490
|
+
// loop of single scalar multiplications. Bernstein et al., page
|
|
491
|
+
// 17, are aware of the problem, but they say that doing anything
|
|
492
|
+
// about it is "not worthwhile". On the other hand, the fix doesn't
|
|
493
|
+
// cost anything either, so may as well do it. (Bernstein et
|
|
494
|
+
// al. propose a different fix.)
|
|
495
|
+
|
|
496
|
+
// For easy access to the largest s[0] and second-largest s[1], we
|
|
497
|
+
// keep the (p[i], s[i]) terms in a heap. Here, "heap" denotes a
|
|
498
|
+
// variant of the standard heap where the root node H[0] has one
|
|
499
|
+
// child H[1] (as opposed to two children), and every other node i>0
|
|
500
|
+
// has two children H[2*i] and H[2*i+1]. A heap comprises at least
|
|
501
|
+
// two elements H[0] and H[1]. In this way, the two largest scalars
|
|
502
|
+
// are always available directly.
|
|
503
|
+
|
|
504
|
+
// The following function is equivalent to assigning (p[i], s[i]) =
|
|
505
|
+
// (tp, ts) followed by restoring heap order. However, the logic is
|
|
506
|
+
// a bit complicated by our desire to avoid unnecessary copies of
|
|
507
|
+
// large objects (e.g., swap p[i] with a child, followed by another
|
|
508
|
+
// swap of the child with its child.)
|
|
509
|
+
//
|
|
510
|
+
// Warning: tp and ts MUST NOT be references to p[i] and s[i], since
|
|
511
|
+
// the algorithm overwrites the p and s arrays. This complication
|
|
512
|
+
// ensues because we are trying to avoid unnecessary copies.
|
|
513
|
+
void bury(size_t i, size_t n, ECPoint p[/*n*/], N s[/*n*/], const ECPoint& tp,
|
|
514
|
+
const N& ts) const {
|
|
515
|
+
while (2 * i < n) {
|
|
516
|
+
// at least one child
|
|
517
|
+
size_t cld = 2 * i;
|
|
518
|
+
if (2 * i + 1 < n && s[cld] < s[2 * i + 1]) {
|
|
519
|
+
// right child exists and is larger
|
|
520
|
+
cld = 2 * i + 1;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (ts < s[cld]) {
|
|
524
|
+
// I is out of order with CLD. Bubble CLD up the tree and
|
|
525
|
+
// continue as in BURY(CLD, N, P, S, TP, TS).
|
|
526
|
+
s[i] = s[cld];
|
|
527
|
+
p[i] = p[cld];
|
|
528
|
+
i = cld;
|
|
529
|
+
} else {
|
|
530
|
+
// already in heap order, stop here.
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
p[i] = tp;
|
|
536
|
+
s[i] = ts;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// bury (p[0], s[0]) to its rightful place in the heap.
|
|
540
|
+
void bury0(size_t n, ECPoint p[/*n*/], N s[/*n*/]) const {
|
|
541
|
+
if (s[0] < s[1]) {
|
|
542
|
+
// equivalent to swap(s[0], s[1]); bury(s[1]);
|
|
543
|
+
// but without the possibly unnecessary assignment of (s,p)[1]
|
|
544
|
+
ECPoint tp = p[0];
|
|
545
|
+
N ts = s[0];
|
|
546
|
+
p[0] = p[1];
|
|
547
|
+
s[0] = s[1];
|
|
548
|
+
bury(1, n, p, s, tp, ts);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// The main Bernstein/Bos-Coster algorithm.
|
|
553
|
+
ECPoint bos_coster(size_t n, ECPoint p[/*n*/], N s[/*n*/]) const {
|
|
554
|
+
check(n >= 2, "n >= 2");
|
|
555
|
+
ECPoint res = zero();
|
|
556
|
+
|
|
557
|
+
// build a heap on [1..n)
|
|
558
|
+
for (size_t i = /*floor*/ (n / 2); i >= 1; --i) {
|
|
559
|
+
// create temporary copies of p[i], s[i], which are passed by
|
|
560
|
+
// const &.
|
|
561
|
+
bury(i, n, p, s, ECPoint(p[i]), N(s[i]));
|
|
562
|
+
}
|
|
563
|
+
// finish the heap on [0..n)
|
|
564
|
+
bury0(n, p, s);
|
|
565
|
+
|
|
566
|
+
while (s[0] != /*zero*/ N{}) {
|
|
567
|
+
// ns0 = s[0] - s[1]
|
|
568
|
+
N ns0(s[0]);
|
|
569
|
+
ns0.sub(s[1]);
|
|
570
|
+
|
|
571
|
+
// Double-and-add is (locally) better than Bernstein iff s[0]/2
|
|
572
|
+
// < s[0] - s[1], equivalent to s[0] > 2*s[1], equivalent to
|
|
573
|
+
// ns0 = s[0] - s[1] > s[1]:
|
|
574
|
+
if (s[1] < ns0) {
|
|
575
|
+
// res += (s[0] & 1) * p[0]; s[0] /= 2; p[0] *= 2;
|
|
576
|
+
uint64_t lsb = s[0].shiftr(1);
|
|
577
|
+
if (lsb != 0) {
|
|
578
|
+
addE(res, p[0]);
|
|
579
|
+
}
|
|
580
|
+
doubleE(p[0]);
|
|
581
|
+
} else {
|
|
582
|
+
// s[0] -= s[1], p[1] += p[0]
|
|
583
|
+
s[0] = ns0;
|
|
584
|
+
addE(p[1], p[0]);
|
|
585
|
+
}
|
|
586
|
+
bury0(n, p, s);
|
|
587
|
+
}
|
|
588
|
+
return res;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
bool is_zero_a_;
|
|
592
|
+
bool is_minus_3_a_;
|
|
593
|
+
};
|
|
594
|
+
} // namespace proofs
|
|
595
|
+
|
|
596
|
+
#endif // PRIVACY_PROOFS_ZK_LIB_EC_ELLIPTIC_CURVE_H_
|