diff --git a/barretenberg/acir_tests/bbjs-test/src/index.ts b/barretenberg/acir_tests/bbjs-test/src/index.ts index 7a50b1a1c787..ddd40179bd4e 100644 --- a/barretenberg/acir_tests/bbjs-test/src/index.ts +++ b/barretenberg/acir_tests/bbjs-test/src/index.ts @@ -42,6 +42,7 @@ async function generateProof({ const witness = await fs.readFile(witnessPath); const proof = await backend.generateProof(new Uint8Array(witness), { keccak: oracleHash === "keccak", + starknet: oracleHash === "starknet", }); assert( proof.proof.length === UH_PROOF_LENGTH_IN_BYTES, @@ -66,6 +67,7 @@ async function generateProof({ const verificationKey = await backend.getVerificationKey({ keccak: oracleHash === "keccak", + starknet: oracleHash === "starknet", }); await fs.writeFile(vkeyPath(outputDirectory), Buffer.from(verificationKey)); debug("Verification key written to " + vkeyPath(outputDirectory)); diff --git a/barretenberg/acir_tests/bootstrap.sh b/barretenberg/acir_tests/bootstrap.sh index b15cfba94721..0d589f4ad154 100755 --- a/barretenberg/acir_tests/bootstrap.sh +++ b/barretenberg/acir_tests/bootstrap.sh @@ -182,6 +182,7 @@ function test_cmds_internal { echo SYS=ultra_honk FLOW=prove_then_verify $run_test assert_statement echo SYS=ultra_honk FLOW=prove_then_verify $run_test double_verify_honk_proof echo SYS=ultra_honk FLOW=prove_then_verify HASH=keccak $run_test assert_statement + echo SYS=ultra_honk FLOW=prove_then_verify HASH=starknet $run_test assert_statement echo SYS=ultra_honk FLOW=prove_then_verify ROLLUP=true $run_test verify_rollup_honk_proof # prove and verify using bb.js classes diff --git a/barretenberg/cpp/src/CMakeLists.txt b/barretenberg/cpp/src/CMakeLists.txt index 6385b813d26f..79bfb4af2f25 100644 --- a/barretenberg/cpp/src/CMakeLists.txt +++ b/barretenberg/cpp/src/CMakeLists.txt @@ -80,6 +80,8 @@ add_subdirectory(barretenberg/eccvm) add_subdirectory(barretenberg/env) add_subdirectory(barretenberg/trace_to_polynomials) add_subdirectory(barretenberg/examples) +add_subdirectory(barretenberg/ext/starknet/crypto) +add_subdirectory(barretenberg/ext/starknet/transcript) add_subdirectory(barretenberg/flavor) add_subdirectory(barretenberg/goblin) add_subdirectory(barretenberg/grumpkin_srs_gen) @@ -141,6 +143,7 @@ set(BARRETENBERG_TARGET_OBJECTS $ $ $ + $ $ $ $ diff --git a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp index bd2cb95c627f..d91491188d48 100644 --- a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp +++ b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp @@ -22,7 +22,12 @@ template Circuit _compute_circuit(const std::string& bytecode_path, const std::string& witness_path) { uint32_t honk_recursion = 0; - if constexpr (IsAnyOf) { + if constexpr (IsAnyOf) { honk_recursion = 1; } else if constexpr (IsAnyOf) { honk_recursion = 2; @@ -171,8 +176,12 @@ void UltraHonkAPI::prove(const Flags& flags, _write(_prove(flags.write_vk, bytecode_path, witness_path)); } else if (flags.oracle_hash_type == "keccak" && !flags.zk) { _write(_prove(flags.write_vk, bytecode_path, witness_path)); + } else if (flags.oracle_hash_type == "starknet" && !flags.zk) { + _write(_prove(flags.write_vk, bytecode_path, witness_path)); } else if (flags.oracle_hash_type == "keccak" && flags.zk) { _write(_prove(flags.write_vk, bytecode_path, witness_path)); + } else if (flags.oracle_hash_type == "starknet" && flags.zk) { + _write(_prove(flags.write_vk, bytecode_path, witness_path)); } else { throw_or_abort("Invalid proving options specified in _prove"); } @@ -188,7 +197,13 @@ bool UltraHonkAPI::verify(const Flags& flags, return _verify(ipa_accumulation, public_inputs_path, proof_path, vk_path); } if (flags.zk) { - return _verify(ipa_accumulation, public_inputs_path, proof_path, vk_path); + if (flags.oracle_hash_type == "keccak") { + return _verify(ipa_accumulation, public_inputs_path, proof_path, vk_path); + } + if (flags.oracle_hash_type == "starknet") { + return _verify(ipa_accumulation, public_inputs_path, proof_path, vk_path); + } + return false; } if (flags.oracle_hash_type == "poseidon2") { return _verify(ipa_accumulation, public_inputs_path, proof_path, vk_path); @@ -196,6 +211,9 @@ bool UltraHonkAPI::verify(const Flags& flags, if (flags.oracle_hash_type == "keccak") { return _verify(ipa_accumulation, public_inputs_path, proof_path, vk_path); } + if (flags.oracle_hash_type == "starknet") { + return _verify(ipa_accumulation, public_inputs_path, proof_path, vk_path); + } return false; } @@ -219,8 +237,12 @@ void UltraHonkAPI::write_vk(const Flags& flags, _write(_compute_vk(bytecode_path, "")); } else if (flags.oracle_hash_type == "keccak" && !flags.zk) { _write(_compute_vk(bytecode_path, "")); + } else if (flags.oracle_hash_type == "starknet" && !flags.zk) { + _write(_compute_vk(bytecode_path, "")); } else if (flags.oracle_hash_type == "keccak" && flags.zk) { _write(_compute_vk(bytecode_path, "")); + } else if (flags.oracle_hash_type == "starknet" && flags.zk) { + _write(_compute_vk(bytecode_path, "")); } else { throw_or_abort("Invalid proving options specified in _prove"); } diff --git a/barretenberg/cpp/src/barretenberg/bb/cli.cpp b/barretenberg/cpp/src/barretenberg/bb/cli.cpp index 60a14e56e6a0..c5cde93f4ee5 100644 --- a/barretenberg/cpp/src/barretenberg/bb/cli.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/cli.cpp @@ -178,13 +178,15 @@ int parse_and_run_cli_command(int argc, char* argv[]) const auto add_oracle_hash_option = [&](CLI::App* subcommand) { return subcommand - ->add_option("--oracle_hash", - flags.oracle_hash_type, - "The hash function used by the prover as random oracle standing in for a verifier's challenge " - "generation. Poseidon2 is to be used for proofs that are intended to be verified inside of a " - "circuit. Keccak is optimized for verification in an Ethereum smart contract, where Keccak " - "has a privileged position due to the existence of an EVM precompile.") - ->check(CLI::IsMember({ "poseidon2", "keccak" }).name("is_member")); + ->add_option( + "--oracle_hash", + flags.oracle_hash_type, + "The hash function used by the prover as random oracle standing in for a verifier's challenge " + "generation. Poseidon2 is to be used for proofs that are intended to be verified inside of a " + "circuit. Keccak is optimized for verification in an Ethereum smart contract, where Keccak " + "has a privileged position due to the existence of an EVM precompile. Starknet is optimized " + "for verification in a Starknet smart contract, which can be generated using the Garaga library.") + ->check(CLI::IsMember({ "poseidon2", "keccak", "starknet" }).name("is_member")); }; const auto add_output_format_option = [&](CLI::App* subcommand) { diff --git a/barretenberg/cpp/src/barretenberg/benchmark/append_only_tree_bench/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/append_only_tree_bench/CMakeLists.txt index c2f2a6c01c51..7182d4b4be0d 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/append_only_tree_bench/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/benchmark/append_only_tree_bench/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(append_only_tree_bench crypto_poseidon2 crypto_pedersen_hash crypto_merkle_tree) +barretenberg_module(append_only_tree_bench crypto_poseidon2 ext_starknet_crypto_poseidon crypto_pedersen_hash crypto_merkle_tree) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/indexed_tree_bench/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/indexed_tree_bench/CMakeLists.txt index 59caee96f979..37ac8e31a80c 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/indexed_tree_bench/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/benchmark/indexed_tree_bench/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(indexed_tree_bench crypto_poseidon2 crypto_pedersen_hash crypto_merkle_tree) +barretenberg_module(indexed_tree_bench crypto_poseidon2 ext_starknet_crypto_poseidon crypto_pedersen_hash crypto_merkle_tree) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/CMakeLists.txt index c5501d1016a8..32f510cc1d64 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/benchmark/merkle_tree_bench/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(merkle_tree_bench crypto_poseidon2 crypto_pedersen_hash crypto_merkle_tree) +barretenberg_module(merkle_tree_bench crypto_poseidon2 ext_starknet_crypto_poseidon crypto_pedersen_hash crypto_merkle_tree) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/poseidon2_bench/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/benchmark/poseidon2_bench/CMakeLists.txt index 87e6e3d63dd6..b4f1fbcd9b7e 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/poseidon2_bench/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/benchmark/poseidon2_bench/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(poseidon2_bench crypto_poseidon2) +barretenberg_module(poseidon2_bench crypto_poseidon2 ext_starknet_crypto_poseidon) diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.cpp index 5bb582f1ff9b..52a77586c104 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.cpp @@ -4,6 +4,7 @@ #include "barretenberg/ecc/curves/bn254/bn254.hpp" #include "barretenberg/eccvm/eccvm_flavor.hpp" #include "barretenberg/eccvm/eccvm_translation_data.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/stdlib/primitives/curves/grumpkin.hpp" @@ -441,6 +442,7 @@ template class SmallSubgroupIPAProver; template class SmallSubgroupIPAProver; template class SmallSubgroupIPAProver; template class SmallSubgroupIPAProver; +template class SmallSubgroupIPAProver; // Instantiations used in tests template class SmallSubgroupIPAProver; diff --git a/barretenberg/cpp/src/barretenberg/crypto/poseidon2/sponge/sponge.hpp b/barretenberg/cpp/src/barretenberg/crypto/poseidon2/sponge/sponge.hpp index 72324c2654b7..6ed263d4ed1f 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/poseidon2/sponge/sponge.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/poseidon2/sponge/sponge.hpp @@ -132,8 +132,14 @@ template (in_len) << 64) + out_len - 1; + return hash_internal(input, iv); + } + + template static std::array hash_internal(std::span input, FF iv) + { FieldSponge sponge(iv); + size_t in_len = input.size(); for (size_t i = 0; i < in_len; ++i) { sponge.absorb(input[i]); } @@ -146,5 +152,6 @@ template input) { return hash_internal<1>(input)[0]; } + static FF hash_internal(std::span input, FF iv) { return hash_internal<1>(input, iv)[0]; } }; -} // namespace bb::crypto \ No newline at end of file +} // namespace bb::crypto diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 95ec1a516fe3..c2c6a34d74fd 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -254,6 +254,23 @@ WASM_EXPORT void acir_prove_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t c *out = to_heap_buffer(to_buffer(proof)); } +WASM_EXPORT void acir_prove_ultra_starknet_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out) +{ + // Lambda function to ensure things get freed before proving. + UltraStarknetProver prover = [&] { + const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 }; + acir_format::AcirProgram program{ + acir_format::circuit_buf_to_acir_format(from_buffer>(acir_vec)), + acir_format::witness_buf_to_witness_data(from_buffer>(witness_vec)) + }; + auto builder = acir_format::create_circuit(program, metadata); + + return UltraStarknetProver(builder); + }(); + auto proof = prover.construct_proof(); + *out = to_heap_buffer(to_buffer(proof)); +} + WASM_EXPORT void acir_verify_ultra_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result) { using VerificationKey = UltraFlavor::VerificationKey; @@ -280,6 +297,19 @@ WASM_EXPORT void acir_verify_ultra_keccak_honk(uint8_t const* proof_buf, uint8_t *result = verifier.verify_proof(proof); } +WASM_EXPORT void acir_verify_ultra_starknet_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result) +{ + using VerificationKey = UltraStarknetFlavor::VerificationKey; + using Verifier = UltraVerifier_; + + auto proof = from_buffer>(from_buffer>(proof_buf)); + auto verification_key = std::make_shared(from_buffer(vk_buf)); + + Verifier verifier{ verification_key }; + + *result = verifier.verify_proof(proof); +} + WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, uint8_t** out) { using DeciderProvingKey = DeciderProvingKey_; @@ -315,6 +345,24 @@ WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec, uint8_ *out = to_heap_buffer(to_buffer(vk)); } +WASM_EXPORT void acir_write_vk_ultra_starknet_honk(uint8_t const* acir_vec, uint8_t** out) +{ + using DeciderProvingKey = DeciderProvingKey_; + using VerificationKey = UltraStarknetFlavor::VerificationKey; + + // lambda to free the builder + DeciderProvingKey proving_key = [&] { + const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 }; + acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format( + from_buffer>(acir_vec)) }; + auto builder = acir_format::create_circuit(program, metadata); + return DeciderProvingKey(builder); + }(); + VerificationKey vk(proving_key.proving_key); + vinfo("Constructed UltraStarknetHonk verification key"); + *out = to_heap_buffer(to_buffer(vk)); +} + WASM_EXPORT void acir_honk_solidity_verifier(uint8_t const* proof_buf, uint8_t const* vk_buf, uint8_t** out) { using VerificationKey = UltraKeccakFlavor::VerificationKey; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index 1aa5f5743569..9daa6f71bdc9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -78,12 +78,15 @@ WASM_EXPORT void acir_serialize_verification_key_into_fields(in_ptr acir_compose WASM_EXPORT void acir_prove_ultra_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out); WASM_EXPORT void acir_prove_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out); +WASM_EXPORT void acir_prove_ultra_starknet_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out); WASM_EXPORT void acir_verify_ultra_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result); WASM_EXPORT void acir_verify_ultra_keccak_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result); +WASM_EXPORT void acir_verify_ultra_starknet_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result); WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, uint8_t** out); WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t** out); +WASM_EXPORT void acir_write_vk_ultra_starknet_honk(uint8_t const* acir_vec, uint8_t** out); WASM_EXPORT void acir_proof_as_fields_ultra_honk(uint8_t const* proof_buf, fr::vec_out_buf out); diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp index 21bc5b23471a..e155bba4c770 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp @@ -325,7 +325,8 @@ template struct alignas(32) field { BB_INLINE constexpr field pow(const uint256_t& exponent) const noexcept; BB_INLINE constexpr field pow(uint64_t exponent) const noexcept; - static_assert(Params::modulus_0 != 1); + // STARKNET: next line was commented as stark252 violates the assertion + // static_assert(Params::modulus_0 != 1); static constexpr uint256_t modulus_minus_two = uint256_t(Params::modulus_0 - 2ULL, Params::modulus_1, Params::modulus_2, Params::modulus_3); constexpr field invert() const noexcept; diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/CMakeLists.txt new file mode 100644 index 000000000000..f7abc9dafdaa --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(poseidon) diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/CMakeLists.txt new file mode 100644 index 000000000000..09260f0670f1 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/CMakeLists.txt @@ -0,0 +1 @@ +barretenberg_module(ext_starknet_crypto_poseidon ecc) diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.cpp b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.cpp new file mode 100644 index 000000000000..2fab961e6348 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.cpp @@ -0,0 +1,19 @@ +#include "poseidon.hpp" + +namespace bb::starknet::crypto { + +template +typename Poseidon::FF Poseidon::hash(const std::vector::FF>& input) +{ + return Sponge::hash_internal(input); +} + +template +typename Poseidon::FF Poseidon::hash(const std::vector::FF>& input, FF iv) +{ + return Sponge::hash_internal(input, iv); +} + +template class Poseidon; + +} // namespace bb::starknet::crypto diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.hpp b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.hpp new file mode 100644 index 000000000000..a200b60629b3 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "barretenberg/crypto/poseidon2/sponge/sponge.hpp" +#include "poseidon_params.hpp" +#include "poseidon_permutation.hpp" + +namespace bb::starknet::crypto { + +template class Poseidon { + public: + using FF = typename Params::FF; + + using Sponge = bb::crypto::FieldSponge>; + + static FF hash(const std::vector& input); + + static FF hash(const std::vector& input, FF iv); +}; + +extern template class Poseidon; + +} // namespace bb::starknet::crypto diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.test.cpp b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.test.cpp new file mode 100644 index 000000000000..106e527da3b4 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon.test.cpp @@ -0,0 +1,47 @@ +#include "poseidon.hpp" +#include "barretenberg/ext/starknet/ecc/curves/stark252/stark252.hpp" +#include "poseidon_params.hpp" +#include + +using namespace bb::starknet; + +namespace { +auto& engine = bb::numeric::get_debug_randomness(); +} + +TEST(Poseidon, HashBasicTests) +{ + using fq = stark252::fq; + + fq a = fq::random_element(&engine); + fq b = fq::random_element(&engine); + fq c = fq::random_element(&engine); + fq d = fq::random_element(&engine); + + std::vector input1{ a, b, c, d }; + std::vector input2{ d, c, b, a }; + + auto r0 = crypto::Poseidon::hash(input1); + auto r1 = crypto::Poseidon::hash(input1); + auto r2 = crypto::Poseidon::hash(input2); + + EXPECT_EQ(r0, r1); + EXPECT_NE(r0, r2); +} + +TEST(Poseidon, HashConsistencyCheck) +{ + using fq = stark252::fq; + + fq a(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); + fq b(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); + fq c(std::string("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); + fq d(std::string("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); + + std::vector input{ a, b, c, d }; + auto result = crypto::Poseidon::hash(input); + + fq expected(std::string("0x0494e3a5a8047943395f79e41f11ba73285be9aa930953fbad060c0649a7c79d")); + + EXPECT_EQ(result, expected); +} diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_params.hpp b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_params.hpp new file mode 100644 index 000000000000..f52d5e8ae8fe --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_params.hpp @@ -0,0 +1,509 @@ +#pragma once + +#include "barretenberg/ext/starknet/ecc/curves/stark252/stark252.hpp" + +namespace bb::starknet::crypto { + +struct PoseidonStark252BaseFieldParams { + + using FF = bb::starknet::stark252::fq; + static constexpr size_t t = 3; + static constexpr size_t d = 3; + static constexpr size_t rounds_f = 8; + static constexpr size_t rounds_p = 83; + static constexpr size_t sbox_size = 252; + static constexpr std::array internal_matrix_diagonal = { + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000002")), + FF(std::string("0x0800000000000010ffffffffffffffffffffffffffffffffffffffffffffffff")), + FF(std::string("0x0800000000000010fffffffffffffffffffffffffffffffffffffffffffffffe")), + }; + + static constexpr std::array, t> internal_matrix = { + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000002")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000001")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000001")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000001")), + FF(std::string("0x0800000000000010ffffffffffffffffffffffffffffffffffffffffffffffff")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000001")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000001")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000001")), + FF(std::string("0x0800000000000010fffffffffffffffffffffffffffffffffffffffffffffffe")), + }, + }; + + static constexpr std::array, rounds_f + rounds_p> round_constants{ + std::array{ + FF(std::string("0x06861759ea556a2339dd92f9562a30b9e58e2ad98109ae4780b7fd8eac77fe6f")), + FF(std::string("0x03827681995d5af9ffc8397a3d00425a3da43f76abf28a64e4ab1a22f27508c4")), + FF(std::string("0x03a3956d2fad44d0e7f760a2277dc7cb2cac75dc279b2d687a0dbe17704a8309")), + }, + std::array{ + FF(std::string("0x0626c47a7d421fe1f13c4282214aa759291c78f926a2d1c6882031afe67ef4cd")), + FF(std::string("0x078985f8e16505035bd6df5518cfd41f2d327fcc948d772cadfe17baca05d6a6")), + FF(std::string("0x05427f10867514a3204c659875341243c6e26a68b456dc1d142dcf34341696ff")), + }, + std::array{ + FF(std::string("0x05af083f36e4c729454361733f0883c5847cd2c5d9d4cb8b0465e60edce699d7")), + FF(std::string("0x07d71701bde3d06d54fa3f74f7b352a52d3975f92ff84b1ac77e709bfd388882")), + FF(std::string("0x0603da06882019009c26f8a6320a1c5eac1b64f699ffea44e39584467a6b1d3e")), + }, + std::array{ + FF(std::string("0x04332a6f6bde2f288e79ce13f47ad1cdeebd8870fd13a36b613b9721f6453a5d")), + FF(std::string("0x053d0ebf61664c685310a04c4dec2e7e4b9a813aaeff60d6c9e8caeb5cba78e7")), + FF(std::string("0x05346a68894845835ae5ebcb88028d2a6c82f99f928494ee1bfc2d15eaabfebc")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04b085eb1df4258c3453cc97445954bf3433b6ab9dd5a99592864c00f54a3f9a")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0731cfd19d508285965f12a079b2a169fdfe0a8e610e6f2d5ca5d7b0961f6d96")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0217d08b5339852bcc6f7a774936b3e72ecd9e1f9a73d743f8079c1e3587eeaa")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x000c935dd633b0fd63599b13c850dab3cb966ba510c81b20959e267008518c6e")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x052af8d378dd6772ee187ed23f79a7d98cf5a0a387103971467fe940e7b8b2be")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0294851c98b2682f1ec9918b9f12fcceaa6e28a7b79b2e506362cda595f8ab75")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x011b59990bacc280824d1021418d4f589da8c30063471494c204b169ab086064")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04b4df56e3d7753f91960d59ae099b9beb2ce690e6bbdcd0b599d49ceb2acd6a")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x005eecfa15a757dc3ecae9fbd8ff06e466243534f30629fc5f1cf09eb5161ac4")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0680bfdd8b9680e04659227634a1ec5282e5a7cef81b15677f8448bda4279059")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x01d0bf8fab0a1a7a14e2930794f7a3065c17e10b1cedd791b8877d97acd85053")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x02c2c8c79f808ace54ba207053c0d412c0fc11a610f14c48876701a37e32f464")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0354ec9ed01d20ec52aae19a9b858d3474d8234c11ad7bce630ad56c54afa562")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x030df20fcf6427bac38bb5d1a42287f4e4136ac5892340e994e6ea28deec1e55")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0528cf329c64e7ee3040bafbdeff61e241d99b424091e31472eda296fc9c6778")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x040416f24f623534634789660df5435ebf0c3e0c69e6c5b5ff6e757930bd1960")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x00380c8f936e2ed9fd488ae3bac7dce315ba21b11e88339cd5444435ccc9ea38")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x01cc4f5d5603d176f1a8e344392efd2d03ad0541832829d245e0e2291f255b75")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x05728917af5da91f9539310d99f5d142e011d6c8e015ea5423c502aa99c09752")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x00efb450a9e86e1a46e295a348f0f23590925107d17c56d7c788fecc17219aa1")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x02020d74d36c421ae1a025616b342d0784b8fcd977de6c53a6c26693774dca99")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x07cfb309b75fd3bf2705558ae511dc82335050969f4bf84fa2b7b4f583989287")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04651e48b2e9349a5365e009ece626809d7b7d02a617eb98c785a784812d75e9")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x00d77627b270f65122d0269719da923ccae822d9aad0f0947a3b5c8f71c0dcc7")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0199ad3d641b54c4d571b3fe37773a8b82b003377f0dd8b7d3b7758c32908ea8")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x044f33640a8ecfd3973e2e9172a7333482b2d297be2da289319e72d137cdfe6e")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x07e4adf9894d964189d00a02dcf1e6be7f801234f5216eab6b6f366b6701abf7")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x03641fa5b3c90452f5ff808f8a9817eda7c6aecfb5471dfdca559fb4e711ee90")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x03de5729efd2fcbd897a49a78fa923fc306df32e6e2f0e02d0eee2c2cc3f3533")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x062691891a3fc1e27f622966ca0be20c06563500c8f06c9bdb77bd2882d6c994")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x06608d3bf11c18e4688739f72205763d1590cc4f9885ae1d86e96e0604baa0be")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x011c9c9b39cac71e3419726ce779116d07249f51cbdda4fd98c25cbbf593a316")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x061e23b58203269caef0850f74da27b9748e3312ea40c6844dd68c557c462ad7")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04182cd9ab1d9488f870a572010bc2a3d9878440b25951e4ce010855cf83bdc8")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0520fe6c4a096793f9055e6823116d15f1df2fe89d306f9965f6a59f4f3ecb71")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0346b2b2d6e5810129e093093dcd3dfa99ed6d71f47723ea3fbe4d4e2fd4afa1")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x01359ca923e7f1448ec1dd2a3684bee4e8b682c8e8e973acea72877ce9f7e6cf")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x047c655f55cf307800dfefdad24de86fde9deadab145a1b392420f37b95d9675")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04ab291f16555fa8a968cd7c9c285a9598efd925f2d58b7aa38ad87dca8441a8")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x039f409c7c782101223d1f6f7d86c21a22c44ef959510e392c9c7c5d17c629c5")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x044be36b782f882ad86eecb0cd6beb02e1a2f9fb5587a3babfacead0cafb6052")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x050a1dfde9b504ad2906db6eb5b507203cd1ceb394c52ce7107679a53a0d538b")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x05c753c14da89e287b181c0dd11ac6c3680bdd7f1017dae083e7aebbeab183ab")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x02cf6306ed32232106c8015a3b180f386eee93e15f7b4f4fa57746525fc0520c")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x02c2014634d52e27420873cf347429091dfc6380689bd4f54d7d8e502c1c3a09")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x03cfb9c5bd93e02b2fdacde2058e33e5975c446345f010d850fc09cdf86ed8a1")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0363fa71a383cf3897933f1411fc5f806e311e84f72cb50a9ea4e1281f6b0299")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0728199657067ee16947b3fc76271676b4901b2a3686cffebcb960da91b05df8")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x03fdfbd47d27f3d34f0723b728e8921dc9bde34a9872df5a652a078d7e4ee021")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x07f241379440cacd7dc0efbe7858eb7de53cc02ca7d24197945c453398eff449")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x05b2e8771ea9a0004e3bf056f3727797cbb457a27574d5f104354e52a5c25f0b")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x00a8ddbce708de44a7e0b3b0333146e1e910245be6bf822ea057a081bda2e23e")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x02d521e0daca24e431aa47cd90a0f551c12270e533835613edce2e19aa9b0f61")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x06cdbc0f2aa54d2cf7d5ac3b93f855af03eef7b07aaee00341a6266c30e08ae6")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x03dd96a17111ec8f4c5da3ad6794c0961ceee452cbe92c7a0941112b36ed9bf3")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x05eafb1edeedc5c07ac07fdd06159344a2cfb92196a65d9ec0c5e732c36687dc")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04ab038d7b09eda9324577b260feaebdbcec5a7b7c7f449b312cfcd065c207e6")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04ca71981e4df6b505d2b0d94e235608463c58052570f68e495fc80c7fdef220")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x06dee9c6da4617e32aa419899c8ea8137e9b59d7e2759ffe573c15b77e413d2f")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x058f9e60b34ddab84dcbe2396065a4305b4a795a4770e4541e625d0460c6f186")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x047b7b4a802a10c1e6c9c735db6c34042d290906f274bea8fcecef17fc9af632")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x01849bcdb9ad7171096ecc936a186774084a074be0bfc0fbb9463a06a2bd430c")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x041870fbe04438348af5767bddaecd8aea3b49b4217547dec4d699b1466736cc")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0226c04e598076a9fa02aa64557daf28c0ec42e3d4da68d1965029d284738b07")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x01f0e971f0485a5b42eb92d6655c3ddb475cec4371f269a95335b2a7d6dac0fb")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x009f31cc2907dccbf994d35aa47ee3f4ebdf3703f795047a7b40dd3926431563")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04b40cce78f3b641e31ce4df58ce5a42c22cfbc198c84451ffe8cca4c64bd7d2")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0191660489e4bd8a3e4563173de4a226f3ac736962fdfb70f72cb93ce50f8b9f")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x018c0919618db971f74eb01f293f2daea814b475103373dc7ed8dd4c7b467410")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x035b60253848530e845c8753121577d0ef37002e941c3dc1fb240bd57eadc803")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x01ae99db1575ae91c8b43a9f71a5f362581ad9b413d97fa6fd029134957451d5")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x03e6e1d0f3f8a0f728148ebcbd5d7d337d7cb8feb58a37d2d1dfb357e172647b")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x018bc36dffa8f96a659e1a171b55d2706ee3e9ad619e16f5c38dd1f4a209b8f3")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x02c7a3ef1afb6a302b54afc3a107ff9199a16efe9a1cc3ab83fa5b64893de4ed")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x053a7bd889bed07bf5e27dd8e92f6ae85e4fe4e84b0c6dde9856e94469de4bd7")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04d383ff7ffc6318fda704aca35995f86bec5a02ce9a0bf9d3cc0cc2f03ccea9")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x04667b6762fb8ad53d07ef7e8a65b21ca96e0b3503037710d1292519c326f5cd")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x002cc8b43e75cf0b42a93c39ea98bcd46055dccc9589f02eb7fb536422e5921f")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x06b32ee98680871d38751447bfd76086ba4df0e7be59c55f4b2ce25582bf9c60")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x03e907927c7182faaa3b3c81358b82e734efac1f0609f0862d635cb1387102a3")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x03f3a5057b3a08975f0253728e512af78d2f437973f6a93793ea5e8424fbc6ea")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x014b491d73724779f8aa74b3fd8aa5821c21e1017224726a7a946bb6ca68d8f5")), + }, + std::array{ + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x05c8278c7bbfc30ae7f60e514fe3b9367aca84c54ad1373861695ea4abb814ef")), + }, + std::array{ + FF(std::string("0x064851937f9836ee5a08a7dde65e44b467018a82ba3bf99bba0b4502755c8074")), + FF(std::string("0x06a9ac84251294769eca450ffb52b441882be77cb85f422ff9ea5e73f1d971dc")), + FF(std::string("0x037ec35b710b0d04c9a2b71f2f7bd098c6a81d991d27f0fc1884f5ca545064de")), + }, + std::array{ + FF(std::string("0x005334f75b052c0235119816883040da72c6d0a61538bdfff46d6a242bfeb7a1")), + FF(std::string("0x05d0af4fcbd9e056c1020cca9d871ae68f80ee4af2ec6547cd49d6dca50aa431")), + FF(std::string("0x030131bce2fba5694114a19c46d24e00b4699dc00f1d53ba5ab99537901b1e65")), + }, + std::array{ + FF(std::string("0x05646a95a7c1ae86b34c0750ed2e641c538f93f13161be3c4957660f2e788965")), + FF(std::string("0x04b9f291d7b430c79fac36230a11f43e78581f5259692b52c90df47b7d4ec01a")), + FF(std::string("0x05006d393d3480f41a98f19127072dc83e00becf6ceb4d73d890e74abae01a13")), + }, + std::array{ + FF(std::string("0x062c9d42199f3b260e7cb8a115143106acf4f702e6b346fd202dc3b26a679d80")), + FF(std::string("0x051274d092db5099f180b1a8a13b7f2c7606836eabd8af54bf1d9ac2dc5717a5")), + FF(std::string("0x061fc552b8eb75e17ad0fb7aaa4ca528f415e14f0d9cdbed861a8db0bfff0c5b")), + }, + }; + + static constexpr std::array TEST_VECTOR_INPUT{ + FF(std::string("0x0000000000000000000000000000000000000000537461726b6e6574486f6e6b")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000000")), + FF(std::string("0x0000000000000000000000000000000000000000000000000000000000000001")), + }; + static constexpr std::array TEST_VECTOR_OUTPUT{ + FF(std::string("0x05b65cb3dd09edcddac6731b71ec2eaa6c2974d97a1d5978a1c97fa1b00c80ff")), + FF(std::string("0x0257539df2ca7f054b6206fa85d6fb92c692ed7f51b34534fcbab8e9cf821071")), + FF(std::string("0x05c6798b795dabcf3dee9ae895a0a48b98458b78c7f7885959261ddd251606f5")), + }; +}; + +} // namespace bb::starknet::crypto diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_permutation.hpp b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_permutation.hpp new file mode 100644 index 000000000000..8a57a78c7c22 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_permutation.hpp @@ -0,0 +1,88 @@ +#pragma once + +#include +#include +#include + +namespace bb::starknet::crypto { + +template class PoseidonPermutation { + public: + static constexpr size_t t = Params::t; + static constexpr size_t d = Params::d; + static constexpr size_t sbox_size = Params::sbox_size; + static constexpr size_t rounds_f = Params::rounds_f; + static constexpr size_t rounds_p = Params::rounds_p; + static constexpr size_t NUM_ROUNDS = Params::rounds_f + Params::rounds_p; + + using FF = typename Params::FF; + using State = std::array; + using RoundConstants = std::array; + using MatrixDiagonal = std::array; + using RoundConstantsContainer = std::array; + + static constexpr MatrixDiagonal internal_matrix_diagonal = Params::internal_matrix_diagonal; + static constexpr RoundConstantsContainer round_constants = Params::round_constants; + + static constexpr void add_round_constants(State& input, const RoundConstants& rc) + { + for (size_t i = 0; i < t; ++i) { + input[i] += rc[i]; + } + } + + static constexpr void matrix_multiplication_internal(State& input) + { + auto sum = input[0]; + for (size_t i = 1; i < t; ++i) { + sum += input[i]; + } + for (size_t i = 0; i < t; ++i) { + input[i] *= internal_matrix_diagonal[i]; + input[i] += sum; + } + } + + static constexpr void apply_single_sbox(FF& input) + { + static_assert(d == 3); + auto xx = input.sqr(); + input *= xx; + } + + static constexpr void apply_sbox(State& input) + { + for (auto& in : input) { + apply_single_sbox(in); + } + } + + static constexpr State permutation(const State& input) + { + State current_state(input); + + constexpr size_t rounds_f_beginning = rounds_f / 2; + for (size_t i = 0; i < rounds_f_beginning; ++i) { + add_round_constants(current_state, round_constants[i]); + apply_sbox(current_state); + matrix_multiplication_internal(current_state); + } + + const size_t p_end = rounds_f_beginning + rounds_p; + for (size_t i = rounds_f_beginning; i < p_end; ++i) { + current_state[2] += round_constants[i][2]; + apply_single_sbox(current_state[2]); + matrix_multiplication_internal(current_state); + } + + for (size_t i = p_end; i < NUM_ROUNDS; ++i) { + add_round_constants(current_state, round_constants[i]); + apply_sbox(current_state); + matrix_multiplication_internal(current_state); + } + + return current_state; + } +}; + +} // namespace bb::starknet::crypto diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_permutation.test.cpp b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_permutation.test.cpp new file mode 100644 index 000000000000..8199f515061a --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/crypto/poseidon/poseidon_permutation.test.cpp @@ -0,0 +1,57 @@ +#include "poseidon_permutation.hpp" +#include "barretenberg/ext/starknet/ecc/curves/stark252/stark252.hpp" +#include "poseidon_params.hpp" +#include + +using namespace bb::starknet; + +namespace { +auto& engine = bb::numeric::get_debug_randomness(); +} + +TEST(PoseidonPermutation, TestVectors) +{ + auto input = crypto::PoseidonStark252BaseFieldParams::TEST_VECTOR_INPUT; + auto expected = crypto::PoseidonStark252BaseFieldParams::TEST_VECTOR_OUTPUT; + auto result = crypto::PoseidonPermutation::permutation(input); + + EXPECT_EQ(result, expected); +} + +TEST(PoseidonPermutation, BasicTests) +{ + using fq = stark252::fq; + + fq a = fq::random_element(&engine); + fq b = fq::random_element(&engine); + fq c = fq::random_element(&engine); + + std::array input1{ a, b, c }; + std::array input2{ c, b, a }; + + auto r0 = crypto::PoseidonPermutation::permutation(input1); + auto r1 = crypto::PoseidonPermutation::permutation(input1); + auto r2 = crypto::PoseidonPermutation::permutation(input2); + + EXPECT_EQ(r0, r1); + EXPECT_NE(r0, r2); +} + +TEST(PoseidonPermutation, ConsistencyCheck) +{ + using fq = stark252::fq; + + fq a(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); + fq b(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); + fq c(std::string("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")); + + std::array input{ a, b, c }; + auto result = crypto::PoseidonPermutation::permutation(input); + + std::array expected{ + fq(std::string("0x03209a40f2b5e046337b5fae9e1e495dc3d9bcb5602ee9d4bd22aed772eab0f2")), + fq(std::string("0x04fbaa255051a602e8fcaf49614be34440da55ed42b3d8f33909ad0fbf8bce6a")), + fq(std::string("0x01655846c1e8dda470d0171d2d93efe9a71debadd42f9164e54ab90d70e04e48")), + }; + EXPECT_EQ(result, expected); +} diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/ecc/curves/stark252/stark252.hpp b/barretenberg/cpp/src/barretenberg/ext/starknet/ecc/curves/stark252/stark252.hpp new file mode 100644 index 000000000000..bb56973601df --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/ecc/curves/stark252/stark252.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include "barretenberg/ecc/fields/field.hpp" + +namespace bb::starknet::stark252 { + +struct FqParams { + static constexpr uint64_t modulus_0 = 0x0000000000000001ULL; + static constexpr uint64_t modulus_1 = 0x0000000000000000ULL; + static constexpr uint64_t modulus_2 = 0x0000000000000000ULL; + static constexpr uint64_t modulus_3 = 0x0800000000000011ULL; + + static constexpr uint64_t r_squared_0 = 0xfffffd737e000401ULL; + static constexpr uint64_t r_squared_1 = 0x00000001330fffffULL; + static constexpr uint64_t r_squared_2 = 0xffffffffff6f8000ULL; + static constexpr uint64_t r_squared_3 = 0x07ffd4ab5e008810ULL; + + static constexpr uint64_t r_inv = 0xffffffffffffffffULL; + + static constexpr uint64_t r_inv_0 = 0x0000000000000001ULL; + static constexpr uint64_t r_inv_1 = 0x0000000000000000ULL; + static constexpr uint64_t r_inv_2 = 0xf7ffffffffffffefULL; + static constexpr uint64_t r_inv_3 = 0x0800000000000010ULL; + + static constexpr uint64_t modulus_wasm_0 = 0x00000001; + static constexpr uint64_t modulus_wasm_1 = 0x00000000; + static constexpr uint64_t modulus_wasm_2 = 0x00000000; + static constexpr uint64_t modulus_wasm_3 = 0x00000000; + static constexpr uint64_t modulus_wasm_4 = 0x00000000; + static constexpr uint64_t modulus_wasm_5 = 0x00000000; + static constexpr uint64_t modulus_wasm_6 = 0x00440000; + static constexpr uint64_t modulus_wasm_7 = 0x00000000; + static constexpr uint64_t modulus_wasm_8 = 0x00080000; + + static constexpr uint64_t r_squared_wasm_0 = 0xfff5cdf800100001ULL; + static constexpr uint64_t r_squared_wasm_1 = 0x000004cc3fffffffULL; + static constexpr uint64_t r_squared_wasm_2 = 0xfffffffdbe000000ULL; + static constexpr uint64_t r_squared_wasm_3 = 0x0752ad7802200010ULL; + + static constexpr uint64_t r_inv_wasm_0 = 0x00000001; + static constexpr uint64_t r_inv_wasm_1 = 0x00000000; + static constexpr uint64_t r_inv_wasm_2 = 0x00000000; + static constexpr uint64_t r_inv_wasm_3 = 0x00000000; + static constexpr uint64_t r_inv_wasm_4 = 0x00000000; + static constexpr uint64_t r_inv_wasm_5 = 0x3fbc0000; + static constexpr uint64_t r_inv_wasm_6 = 0x0043ffff; + static constexpr uint64_t r_inv_wasm_7 = 0x3ff80000; + static constexpr uint64_t r_inv_wasm_8 = 0x0007ffff; +}; + +using fq = field; + +} // namespace bb::starknet::stark252 diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_flavor.hpp b/barretenberg/cpp/src/barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_flavor.hpp new file mode 100644 index 000000000000..363aeccf6759 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_flavor.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "barretenberg/ext/starknet/transcript/transcript.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp" + +namespace bb { + +class UltraStarknetFlavor : public UltraKeccakFlavor { + public: + using Transcript = Transcript_; +}; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp b/barretenberg/cpp/src/barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp new file mode 100644 index 000000000000..87940efac2f8 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp @@ -0,0 +1,162 @@ +#pragma once + +#include "barretenberg/ext/starknet/transcript/transcript.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_keccak_zk_flavor.hpp" + +namespace bb { + +class UltraStarknetZKFlavor : public UltraKeccakZKFlavor { + public: + /** + * @brief Derived class that defines proof structure for Ultra zero knowledge proofs, as well as supporting + * functions. + * TODO(https://github.com/AztecProtocol/barretenberg/issues/1355): Deduplicate zk flavor transcripts. + */ + + class Transcript : public Transcript_ { + public: + using Base = Transcript_; + // Note: we have a different vector of univariates because the degree for ZK flavors differs + std::vector> zk_sumcheck_univariates; + Commitment libra_concatenation_commitment; + FF libra_sum; + FF libra_claimed_evaluation; + Commitment libra_grand_sum_commitment; + Commitment libra_quotient_commitment; + FF libra_concatenation_eval; + FF libra_shifted_grand_sum_eval; + FF libra_grand_sum_eval; + FF libra_quotient_eval; + Commitment hiding_polynomial_commitment; + FF hiding_polynomial_eval; + + Transcript() = default; + + // Used by verifier to initialize the transcript + Transcript(const std::vector& proof) + : Transcript_(proof) + {} + + static std::shared_ptr prover_init_empty() + { + auto transcript = std::make_shared(); + constexpr uint32_t init{ 42 }; // arbitrary + transcript->send_to_verifier("Init", init); + return transcript; + }; + + static std::shared_ptr verifier_init_empty(const std::shared_ptr& transcript) + { + auto verifier_transcript = std::make_shared(transcript->proof_data); + verifier_transcript->template receive_from_prover("Init"); + return verifier_transcript; + }; + + /** + * @brief Takes a FULL Ultra proof and deserializes it into the public member variables + * that compose the structure. Must be called in order to access the structure of the + * proof. + * + */ + void deserialize_full_transcript(size_t public_input_size) + { + // take current proof and put them into the struct + size_t num_frs_read = 0; + auto& proof_data = this->proof_data; + for (size_t i = 0; i < public_input_size; ++i) { + this->public_inputs.push_back(Base::template deserialize_from_buffer(proof_data, num_frs_read)); + } + this->w_l_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->w_r_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->w_o_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->lookup_read_counts_comm = + Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->lookup_read_tags_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->w_4_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->lookup_inverses_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->z_perm_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + libra_concatenation_commitment = + Base::template deserialize_from_buffer(proof_data, num_frs_read); + libra_sum = Base::template deserialize_from_buffer(proof_data, num_frs_read); + + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { + zk_sumcheck_univariates.push_back( + Base::template deserialize_from_buffer>( + proof_data, num_frs_read)); + } + libra_claimed_evaluation = Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->sumcheck_evaluations = + Base::template deserialize_from_buffer>(proof_data, num_frs_read); + libra_grand_sum_commitment = Base::template deserialize_from_buffer(proof_data, num_frs_read); + libra_quotient_commitment = Base::template deserialize_from_buffer(proof_data, num_frs_read); + hiding_polynomial_commitment = Base::template deserialize_from_buffer(proof_data, num_frs_read); + hiding_polynomial_eval = Base::template deserialize_from_buffer(proof_data, num_frs_read); + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; ++i) { + this->gemini_fold_comms.push_back( + Base::template deserialize_from_buffer(proof_data, num_frs_read)); + } + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { + this->gemini_fold_evals.push_back(Base::template deserialize_from_buffer(proof_data, num_frs_read)); + } + libra_concatenation_eval = Base::template deserialize_from_buffer(proof_data, num_frs_read); + libra_shifted_grand_sum_eval = Base::template deserialize_from_buffer(proof_data, num_frs_read); + libra_grand_sum_eval = Base::template deserialize_from_buffer(proof_data, num_frs_read); + libra_quotient_eval = Base::template deserialize_from_buffer(proof_data, num_frs_read); + this->shplonk_q_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + + this->kzg_w_comm = Base::template deserialize_from_buffer(proof_data, num_frs_read); + } + + /** + * @brief Serializes the structure variables into a FULL Ultra proof. Should be called + * only if deserialize_full_transcript() was called and some transcript variable was + * modified. + * + */ + void serialize_full_transcript() + { + auto& proof_data = this->proof_data; + size_t old_proof_length = proof_data.size(); + proof_data.clear(); // clear proof_data so the rest of the function can replace it + for (const auto& public_input : this->public_inputs) { + Base::template serialize_to_buffer(public_input, proof_data); + } + Base::template serialize_to_buffer(this->w_l_comm, proof_data); + Base::template serialize_to_buffer(this->w_r_comm, proof_data); + Base::template serialize_to_buffer(this->w_o_comm, proof_data); + Base::template serialize_to_buffer(this->lookup_read_counts_comm, proof_data); + Base::template serialize_to_buffer(this->lookup_read_tags_comm, proof_data); + Base::template serialize_to_buffer(this->w_4_comm, proof_data); + Base::template serialize_to_buffer(this->lookup_inverses_comm, proof_data); + Base::template serialize_to_buffer(this->z_perm_comm, proof_data); + Base::template serialize_to_buffer(libra_concatenation_commitment, proof_data); + Base::template serialize_to_buffer(libra_sum, proof_data); + + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { + Base::template serialize_to_buffer(zk_sumcheck_univariates[i], proof_data); + } + Base::template serialize_to_buffer(libra_claimed_evaluation, proof_data); + + Base::template serialize_to_buffer(this->sumcheck_evaluations, proof_data); + Base::template serialize_to_buffer(libra_grand_sum_commitment, proof_data); + Base::template serialize_to_buffer(libra_quotient_commitment, proof_data); + Base::template serialize_to_buffer(hiding_polynomial_commitment, proof_data); + Base::template serialize_to_buffer(hiding_polynomial_eval, proof_data); + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; ++i) { + Base::template serialize_to_buffer(this->gemini_fold_comms[i], proof_data); + } + for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) { + Base::template serialize_to_buffer(this->gemini_fold_evals[i], proof_data); + } + Base::template serialize_to_buffer(libra_concatenation_eval, proof_data); + Base::template serialize_to_buffer(libra_shifted_grand_sum_eval, proof_data); + Base::template serialize_to_buffer(libra_grand_sum_eval, proof_data); + Base::template serialize_to_buffer(libra_quotient_eval, proof_data); + Base::template serialize_to_buffer(this->shplonk_q_comm, proof_data); + Base::template serialize_to_buffer(this->kzg_w_comm, proof_data); + + ASSERT(proof_data.size() == old_proof_length); + } + }; +}; +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/transcript/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/ext/starknet/transcript/CMakeLists.txt new file mode 100644 index 000000000000..e4421870ccf3 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/transcript/CMakeLists.txt @@ -0,0 +1 @@ +barretenberg_module(ext_starknet_transcript ext_starknet_crypto_poseidon) diff --git a/barretenberg/cpp/src/barretenberg/ext/starknet/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/ext/starknet/transcript/transcript.hpp new file mode 100644 index 000000000000..9631e0c4a214 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/ext/starknet/transcript/transcript.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "barretenberg/ext/starknet/crypto/poseidon/poseidon.hpp" +#include "barretenberg/transcript/transcript.hpp" + +namespace bb::starknet { + +inline bb::fr starknet_hash_uint256(std::vector const& data) +{ + using Poseidon = crypto::Poseidon; + using FF = Poseidon::FF; + + size_t elem_count = data.size(); + std::vector elems(2 * (1 + elem_count)); + + elems[0] = FF(std::string("0x0000000000000000000000000000000000000000537461726b6e6574486f6e6b")); // "StarknetHonk" + elems[1] = FF(0); + + for (size_t k = 0; k < elem_count; ++k) { + std::vector input = to_buffer(data[k]); + + std::array limb_lo = {}; + std::array limb_hi = {}; + + for (size_t i = 16; i < 32; ++i) { + limb_hi[i] = input[i - 16]; + limb_lo[i] = input[i]; + } + + elems[2 * (1 + k)] = from_buffer(limb_lo); + elems[2 * (1 + k) + 1] = from_buffer(limb_hi); + } + + FF iv = FF(1); + + FF output = Poseidon::hash(elems, iv); + + std::vector result = to_buffer(output); + + auto result_fr = from_buffer(result); + + return result_fr; +} + +struct StarknetTranscriptParams : public bb::KeccakTranscriptParams { + static inline Fr hash(const std::vector& data) { return starknet_hash_uint256(data); } +}; + +using StarknetTranscript = bb::BaseTranscript; + +} // namespace bb::starknet diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index c530eeebd92d..bdca698bd6c0 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -333,7 +333,9 @@ class UltraZKFlavor; class UltraRollupFlavor; class ECCVMFlavor; class UltraKeccakFlavor; +class UltraStarknetFlavor; class UltraKeccakZKFlavor; +class UltraStarknetZKFlavor; class MegaFlavor; class MegaZKFlavor; class TranslatorFlavor; @@ -373,7 +375,7 @@ template concept IsPlonkFlavor = IsAnyOf; template -concept IsUltraHonkFlavor = IsAnyOf; +concept IsUltraHonkFlavor = IsAnyOf; template concept IsUltraFlavor = IsUltraHonkFlavor || IsAnyOf; @@ -423,7 +425,9 @@ template concept IsECCVMRecursiveFlavor = IsAnyOf concept IsFoldingFlavor = IsAnyOf class FlavorSerializationTests : public ::testing::Te static void SetUpTestSuite() { bb::srs::init_crs_factory(bb::srs::get_ignition_crs_path()); } }; -using FlavorTypes = testing::Types; +using FlavorTypes = testing::Types; TYPED_TEST_SUITE(FlavorSerializationTests, FlavorTypes); // Test msgpack serialization/deserialization of verification keys diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp index 64e127806d53..f0d21ec98c48 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_flavor.hpp @@ -755,7 +755,6 @@ class MegaFlavor { /** * @brief Derived class that defines proof structure for Mega proofs, as well as supporting functions. * Note: Made generic for use in MegaRecursive. - * TODO(https://github.com/AztecProtocol/barretenberg/issues/877): Remove this Commitment template parameter */ class Transcript : public NativeTranscript { public: diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp index 7062a00cb7eb..e3cd9049e169 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp @@ -17,8 +17,8 @@ class MegaZKFlavor : public bb::MegaFlavor { /** * @brief Derived class that defines proof structure for Mega proofs, as well as supporting functions. * Note: Made generic for use in MegaRecursive. - * TODO(https://github.com/AztecProtocol/barretenberg/issues/877): Remove this Commitment template parameter - */ + * TODO(https://github.com/AztecProtocol/barretenberg/issues/1355): Deduplicate zk flavor transcripts. +i */ class Transcript : public MegaFlavor::Transcript { public: // Note: we have a different vector of univariates because the degree for ZK flavors differs diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp index a542efbd1306..b1f8493ed0a2 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp @@ -23,7 +23,7 @@ class UltraZKFlavor : public UltraFlavor { /** * @brief Derived class that defines proof structure for Ultra zero knowledge proofs, as well as supporting * functions. - * + * TODO(https://github.com/AztecProtocol/barretenberg/issues/1355): Deduplicate zk flavor transcripts. */ template class Transcript_ : public UltraFlavor::Transcript_ { public: diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp index 90587967bb89..af37c8af678a 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.test.cpp @@ -374,8 +374,14 @@ template class SumcheckTests : public ::testing::Test { }; // Define the FlavorTypes -using FlavorTypes = - testing::Types; +using FlavorTypes = testing::Types; TYPED_TEST_SUITE(SumcheckTests, FlavorTypes); diff --git a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp index 6fd27f276baa..7d4434b85950 100644 --- a/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp +++ b/barretenberg/cpp/src/barretenberg/trace_to_polynomials/trace_to_polynomials.cpp @@ -1,4 +1,6 @@ #include "trace_to_polynomials.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_flavor.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp" #include "barretenberg/flavor/plonk_flavors.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" @@ -157,7 +159,9 @@ void TraceToPolynomials::add_ecc_op_wires_to_proving_key(Builder& builde template class TraceToPolynomials; template class TraceToPolynomials; template class TraceToPolynomials; +template class TraceToPolynomials; template class TraceToPolynomials; +template class TraceToPolynomials; template class TraceToPolynomials; template class TraceToPolynomials; template class TraceToPolynomials; diff --git a/barretenberg/cpp/src/barretenberg/transcript/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/transcript/CMakeLists.txt index ff33c7197e59..84788f88117b 100644 --- a/barretenberg/cpp/src/barretenberg/transcript/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/transcript/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(transcript crypto_poseidon2) \ No newline at end of file +barretenberg_module(transcript crypto_poseidon2 ext_starknet_crypto_poseidon) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.cpp index 23e14c8e20d7..3cb0663a4ce0 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_prover.cpp @@ -117,7 +117,9 @@ template class DeciderProver_; template class DeciderProver_; template class DeciderProver_; template class DeciderProver_; +template class DeciderProver_; template class DeciderProver_; +template class DeciderProver_; template class DeciderProver_; template class DeciderProver_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp index 34e6adad7ec3..d0234837d165 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.cpp @@ -331,7 +331,9 @@ void DeciderProvingKey_::move_structured_trace_overflow_to_overflow_bloc template class DeciderProvingKey_; template class DeciderProvingKey_; template class DeciderProvingKey_; +template class DeciderProvingKey_; template class DeciderProvingKey_; +template class DeciderProvingKey_; template class DeciderProvingKey_; template class DeciderProvingKey_; template class DeciderProvingKey_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp index fd46f8e2792e..5bad1aa03afe 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_proving_key.hpp @@ -1,5 +1,7 @@ #pragma once #include "barretenberg/common/log.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_flavor.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp" #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/plonk_honk_shared/composer/composer_lib.hpp" #include "barretenberg/plonk_honk_shared/composer/permutation_lib.hpp" diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp index c475181c7c3d..a7a1fef12bb2 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp @@ -90,7 +90,9 @@ template bool DeciderVerifier_::verify() template class DeciderVerifier_; template class DeciderVerifier_; template class DeciderVerifier_; +template class DeciderVerifier_; template class DeciderVerifier_; +template class DeciderVerifier_; template class DeciderVerifier_; template class DeciderVerifier_; template class DeciderVerifier_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp index f60cad79b1a6..22ed0d7a4a5b 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp @@ -266,7 +266,9 @@ void OinkProver::commit_to_witness_polynomial(Polynomial& polynomial template class OinkProver; template class OinkProver; template class OinkProver; +template class OinkProver; template class OinkProver; +template class OinkProver; template class OinkProver; template class OinkProver; template class OinkProver; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp index fedc7eeb8497..f0e2d0d256c5 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_verifier.cpp @@ -1,5 +1,7 @@ #include "barretenberg/ultra_honk/oink_verifier.hpp" #include "barretenberg/common/throw_or_abort.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_flavor.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/mega_zk_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_keccak_flavor.hpp" @@ -156,7 +158,9 @@ template typename Flavor::RelationSeparator OinkVerifier< template class OinkVerifier; template class OinkVerifier; template class OinkVerifier; +template class OinkVerifier; template class OinkVerifier; +template class OinkVerifier; template class OinkVerifier; template class OinkVerifier; template class OinkVerifier; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp index 82c868b1a416..74ce69f09b65 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_honk.test.cpp @@ -47,7 +47,12 @@ template class UltraHonkTests : public ::testing::Test { static void SetUpTestSuite() { bb::srs::init_crs_factory(bb::srs::get_ignition_crs_path()); } }; -using FlavorTypes = testing::Types; +using FlavorTypes = testing::Types; TYPED_TEST_SUITE(UltraHonkTests, FlavorTypes); /** @@ -927,4 +932,4 @@ TYPED_TEST(UltraHonkTests, range_constraint_small_variable) circuit_builder.assert_equal(a_idx, c_idx); TestFixture::prove_and_verify(circuit_builder, /*expected_result=*/true); -} \ No newline at end of file +} diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index 66b8eb9e07d8..cf2da6afcf7f 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -84,7 +84,9 @@ template HonkProof UltraProver_::construct_proof( template class UltraProver_; template class UltraProver_; template class UltraProver_; +template class UltraProver_; template class UltraProver_; +template class UltraProver_; template class UltraProver_; template class UltraProver_; template class UltraProver_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp index 50fc459e07a1..c0876a304909 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.hpp @@ -58,7 +58,9 @@ template class UltraProver_ { using UltraProver = UltraProver_; using UltraKeccakProver = UltraProver_; +using UltraStarknetProver = UltraProver_; using UltraKeccakZKProver = UltraProver_; +using UltraStarknetZKProver = UltraProver_; using MegaProver = UltraProver_; using MegaZKProver = UltraProver_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp index 9de2a6dff35e..93aa7d17c7f5 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp @@ -183,8 +183,13 @@ template class UltraTranscriptTests : public ::testing::Test { } }; -using FlavorTypes = - ::testing::Types; +using FlavorTypes = ::testing::Types; TYPED_TEST_SUITE(UltraTranscriptTests, FlavorTypes); /** diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp index 2c10eef26e31..e53830d39915 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.cpp @@ -76,7 +76,9 @@ template bool UltraVerifier_::verify_proof(const HonkP template class UltraVerifier_; template class UltraVerifier_; template class UltraVerifier_; +template class UltraVerifier_; template class UltraVerifier_; +template class UltraVerifier_; template class UltraVerifier_; template class UltraVerifier_; template class UltraVerifier_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp index 884bd6ecb908..ffc1fbdbcd4d 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_verifier.hpp @@ -35,6 +35,7 @@ template class UltraVerifier_ { using UltraVerifier = UltraVerifier_; using UltraRollupVerifier = UltraVerifier_; using UltraKeccakVerifier = UltraVerifier_; +using UltraStarknetVerifier = UltraVerifier_; using MegaVerifier = UltraVerifier_; using MegaZKVerifier = UltraVerifier_; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/witness_computation.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/witness_computation.cpp index 29bbfe450ad1..a2a5ca867ad2 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/witness_computation.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/witness_computation.cpp @@ -1,5 +1,7 @@ #include "barretenberg/ultra_honk/witness_computation.hpp" #include "barretenberg/common/op_count.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_flavor.hpp" +#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_library.hpp" #include "barretenberg/plonk_honk_shared/proving_key_inspector.hpp" @@ -136,9 +138,11 @@ void WitnessComputation::complete_proving_key_for_test( template class WitnessComputation; template class WitnessComputation; template class WitnessComputation; +template class WitnessComputation; template class WitnessComputation; +template class WitnessComputation; template class WitnessComputation; template class WitnessComputation; template class WitnessComputation; -} // namespace bb \ No newline at end of file +} // namespace bb diff --git a/barretenberg/scripts/combine_benchmarks.py b/barretenberg/scripts/combine_benchmarks.py index 52729588660b..fed6d1e0e8f4 100755 --- a/barretenberg/scripts/combine_benchmarks.py +++ b/barretenberg/scripts/combine_benchmarks.py @@ -55,6 +55,7 @@ def modify_benchmark_data(file_paths): combined_results = {"benchmarks": []} for file_path in file_paths: + print("!") prefix = "" # Historical name compatibility: if "wasm" in file_path: @@ -83,6 +84,7 @@ def modify_benchmark_data(file_paths): def main(): file_paths = sys.argv[1::] + print(file_paths) final_data = modify_benchmark_data(file_paths) # Output the combined benchmark data as formatted JSON. diff --git a/barretenberg/ts/src/barretenberg/backend.ts b/barretenberg/ts/src/barretenberg/backend.ts index 063ab0ceb13b..0bb478ce7407 100644 --- a/barretenberg/ts/src/barretenberg/backend.ts +++ b/barretenberg/ts/src/barretenberg/backend.ts @@ -178,11 +178,16 @@ export class UltraPlonkBackend { * Options for the UltraHonkBackend. */ export type UltraHonkBackendOptions = { - /**Selecting this option will use the keccak hash function instead of poseidon + /** Selecting this option will use the keccak hash function instead of poseidon * when generating challenges in the proof. * Use this when you want to verify the created proof on an EVM chain. */ - keccak: boolean; + keccak?: boolean; + /**S electing this option will use the poseidon/stark252 hash function instead of poseidon + * when generating challenges in the proof. + * Use this when you want to verify the created proof on an Starknet chain with Garaga. + */ + starknet?: boolean; }; export class UltraHonkBackend { @@ -219,14 +224,18 @@ export class UltraHonkBackend { const proveUltraHonk = options?.keccak ? this.api.acirProveUltraKeccakHonk.bind(this.api) - : this.api.acirProveUltraHonk.bind(this.api); + : options?.starknet + ? this.api.acirProveUltraStarknetHonk.bind(this.api) + : this.api.acirProveUltraHonk.bind(this.api); const proofWithPublicInputs = await proveUltraHonk(this.acirUncompressedBytecode, gunzip(compressedWitness)); // Write VK to get the number of public inputs const writeVKUltraHonk = options?.keccak ? this.api.acirWriteVkUltraKeccakHonk.bind(this.api) - : this.api.acirWriteVkUltraHonk.bind(this.api); + : options?.starknet + ? this.api.acirWriteVkUltraStarknetHonk.bind(this.api) + : this.api.acirWriteVkUltraHonk.bind(this.api); const vk = await writeVKUltraHonk(this.acirUncompressedBytecode); const vkAsFields = await this.api.acirVkAsFieldsUltraHonk(new RawBuffer(vk)); @@ -248,10 +257,14 @@ export class UltraHonkBackend { const writeVkUltraHonk = options?.keccak ? this.api.acirWriteVkUltraKeccakHonk.bind(this.api) - : this.api.acirWriteVkUltraHonk.bind(this.api); + : options?.starknet + ? this.api.acirWriteVkUltraStarknetHonk.bind(this.api) + : this.api.acirWriteVkUltraHonk.bind(this.api); const verifyUltraHonk = options?.keccak ? this.api.acirVerifyUltraKeccakHonk.bind(this.api) - : this.api.acirVerifyUltraHonk.bind(this.api); + : options?.starknet + ? this.api.acirVerifyUltraStarknetHonk.bind(this.api) + : this.api.acirVerifyUltraHonk.bind(this.api); const vkBuf = await writeVkUltraHonk(this.acirUncompressedBytecode); return await verifyUltraHonk(proof, new RawBuffer(vkBuf)); @@ -261,7 +274,9 @@ export class UltraHonkBackend { await this.instantiate(); return options?.keccak ? await this.api.acirWriteVkUltraKeccakHonk(this.acirUncompressedBytecode) - : await this.api.acirWriteVkUltraHonk(this.acirUncompressedBytecode); + : options?.starknet + ? await this.api.acirWriteVkUltraStarknetHonk(this.acirUncompressedBytecode) + : await this.api.acirWriteVkUltraHonk(this.acirUncompressedBytecode); } /** @description Returns a solidity verifier */ diff --git a/barretenberg/ts/src/barretenberg_api/index.ts b/barretenberg/ts/src/barretenberg_api/index.ts index 9825f183a32f..a45984e6c032 100644 --- a/barretenberg/ts/src/barretenberg_api/index.ts +++ b/barretenberg/ts/src/barretenberg_api/index.ts @@ -473,6 +473,18 @@ export class BarretenbergApi { return out[0]; } + async acirProveUltraStarknetHonk(acirVec: Uint8Array, witnessVec: Uint8Array): Promise { + const inArgs = [acirVec, witnessVec].map(serializeBufferable); + const outTypes: OutputType[] = [BufferDeserializer()]; + const result = await this.wasm.callWasmExport( + 'acir_prove_ultra_starknet_honk', + inArgs, + outTypes.map(t => t.SIZE_IN_BYTES), + ); + const out = result.map((r, i) => outTypes[i].fromBuffer(r)); + return out[0]; + } + async acirVerifyUltraHonk(proofBuf: Uint8Array, vkBuf: Uint8Array): Promise { const inArgs = [proofBuf, vkBuf].map(serializeBufferable); const outTypes: OutputType[] = [BoolDeserializer()]; @@ -497,6 +509,18 @@ export class BarretenbergApi { return out[0]; } + async acirVerifyUltraStarknetHonk(proofBuf: Uint8Array, vkBuf: Uint8Array): Promise { + const inArgs = [proofBuf, vkBuf].map(serializeBufferable); + const outTypes: OutputType[] = [BoolDeserializer()]; + const result = await this.wasm.callWasmExport( + 'acir_verify_ultra_starknet_honk', + inArgs, + outTypes.map(t => t.SIZE_IN_BYTES), + ); + const out = result.map((r, i) => outTypes[i].fromBuffer(r)); + return out[0]; + } + async acirWriteVkUltraHonk(acirVec: Uint8Array): Promise { const inArgs = [acirVec].map(serializeBufferable); const outTypes: OutputType[] = [BufferDeserializer()]; @@ -521,6 +545,18 @@ export class BarretenbergApi { return out[0]; } + async acirWriteVkUltraStarknetHonk(acirVec: Uint8Array): Promise { + const inArgs = [acirVec].map(serializeBufferable); + const outTypes: OutputType[] = [BufferDeserializer()]; + const result = await this.wasm.callWasmExport( + 'acir_write_vk_ultra_starknet_honk', + inArgs, + outTypes.map(t => t.SIZE_IN_BYTES), + ); + const out = result.map((r, i) => outTypes[i].fromBuffer(r)); + return out[0]; + } + async acirProofAsFieldsUltraHonk(proofBuf: Uint8Array): Promise { const inArgs = [proofBuf].map(serializeBufferable); const outTypes: OutputType[] = [VectorDeserializer(Fr)]; diff --git a/barretenberg/ts/src/main.ts b/barretenberg/ts/src/main.ts index 3afac3f5ad10..ea77e29b9a5c 100755 --- a/barretenberg/ts/src/main.ts +++ b/barretenberg/ts/src/main.ts @@ -407,7 +407,9 @@ export async function proveUltraHonk( const acirProveUltraHonk = options?.keccak ? api.acirProveUltraKeccakHonk.bind(api) - : api.acirProveUltraHonk.bind(api); + : options?.starknet + ? api.acirProveUltraStarknetHonk.bind(api) + : api.acirProveUltraHonk.bind(api); const proof = await acirProveUltraHonk(bytecode, witness); if (outputPath === '-') { @@ -435,7 +437,9 @@ export async function writeVkUltraHonk( const acirWriteVkUltraHonk = options?.keccak ? api.acirWriteVkUltraKeccakHonk.bind(api) - : api.acirWriteVkUltraHonk.bind(api); + : options?.starknet + ? api.acirWriteVkUltraStarknetHonk.bind(api) + : api.acirWriteVkUltraHonk.bind(api); const vk = await acirWriteVkUltraHonk(bytecode); if (outputPath === '-') { @@ -460,7 +464,9 @@ export async function verifyUltraHonk( try { const acirVerifyUltraHonk = options?.keccak ? api.acirVerifyUltraKeccakHonk.bind(api) - : api.acirVerifyUltraHonk.bind(api); + : options?.starknet + ? api.acirVerifyUltraStarknetHonk.bind(api) + : api.acirVerifyUltraHonk.bind(api); const verified = await acirVerifyUltraHonk( Uint8Array.from(readFileSync(proofPath)), new RawBuffer(readFileSync(vkPath)), @@ -679,6 +685,18 @@ program await proveUltraHonk(bytecodePath, witnessPath, crsPath, outputPath, { keccak: true }); }); +program + .command('prove_ultra_starknet_honk') + .description('Generate a proof and write it to a file.') + .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') + .option('-r, --recursive', 'Create a SNARK friendly proof', false) + .option('-w, --witness-path ', 'Specify the witness path', './target/witness.gz') + .option('-o, --output-path ', 'Specify the proof output path', './proofs/proof') + .action(async ({ bytecodePath, recursive, witnessPath, outputPath, crsPath }) => { + handleGlobalOptions(); + await proveUltraHonk(bytecodePath, witnessPath, crsPath, outputPath, { starknet: true }); + }); + program .command('write_vk_ultra_honk') .description('Output verification key.') @@ -699,6 +717,17 @@ program await writeVkUltraHonk(bytecodePath, crsPath, outputPath, { keccak: true }); }); +program + .command('write_vk_ultra_starknet_honk') + .description('Output verification key.') + .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') + .option('-r, --recursive', 'Create a SNARK friendly proof', false) + .requiredOption('-o, --output-path ', 'Specify the path to write the key') + .action(async ({ bytecodePath, recursive, outputPath, crsPath }) => { + handleGlobalOptions(); + await writeVkUltraHonk(bytecodePath, crsPath, outputPath, { starknet: true }); + }); + program .command('verify_ultra_honk') .description('Verify a proof. Process exists with success or failure code.') @@ -721,6 +750,17 @@ program process.exit(result ? 0 : 1); }); +program + .command('verify_ultra_starknet_honk') + .description('Verify a proof. Process exists with success or failure code.') + .requiredOption('-p, --proof-path ', 'Specify the path to the proof') + .requiredOption('-k, --vk ', 'path to a verification key. avoids recomputation.') + .action(async ({ proofPath, vk }) => { + const { crsPath } = handleGlobalOptions(); + const result = await verifyUltraHonk(proofPath, vk, crsPath, { starknet: true }); + process.exit(result ? 0 : 1); + }); + program .command('proof_as_fields_honk') .description('Return the proof as fields elements') diff --git a/cspell.json b/cspell.json index a2edfcd84939..b8e8a76eb44c 100644 --- a/cspell.json +++ b/cspell.json @@ -272,6 +272,7 @@ "socat", "solhint", "SSTORE", + "starknet", "staticcall", "stdlib", "struct", diff --git a/yarn-project/bb-prover/src/bb/execute.ts b/yarn-project/bb-prover/src/bb/execute.ts index 699465c6c6d3..ca0bdfdb029d 100644 --- a/yarn-project/bb-prover/src/bb/execute.ts +++ b/yarn-project/bb-prover/src/bb/execute.ts @@ -184,6 +184,9 @@ function getArgs(flavor: UltraHonkFlavor) { case 'ultra_keccak_honk': { return ['--scheme', 'ultra_honk', '--oracle_hash', 'keccak']; } + case 'ultra_starknet_honk': { + return ['--scheme', 'ultra_honk', '--oracle_hash', 'starknet']; + } case 'ultra_rollup_honk': { return ['--scheme', 'ultra_honk', '--oracle_hash', 'poseidon2', '--ipa_accumulation']; } diff --git a/yarn-project/bb-prover/src/honk.ts b/yarn-project/bb-prover/src/honk.ts index 31909160369e..7f04ad92fe18 100644 --- a/yarn-project/bb-prover/src/honk.ts +++ b/yarn-project/bb-prover/src/honk.ts @@ -1,6 +1,6 @@ import type { ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/server'; -export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_rollup_honk'; +export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_starknet_honk' | 'ultra_rollup_honk'; const UltraKeccakHonkCircuits = ['RootRollupArtifact'] as const satisfies ServerProtocolArtifact[]; const UltraHonkCircuits = ['BaseParityArtifact', 'RootParityArtifact'] as const satisfies ServerProtocolArtifact[]; @@ -17,6 +17,7 @@ export function getUltraHonkFlavorForCircuit(artifact: UltraHonkServerProtocolAr export function getUltraHonkFlavorForCircuit(artifact: UltraRollupHonkServerProtocolArtifact): 'ultra_rollup_honk'; export function getUltraHonkFlavorForCircuit(artifact: ServerProtocolArtifact): UltraHonkFlavor; export function getUltraHonkFlavorForCircuit(artifact: ServerProtocolArtifact): UltraHonkFlavor { + // STARKNET: how to allow for the distinction between keccak/starknet? ultra_keccak_honk is returned in both cases if (isUltraKeccakHonkCircuit(artifact)) { return 'ultra_keccak_honk'; } else if (UltraHonkCircuits.includes(artifact as UltraHonkServerProtocolArtifact)) {