-
Notifications
You must be signed in to change notification settings - Fork 599
feat(avm): class id derivation #12263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| include "constants_gen.pil"; | ||
| include "poseidon2_hash.pil"; | ||
| include "precomputed.pil"; | ||
| include "bc_retrieval.pil"; | ||
|
|
||
| namespace class_id_derivation; | ||
|
|
||
| pol commit sel; | ||
| sel * (1 - sel) = 0; | ||
|
|
||
| #[skippable_if] | ||
| sel = 0; | ||
|
|
||
| // Members of Contract Class Id, looked up with bc_retrieval | ||
| pol commit artifact_hash; | ||
| pol commit private_function_root; | ||
| pol commit public_bytecode_commitment; // This is constrained via bc_retrieval's lookup to bc_hashing | ||
| // The result of | ||
| // H(GENERATOR_INDEX__CONTRACT_LEAF, artifact_hash, private_function_root, public_bytecode_commitment) | ||
| pol commit class_id; | ||
|
|
||
| // TODO: We need this temporarily while we dont allow for aliases in the lookup tuple, there must be a better way | ||
| pol commit temp_constant_for_lookup; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a todo comment about the constants? |
||
| sel * (temp_constant_for_lookup - constants.GENERATOR_INDEX__CONTRACT_LEAF) = 0; | ||
| // Since the inputs to poseidon2 have to be chunks of 3, we need two lookups if we want to do this in a single row | ||
| #[CLASS_ID_POSEIDON2_0] | ||
| sel { temp_constant_for_lookup, artifact_hash, private_function_root, class_id } | ||
| in poseidon2_hash.start { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output }; | ||
|
|
||
| #[CLASS_ID_POSEIDON2_1] | ||
| sel { public_bytecode_commitment, precomputed.zero, precomputed.zero, class_id} | ||
| in poseidon2_hash.end { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output }; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -67,21 +67,20 @@ namespace poseidon2_hash; | |
| // The permutation output values are represented by b_0, b_1, b_2, b_3 | ||
| // This most definitely could be simplified to a lower degree check | ||
| // The next perm input is constrained to be the previous perm output + the new values to be hashed if we | ||
| // are not at the start or the end of hashing | ||
| pol NEXT_INPUT_IS_PREV_OUTPUT_SEL = (1 - LATCH_CONDITION) * (1 - start); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was a bug 😨 . It was too relaxed, it's changed to only be the |
||
| // are not at the end of hashing | ||
| pol commit a_0; | ||
| pol commit a_1; | ||
| pol commit a_2; | ||
| pol commit a_3; | ||
|
|
||
| sel * start * (a_0 - input_0) = 0; | ||
| sel * NEXT_INPUT_IS_PREV_OUTPUT_SEL * (a_0' - b_0 - input_0') = 0; | ||
| sel * (1 - LATCH_CONDITION) * (a_0' - b_0 - input_0') = 0; | ||
| sel * start * (a_1 - input_1) = 0; | ||
| sel * NEXT_INPUT_IS_PREV_OUTPUT_SEL * (a_1' - b_1 - input_1') = 0; | ||
| sel * (1 - LATCH_CONDITION) * (a_1' - b_1 - input_1') = 0; | ||
| sel * start * (a_2 - input_2) = 0; | ||
| sel * NEXT_INPUT_IS_PREV_OUTPUT_SEL * (a_2' - b_2 - input_2') = 0; | ||
| sel * (1 - LATCH_CONDITION) * (a_2' - b_2 - input_2') = 0; | ||
| sel * start * (a_3 - IV) = 0; // IV is placed in the last slot if this is the start | ||
| sel * NEXT_INPUT_IS_PREV_OUTPUT_SEL * (a_3' - b_3) = 0; | ||
| sel * (1 - LATCH_CONDITION) * (a_3' - b_3) = 0; | ||
|
|
||
| // The Hash output value represented by b_0 | ||
| pol commit b_0; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| #include <gmock/gmock.h> | ||
| #include <gtest/gtest.h> | ||
|
|
||
| #include "barretenberg/vm2/constraining/testing/check_relation.hpp" | ||
| #include "barretenberg/vm2/generated/columns.hpp" | ||
| #include "barretenberg/vm2/generated/flavor_settings.hpp" | ||
| #include "barretenberg/vm2/generated/relations/class_id_derivation.hpp" | ||
| #include "barretenberg/vm2/generated/relations/lookups_bc_retrieval.hpp" | ||
| #include "barretenberg/vm2/generated/relations/lookups_class_id_derivation.hpp" | ||
| #include "barretenberg/vm2/simulation/class_id_derivation.hpp" | ||
| #include "barretenberg/vm2/simulation/events/event_emitter.hpp" | ||
| #include "barretenberg/vm2/simulation/lib/contract_crypto.hpp" | ||
| #include "barretenberg/vm2/testing/fixtures.hpp" | ||
| #include "barretenberg/vm2/tracegen/bytecode_trace.hpp" | ||
| #include "barretenberg/vm2/tracegen/class_id_derivation_trace.hpp" | ||
| #include "barretenberg/vm2/tracegen/lib/lookup_builder.hpp" | ||
| #include "barretenberg/vm2/tracegen/poseidon2_trace.hpp" | ||
| #include "barretenberg/vm2/tracegen/test_trace_container.hpp" | ||
|
|
||
| namespace bb::avm2::constraining { | ||
| namespace { | ||
|
|
||
| using tracegen::BytecodeTraceBuilder; | ||
| using tracegen::ClassIdDerivationTraceBuilder; | ||
| using tracegen::LookupIntoDynamicTableSequential; | ||
| using tracegen::Poseidon2TraceBuilder; | ||
| using tracegen::TestTraceContainer; | ||
|
|
||
| using simulation::ClassIdDerivation; | ||
| using simulation::ClassIdDerivationEvent; | ||
| using simulation::compute_contract_class_id; | ||
| using simulation::EventEmitter; | ||
| using simulation::NoopEventEmitter; | ||
| using simulation::Poseidon2; | ||
| using simulation::Poseidon2HashEvent; | ||
| using simulation::Poseidon2PermutationEvent; | ||
|
|
||
| using FF = AvmFlavorSettings::FF; | ||
| using C = Column; | ||
| using class_id_derivation_relation = bb::avm2::class_id_derivation<FF>; | ||
| using poseidon2_relation = bb::avm2::poseidon2_hash<FF>; | ||
|
|
||
| using lookup_poseidon2_hash_0 = bb::avm2::lookup_class_id_derivation_class_id_poseidon2_0_relation<FF>; | ||
| using lookup_poseidon2_hash_1 = bb::avm2::lookup_class_id_derivation_class_id_poseidon2_1_relation<FF>; | ||
| using lookup_bc_retrieval = bb::avm2::lookup_bc_retrieval_class_id_derivation_relation<FF>; | ||
|
|
||
| ContractClass generate_contract_class() | ||
| { | ||
| return ContractClass{ .artifact_hash = FF::random_element(), | ||
| .private_function_root = FF::random_element(), | ||
| .public_bytecode_commitment = FF::random_element(), | ||
| .packed_bytecode = {} }; | ||
| } | ||
|
|
||
| TEST(ClassIdDerivationConstrainingTest, EmptyRow) | ||
| { | ||
| TestTraceContainer trace({ | ||
| { { C::precomputed_first_row, 1 } }, | ||
| { { C::precomputed_clk, 0 } }, | ||
| }); | ||
|
|
||
| check_relation<class_id_derivation_relation>(trace); | ||
| } | ||
|
|
||
| TEST(ClassIdDerivationConstrainingTest, Basic) | ||
| { | ||
| TestTraceContainer trace; | ||
| ClassIdDerivationTraceBuilder builder; | ||
|
|
||
| auto klass = generate_contract_class(); | ||
|
|
||
| FF class_id = | ||
| compute_contract_class_id(klass.artifact_hash, klass.private_function_root, klass.public_bytecode_commitment); | ||
|
|
||
| builder.process({ { .class_id = class_id, .klass = klass } }, trace); | ||
|
|
||
| check_relation<class_id_derivation_relation>(trace); | ||
| } | ||
|
|
||
| TEST(ClassIdDerivationConstrainingTest, WithHashInteraction) | ||
| { | ||
| EventEmitter<Poseidon2HashEvent> hash_event_emitter; | ||
| EventEmitter<Poseidon2PermutationEvent> perm_event_emitter; | ||
| Poseidon2 poseidon2(hash_event_emitter, perm_event_emitter); | ||
|
|
||
| EventEmitter<ClassIdDerivationEvent> event_emitter; | ||
| ClassIdDerivation class_id_derivation(poseidon2, event_emitter); | ||
|
|
||
| auto klass = generate_contract_class(); | ||
| FF class_id = | ||
| compute_contract_class_id(klass.artifact_hash, klass.private_function_root, klass.public_bytecode_commitment); | ||
|
|
||
| TestTraceContainer trace({ | ||
| { { C::precomputed_first_row, 1 } }, | ||
| }); | ||
|
|
||
| ClassIdDerivationTraceBuilder builder; | ||
| Poseidon2TraceBuilder poseidon2_builder; | ||
|
|
||
| class_id_derivation.assert_derivation(class_id, klass); | ||
|
|
||
| poseidon2_builder.process_hash(hash_event_emitter.dump_events(), trace); | ||
| builder.process({ { .class_id = class_id, .klass = klass } }, trace); | ||
|
|
||
| LookupIntoDynamicTableSequential<lookup_poseidon2_hash_0::Settings>().process(trace); | ||
| LookupIntoDynamicTableSequential<lookup_poseidon2_hash_1::Settings>().process(trace); | ||
|
|
||
| check_interaction<lookup_poseidon2_hash_0>(trace); | ||
| check_interaction<lookup_poseidon2_hash_1>(trace); | ||
| } | ||
|
|
||
| // TODO: This should probably be refined and moved to bc_retrieval test file once that exists | ||
| TEST(ClassIdDerivationConstrainingTest, WithRetrievalInteraction) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When bc_retrieval is being properly done, we should move the test to there |
||
| { | ||
| NoopEventEmitter<Poseidon2HashEvent> hash_event_emitter; | ||
| NoopEventEmitter<Poseidon2PermutationEvent> perm_event_emitter; | ||
| Poseidon2 poseidon2(hash_event_emitter, perm_event_emitter); | ||
|
|
||
| EventEmitter<ClassIdDerivationEvent> event_emitter; | ||
| ClassIdDerivation class_id_derivation(poseidon2, event_emitter); | ||
|
|
||
| auto klass = generate_contract_class(); | ||
| FF class_id = | ||
| compute_contract_class_id(klass.artifact_hash, klass.private_function_root, klass.public_bytecode_commitment); | ||
|
|
||
| TestTraceContainer trace({ | ||
| { { C::precomputed_first_row, 1 } }, | ||
| }); | ||
|
|
||
| ClassIdDerivationTraceBuilder builder; | ||
| BytecodeTraceBuilder bc_trace_builder; | ||
|
|
||
| class_id_derivation.assert_derivation(class_id, klass); | ||
| builder.process({ { .class_id = class_id, .klass = klass } }, trace); | ||
|
|
||
| ContractInstance instance = {}; | ||
| instance.contract_class_id = class_id; | ||
| bc_trace_builder.process_retrieval({ { .bytecode_id = 0, | ||
| .address = 1, | ||
| .siloed_address = 2, | ||
| .contract_instance = instance, | ||
| .contract_class = klass, | ||
| .nullifier_root = 3 } }, | ||
| trace); | ||
|
|
||
| LookupIntoDynamicTableSequential<lookup_bc_retrieval::Settings>().process(trace); | ||
| check_interaction<lookup_bc_retrieval>(trace); | ||
| } | ||
|
|
||
| } // namespace | ||
| } // namespace bb::avm2::constraining | ||
Large diffs are not rendered by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not used but part of constants gen right now