Skip to content

Commit 6bc34a1

Browse files
feltroidprimeraugferludamad
authored
feat: Garaga UltraStarknet[Zk]Honk flavours (#11489)
Adds a `ultra_starknet_flavour` and `ultra_starknet_zk_flavour`, forked from the ultra_keccak_(zk)_flavour. This was tested with bb 0.82.2 with a reference corresponding implementation of the transcript in python similar to the keccak one. See generic proof -> Transcript implementation https://github.com/keep-starknet-strange/garaga/blob/f5921e0f7e69f474ee0a88b6ecfb52252fc7cc3d/hydra/garaga/precompiled_circuits/honk.py#L526 https://github.com/keep-starknet-strange/garaga/blob/f5921e0f7e69f474ee0a88b6ecfb52252fc7cc3d/hydra/garaga/precompiled_circuits/honk.py#L448-L501 ~The Starknet poseidon hash was imported from the reference implementation from CryptoExperts (used in production in Starkware STONE prover) https://github.com/CryptoExperts/poseidon~ Starknet field is defined using existing templates and poseidon implementation re-uses Sponge from poseidon2 --------- Co-authored-by: Rodrigo Ferreira <[email protected]> Co-authored-by: raugfer <[email protected]> Co-authored-by: ludamad <[email protected]> Co-authored-by: ludamad <[email protected]>
1 parent c302fdd commit 6bc34a1

File tree

57 files changed

+1303
-41
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1303
-41
lines changed

barretenberg/acir_tests/bbjs-test/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ async function generateProof({
4242
const witness = await fs.readFile(witnessPath);
4343
const proof = await backend.generateProof(new Uint8Array(witness), {
4444
keccak: oracleHash === "keccak",
45+
starknet: oracleHash === "starknet",
4546
});
4647
assert(
4748
proof.proof.length === UH_PROOF_LENGTH_IN_BYTES,
@@ -66,6 +67,7 @@ async function generateProof({
6667

6768
const verificationKey = await backend.getVerificationKey({
6869
keccak: oracleHash === "keccak",
70+
starknet: oracleHash === "starknet",
6971
});
7072
await fs.writeFile(vkeyPath(outputDirectory), Buffer.from(verificationKey));
7173
debug("Verification key written to " + vkeyPath(outputDirectory));

barretenberg/acir_tests/bootstrap.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ function test_cmds_internal {
182182
echo SYS=ultra_honk FLOW=prove_then_verify $run_test assert_statement
183183
echo SYS=ultra_honk FLOW=prove_then_verify $run_test double_verify_honk_proof
184184
echo SYS=ultra_honk FLOW=prove_then_verify HASH=keccak $run_test assert_statement
185+
echo SYS=ultra_honk FLOW=prove_then_verify HASH=starknet $run_test assert_statement
185186
echo SYS=ultra_honk FLOW=prove_then_verify ROLLUP=true $run_test verify_rollup_honk_proof
186187

187188
# prove and verify using bb.js classes

barretenberg/cpp/src/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ add_subdirectory(barretenberg/eccvm)
8080
add_subdirectory(barretenberg/env)
8181
add_subdirectory(barretenberg/trace_to_polynomials)
8282
add_subdirectory(barretenberg/examples)
83+
add_subdirectory(barretenberg/ext/starknet/crypto)
84+
add_subdirectory(barretenberg/ext/starknet/transcript)
8385
add_subdirectory(barretenberg/flavor)
8486
add_subdirectory(barretenberg/goblin)
8587
add_subdirectory(barretenberg/grumpkin_srs_gen)
@@ -141,6 +143,7 @@ set(BARRETENBERG_TARGET_OBJECTS
141143
$<TARGET_OBJECTS:dsl_objects>
142144
$<TARGET_OBJECTS:ecc_objects>
143145
$<TARGET_OBJECTS:eccvm_objects>
146+
$<TARGET_OBJECTS:ext_starknet_crypto_poseidon_objects>
144147
$<TARGET_OBJECTS:trace_to_polynomials_objects>
145148
$<TARGET_OBJECTS:simple_example_objects>
146149
$<TARGET_OBJECTS:flavor_objects>

barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ template <typename Flavor, typename Circuit = typename Flavor::CircuitBuilder>
2222
Circuit _compute_circuit(const std::string& bytecode_path, const std::string& witness_path)
2323
{
2424
uint32_t honk_recursion = 0;
25-
if constexpr (IsAnyOf<Flavor, UltraFlavor, UltraKeccakFlavor, UltraKeccakZKFlavor>) {
25+
if constexpr (IsAnyOf<Flavor,
26+
UltraFlavor,
27+
UltraKeccakFlavor,
28+
UltraStarknetFlavor,
29+
UltraKeccakZKFlavor,
30+
UltraStarknetZKFlavor>) {
2631
honk_recursion = 1;
2732
} else if constexpr (IsAnyOf<Flavor, UltraRollupFlavor>) {
2833
honk_recursion = 2;
@@ -171,8 +176,12 @@ void UltraHonkAPI::prove(const Flags& flags,
171176
_write(_prove<UltraFlavor>(flags.write_vk, bytecode_path, witness_path));
172177
} else if (flags.oracle_hash_type == "keccak" && !flags.zk) {
173178
_write(_prove<UltraKeccakFlavor>(flags.write_vk, bytecode_path, witness_path));
179+
} else if (flags.oracle_hash_type == "starknet" && !flags.zk) {
180+
_write(_prove<UltraStarknetFlavor>(flags.write_vk, bytecode_path, witness_path));
174181
} else if (flags.oracle_hash_type == "keccak" && flags.zk) {
175182
_write(_prove<UltraKeccakZKFlavor>(flags.write_vk, bytecode_path, witness_path));
183+
} else if (flags.oracle_hash_type == "starknet" && flags.zk) {
184+
_write(_prove<UltraStarknetZKFlavor>(flags.write_vk, bytecode_path, witness_path));
176185
} else {
177186
throw_or_abort("Invalid proving options specified in _prove");
178187
}
@@ -188,14 +197,23 @@ bool UltraHonkAPI::verify(const Flags& flags,
188197
return _verify<UltraRollupFlavor>(ipa_accumulation, public_inputs_path, proof_path, vk_path);
189198
}
190199
if (flags.zk) {
191-
return _verify<UltraKeccakZKFlavor>(ipa_accumulation, public_inputs_path, proof_path, vk_path);
200+
if (flags.oracle_hash_type == "keccak") {
201+
return _verify<UltraKeccakZKFlavor>(ipa_accumulation, public_inputs_path, proof_path, vk_path);
202+
}
203+
if (flags.oracle_hash_type == "starknet") {
204+
return _verify<UltraStarknetZKFlavor>(ipa_accumulation, public_inputs_path, proof_path, vk_path);
205+
}
206+
return false;
192207
}
193208
if (flags.oracle_hash_type == "poseidon2") {
194209
return _verify<UltraFlavor>(ipa_accumulation, public_inputs_path, proof_path, vk_path);
195210
}
196211
if (flags.oracle_hash_type == "keccak") {
197212
return _verify<UltraKeccakFlavor>(ipa_accumulation, public_inputs_path, proof_path, vk_path);
198213
}
214+
if (flags.oracle_hash_type == "starknet") {
215+
return _verify<UltraStarknetFlavor>(ipa_accumulation, public_inputs_path, proof_path, vk_path);
216+
}
199217
return false;
200218
}
201219

@@ -219,8 +237,12 @@ void UltraHonkAPI::write_vk(const Flags& flags,
219237
_write(_compute_vk<UltraFlavor>(bytecode_path, ""));
220238
} else if (flags.oracle_hash_type == "keccak" && !flags.zk) {
221239
_write(_compute_vk<UltraKeccakFlavor>(bytecode_path, ""));
240+
} else if (flags.oracle_hash_type == "starknet" && !flags.zk) {
241+
_write(_compute_vk<UltraStarknetFlavor>(bytecode_path, ""));
222242
} else if (flags.oracle_hash_type == "keccak" && flags.zk) {
223243
_write(_compute_vk<UltraKeccakZKFlavor>(bytecode_path, ""));
244+
} else if (flags.oracle_hash_type == "starknet" && flags.zk) {
245+
_write(_compute_vk<UltraStarknetZKFlavor>(bytecode_path, ""));
224246
} else {
225247
throw_or_abort("Invalid proving options specified in _prove");
226248
}

barretenberg/cpp/src/barretenberg/bb/cli.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,15 @@ int parse_and_run_cli_command(int argc, char* argv[])
178178

179179
const auto add_oracle_hash_option = [&](CLI::App* subcommand) {
180180
return subcommand
181-
->add_option("--oracle_hash",
182-
flags.oracle_hash_type,
183-
"The hash function used by the prover as random oracle standing in for a verifier's challenge "
184-
"generation. Poseidon2 is to be used for proofs that are intended to be verified inside of a "
185-
"circuit. Keccak is optimized for verification in an Ethereum smart contract, where Keccak "
186-
"has a privileged position due to the existence of an EVM precompile.")
187-
->check(CLI::IsMember({ "poseidon2", "keccak" }).name("is_member"));
181+
->add_option(
182+
"--oracle_hash",
183+
flags.oracle_hash_type,
184+
"The hash function used by the prover as random oracle standing in for a verifier's challenge "
185+
"generation. Poseidon2 is to be used for proofs that are intended to be verified inside of a "
186+
"circuit. Keccak is optimized for verification in an Ethereum smart contract, where Keccak "
187+
"has a privileged position due to the existence of an EVM precompile. Starknet is optimized "
188+
"for verification in a Starknet smart contract, which can be generated using the Garaga library.")
189+
->check(CLI::IsMember({ "poseidon2", "keccak", "starknet" }).name("is_member"));
188190
};
189191

190192
const auto add_output_format_option = [&](CLI::App* subcommand) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
barretenberg_module(append_only_tree_bench crypto_poseidon2 crypto_pedersen_hash crypto_merkle_tree)
1+
barretenberg_module(append_only_tree_bench crypto_poseidon2 ext_starknet_crypto_poseidon crypto_pedersen_hash crypto_merkle_tree)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
barretenberg_module(indexed_tree_bench crypto_poseidon2 crypto_pedersen_hash crypto_merkle_tree)
1+
barretenberg_module(indexed_tree_bench crypto_poseidon2 ext_starknet_crypto_poseidon crypto_pedersen_hash crypto_merkle_tree)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
barretenberg_module(merkle_tree_bench crypto_poseidon2 crypto_pedersen_hash crypto_merkle_tree)
1+
barretenberg_module(merkle_tree_bench crypto_poseidon2 ext_starknet_crypto_poseidon crypto_pedersen_hash crypto_merkle_tree)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
barretenberg_module(poseidon2_bench crypto_poseidon2)
1+
barretenberg_module(poseidon2_bench crypto_poseidon2 ext_starknet_crypto_poseidon)

barretenberg/cpp/src/barretenberg/commitment_schemes/small_subgroup_ipa/small_subgroup_ipa.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "barretenberg/ecc/curves/bn254/bn254.hpp"
55
#include "barretenberg/eccvm/eccvm_flavor.hpp"
66
#include "barretenberg/eccvm/eccvm_translation_data.hpp"
7+
#include "barretenberg/ext/starknet/stdlib_circuit_builders/ultra_starknet_zk_flavor.hpp"
78
#include "barretenberg/polynomials/polynomial.hpp"
89
#include "barretenberg/polynomials/univariate.hpp"
910
#include "barretenberg/stdlib/primitives/curves/grumpkin.hpp"
@@ -441,6 +442,7 @@ template class SmallSubgroupIPAProver<TranslatorFlavor>;
441442
template class SmallSubgroupIPAProver<MegaZKFlavor>;
442443
template class SmallSubgroupIPAProver<UltraZKFlavor>;
443444
template class SmallSubgroupIPAProver<UltraKeccakZKFlavor>;
445+
template class SmallSubgroupIPAProver<UltraStarknetZKFlavor>;
444446

445447
// Instantiations used in tests
446448
template class SmallSubgroupIPAProver<BN254Settings>;

barretenberg/cpp/src/barretenberg/crypto/poseidon2/sponge/sponge.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,14 @@ template <typename FF, size_t rate, size_t capacity, size_t t, typename Permutat
132132
{
133133
size_t in_len = input.size();
134134
const uint256_t iv = (static_cast<uint256_t>(in_len) << 64) + out_len - 1;
135+
return hash_internal<out_len>(input, iv);
136+
}
137+
138+
template <size_t out_len> static std::array<FF, out_len> hash_internal(std::span<const FF> input, FF iv)
139+
{
135140
FieldSponge sponge(iv);
136141

142+
size_t in_len = input.size();
137143
for (size_t i = 0; i < in_len; ++i) {
138144
sponge.absorb(input[i]);
139145
}
@@ -146,5 +152,6 @@ template <typename FF, size_t rate, size_t capacity, size_t t, typename Permutat
146152
}
147153

148154
static FF hash_internal(std::span<const FF> input) { return hash_internal<1>(input)[0]; }
155+
static FF hash_internal(std::span<const FF> input, FF iv) { return hash_internal<1>(input, iv)[0]; }
149156
};
150-
} // namespace bb::crypto
157+
} // namespace bb::crypto

barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,23 @@ WASM_EXPORT void acir_prove_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t c
254254
*out = to_heap_buffer(to_buffer(proof));
255255
}
256256

257+
WASM_EXPORT void acir_prove_ultra_starknet_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out)
258+
{
259+
// Lambda function to ensure things get freed before proving.
260+
UltraStarknetProver prover = [&] {
261+
const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 };
262+
acir_format::AcirProgram program{
263+
acir_format::circuit_buf_to_acir_format(from_buffer<std::vector<uint8_t>>(acir_vec)),
264+
acir_format::witness_buf_to_witness_data(from_buffer<std::vector<uint8_t>>(witness_vec))
265+
};
266+
auto builder = acir_format::create_circuit<UltraCircuitBuilder>(program, metadata);
267+
268+
return UltraStarknetProver(builder);
269+
}();
270+
auto proof = prover.construct_proof();
271+
*out = to_heap_buffer(to_buffer(proof));
272+
}
273+
257274
WASM_EXPORT void acir_verify_ultra_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result)
258275
{
259276
using VerificationKey = UltraFlavor::VerificationKey;
@@ -280,6 +297,19 @@ WASM_EXPORT void acir_verify_ultra_keccak_honk(uint8_t const* proof_buf, uint8_t
280297
*result = verifier.verify_proof(proof);
281298
}
282299

300+
WASM_EXPORT void acir_verify_ultra_starknet_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result)
301+
{
302+
using VerificationKey = UltraStarknetFlavor::VerificationKey;
303+
using Verifier = UltraVerifier_<UltraStarknetFlavor>;
304+
305+
auto proof = from_buffer<std::vector<bb::fr>>(from_buffer<std::vector<uint8_t>>(proof_buf));
306+
auto verification_key = std::make_shared<VerificationKey>(from_buffer<VerificationKey>(vk_buf));
307+
308+
Verifier verifier{ verification_key };
309+
310+
*result = verifier.verify_proof(proof);
311+
}
312+
283313
WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, uint8_t** out)
284314
{
285315
using DeciderProvingKey = DeciderProvingKey_<UltraFlavor>;
@@ -315,6 +345,24 @@ WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec, uint8_
315345
*out = to_heap_buffer(to_buffer(vk));
316346
}
317347

348+
WASM_EXPORT void acir_write_vk_ultra_starknet_honk(uint8_t const* acir_vec, uint8_t** out)
349+
{
350+
using DeciderProvingKey = DeciderProvingKey_<UltraStarknetFlavor>;
351+
using VerificationKey = UltraStarknetFlavor::VerificationKey;
352+
353+
// lambda to free the builder
354+
DeciderProvingKey proving_key = [&] {
355+
const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 };
356+
acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format(
357+
from_buffer<std::vector<uint8_t>>(acir_vec)) };
358+
auto builder = acir_format::create_circuit<UltraCircuitBuilder>(program, metadata);
359+
return DeciderProvingKey(builder);
360+
}();
361+
VerificationKey vk(proving_key.proving_key);
362+
vinfo("Constructed UltraStarknetHonk verification key");
363+
*out = to_heap_buffer(to_buffer(vk));
364+
}
365+
318366
WASM_EXPORT void acir_honk_solidity_verifier(uint8_t const* proof_buf, uint8_t const* vk_buf, uint8_t** out)
319367
{
320368
using VerificationKey = UltraKeccakFlavor::VerificationKey;

barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,15 @@ WASM_EXPORT void acir_serialize_verification_key_into_fields(in_ptr acir_compose
7878

7979
WASM_EXPORT void acir_prove_ultra_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out);
8080
WASM_EXPORT void acir_prove_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out);
81+
WASM_EXPORT void acir_prove_ultra_starknet_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out);
8182

8283
WASM_EXPORT void acir_verify_ultra_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result);
8384
WASM_EXPORT void acir_verify_ultra_keccak_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result);
85+
WASM_EXPORT void acir_verify_ultra_starknet_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result);
8486

8587
WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, uint8_t** out);
8688
WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t** out);
89+
WASM_EXPORT void acir_write_vk_ultra_starknet_honk(uint8_t const* acir_vec, uint8_t** out);
8790

8891
WASM_EXPORT void acir_proof_as_fields_ultra_honk(uint8_t const* proof_buf, fr::vec_out_buf out);
8992

barretenberg/cpp/src/barretenberg/ecc/fields/field_declarations.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,8 @@ template <class Params_> struct alignas(32) field {
325325

326326
BB_INLINE constexpr field pow(const uint256_t& exponent) const noexcept;
327327
BB_INLINE constexpr field pow(uint64_t exponent) const noexcept;
328-
static_assert(Params::modulus_0 != 1);
328+
// STARKNET: next line was commented as stark252 violates the assertion
329+
// static_assert(Params::modulus_0 != 1);
329330
static constexpr uint256_t modulus_minus_two =
330331
uint256_t(Params::modulus_0 - 2ULL, Params::modulus_1, Params::modulus_2, Params::modulus_3);
331332
constexpr field invert() const noexcept;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(poseidon)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
barretenberg_module(ext_starknet_crypto_poseidon ecc)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "poseidon.hpp"
2+
3+
namespace bb::starknet::crypto {
4+
5+
template <typename Params>
6+
typename Poseidon<Params>::FF Poseidon<Params>::hash(const std::vector<typename Poseidon<Params>::FF>& input)
7+
{
8+
return Sponge::hash_internal(input);
9+
}
10+
11+
template <typename Params>
12+
typename Poseidon<Params>::FF Poseidon<Params>::hash(const std::vector<typename Poseidon<Params>::FF>& input, FF iv)
13+
{
14+
return Sponge::hash_internal(input, iv);
15+
}
16+
17+
template class Poseidon<PoseidonStark252BaseFieldParams>;
18+
19+
} // namespace bb::starknet::crypto
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
#include "barretenberg/crypto/poseidon2/sponge/sponge.hpp"
4+
#include "poseidon_params.hpp"
5+
#include "poseidon_permutation.hpp"
6+
7+
namespace bb::starknet::crypto {
8+
9+
template <typename Params> class Poseidon {
10+
public:
11+
using FF = typename Params::FF;
12+
13+
using Sponge = bb::crypto::FieldSponge<FF, Params::t - 1, 1, Params::t, PoseidonPermutation<Params>>;
14+
15+
static FF hash(const std::vector<FF>& input);
16+
17+
static FF hash(const std::vector<FF>& input, FF iv);
18+
};
19+
20+
extern template class Poseidon<PoseidonStark252BaseFieldParams>;
21+
22+
} // namespace bb::starknet::crypto
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "poseidon.hpp"
2+
#include "barretenberg/ext/starknet/ecc/curves/stark252/stark252.hpp"
3+
#include "poseidon_params.hpp"
4+
#include <gtest/gtest.h>
5+
6+
using namespace bb::starknet;
7+
8+
namespace {
9+
auto& engine = bb::numeric::get_debug_randomness();
10+
}
11+
12+
TEST(Poseidon, HashBasicTests)
13+
{
14+
using fq = stark252::fq;
15+
16+
fq a = fq::random_element(&engine);
17+
fq b = fq::random_element(&engine);
18+
fq c = fq::random_element(&engine);
19+
fq d = fq::random_element(&engine);
20+
21+
std::vector<fq> input1{ a, b, c, d };
22+
std::vector<fq> input2{ d, c, b, a };
23+
24+
auto r0 = crypto::Poseidon<crypto::PoseidonStark252BaseFieldParams>::hash(input1);
25+
auto r1 = crypto::Poseidon<crypto::PoseidonStark252BaseFieldParams>::hash(input1);
26+
auto r2 = crypto::Poseidon<crypto::PoseidonStark252BaseFieldParams>::hash(input2);
27+
28+
EXPECT_EQ(r0, r1);
29+
EXPECT_NE(r0, r2);
30+
}
31+
32+
TEST(Poseidon, HashConsistencyCheck)
33+
{
34+
using fq = stark252::fq;
35+
36+
fq a(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"));
37+
fq b(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"));
38+
fq c(std::string("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"));
39+
fq d(std::string("0x9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789"));
40+
41+
std::vector<fq> input{ a, b, c, d };
42+
auto result = crypto::Poseidon<crypto::PoseidonStark252BaseFieldParams>::hash(input);
43+
44+
fq expected(std::string("0x0494e3a5a8047943395f79e41f11ba73285be9aa930953fbad060c0649a7c79d"));
45+
46+
EXPECT_EQ(result, expected);
47+
}

0 commit comments

Comments
 (0)