Skip to content

Commit

Permalink
feat(avm): avm recursive TS/Noir integration (#8531)
Browse files Browse the repository at this point in the history
Resolves #7791
  • Loading branch information
jeanmon authored Sep 17, 2024
1 parent cd46ddd commit dd09f05
Show file tree
Hide file tree
Showing 27 changed files with 519 additions and 236 deletions.
18 changes: 12 additions & 6 deletions barretenberg/cpp/src/barretenberg/bb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@

#include <cstddef>
#ifndef DISABLE_AZTEC_VM
#include "barretenberg/vm/avm/generated/flavor.hpp"
#include "barretenberg/vm/avm/trace/common.hpp"
#include "barretenberg/vm/avm/trace/execution.hpp"
#include "barretenberg/vm/aztec_constants.hpp"
#include "barretenberg/vm/stats.hpp"
#endif
#include "config.hpp"
Expand Down Expand Up @@ -1019,15 +1021,19 @@ bool avm_verify(const std::filesystem::path& proof_path, const std::filesystem::
vinfo("circuit size: ", circuit_size);
vinfo("num of pub inputs: ", num_public_inputs);

// Each commitment (precomputed entity) is represented as 2 Fq field elements.
// Each Fq element is split into two limbs of Fr elements.
// We therefore need 2 (circuit_size, num_public_inputs) + 4 * NUM_PRECOMPUTED_ENTITIES fr elements.
ASSERT(vk_as_fields.size() == 4 * AvmFlavor::NUM_PRECOMPUTED_ENTITIES + 2);
if (vk_as_fields.size() != AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS) {
info("The supplied avm vk has incorrect size. Number of fields: ",
vk_as_fields.size(),
" but expected: ",
AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS);
return false;
}

std::array<Commitment, AvmFlavor::NUM_PRECOMPUTED_ENTITIES> precomputed_cmts;
for (size_t i = 0; i < AvmFlavor::NUM_PRECOMPUTED_ENTITIES; i++) {
// Start at offset 2 and adds 4 fr elements per commitment. Therefore, index = 4 * i + 2.
precomputed_cmts[i] = field_conversion::convert_from_bn254_frs<Commitment>(vk_span.subspan(4 * i + 2, 4));
// Start at offset 2 and adds 4 (NUM_FRS_COM) fr elements per commitment. Therefore, index = 4 * i + 2.
precomputed_cmts[i] = field_conversion::convert_from_bn254_frs<Commitment>(
vk_span.subspan(AvmFlavor::NUM_FRS_COM * i + 2, AvmFlavor::NUM_FRS_COM));
}

auto vk = AvmFlavor::VerificationKey(circuit_size, num_public_inputs, precomputed_cmts);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#ifndef DISABLE_AZTEC_VM

#include "avm_recursion_constraint.hpp"
#include "barretenberg/constants.hpp"
#include "barretenberg/flavor/flavor.hpp"
#include "barretenberg/stdlib/plonk_recursion/aggregation_state/aggregation_state.hpp"
#include "barretenberg/stdlib/primitives/curves/bn254.hpp"
#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp"
#include "barretenberg/vm/avm/recursion/avm_recursive_flavor.hpp"
#include "barretenberg/vm/avm/recursion/avm_recursive_verifier.hpp"
#include "barretenberg/vm/aztec_constants.hpp"
#include "proof_surgeon.hpp"
#include <cstddef>

Expand Down Expand Up @@ -38,21 +40,19 @@ void create_dummy_vkey_and_proof(Builder& builder,
{
using Flavor = AvmFlavor;

size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<Flavor::Commitment>();
size_t num_frs_fr = bb::field_conversion::calc_num_bn254_frs<Flavor::FF>();

// Relevant source for proof layout: AvmFlavor::Transcript::serialize_full_transcript()
assert((proof_size - Flavor::NUM_WITNESS_ENTITIES * num_frs_comm - Flavor::NUM_ALL_ENTITIES * num_frs_fr -
2 * num_frs_comm) %
(num_frs_comm + num_frs_fr * Flavor::BATCHED_RELATION_PARTIAL_LENGTH) ==
assert((proof_size - Flavor::NUM_WITNESS_ENTITIES * Flavor::NUM_FRS_COM -
Flavor::NUM_ALL_ENTITIES * Flavor::NUM_FRS_FR - 2 * Flavor::NUM_FRS_COM - Flavor::NUM_FRS_FR) %
(Flavor::NUM_FRS_COM + Flavor::NUM_FRS_FR * Flavor::BATCHED_RELATION_PARTIAL_LENGTH) ==
0);

// Derivation of circuit size based on the proof
// Here, we should always get CONST_PROOF_SIZE_LOG_N which is not what is
// usually set for the AVM proof. As it is a dummy key/proof, it should not matter.
auto log_circuit_size = (proof_size - Flavor::NUM_WITNESS_ENTITIES * num_frs_comm -
Flavor::NUM_ALL_ENTITIES * num_frs_fr - 2 * num_frs_comm) /
(num_frs_comm + num_frs_fr * Flavor::BATCHED_RELATION_PARTIAL_LENGTH);
auto log_circuit_size =
(proof_size - Flavor::NUM_WITNESS_ENTITIES * Flavor::NUM_FRS_COM -
Flavor::NUM_ALL_ENTITIES * Flavor::NUM_FRS_FR - 2 * Flavor::NUM_FRS_COM - Flavor::NUM_FRS_FR) /
(Flavor::NUM_FRS_COM + Flavor::NUM_FRS_FR * Flavor::BATCHED_RELATION_PARTIAL_LENGTH);

/***************************************************************************
* Construct Dummy Verification Key
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace acir_format {

// Used to specify the type of recursive verifier via the proof_type specified by the RecursiveAggregation opcode from
// ACIR
// Keep this enum values in sync with their noir counterpart constants defined in
// noir-protocol-circuits/crates/types/src/constants.nr
enum PROOF_TYPE { PLONK, HONK, OINK, PG, AVM };

using namespace bb::plonk;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ std::shared_ptr<Flavor::ProvingKey> AvmComposer::compute_proving_key(CircuitCons
}

// Initialize proving_key
const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size();
proving_key = std::make_shared<Flavor::ProvingKey>(subgroup_size, 0);
{
const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size();
proving_key = std::make_shared<Flavor::ProvingKey>(subgroup_size, 0);
}

return proving_key;
}
Expand Down
20 changes: 20 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "barretenberg/transcript/transcript.hpp"

#include "barretenberg/vm/avm/generated/flavor_settings.hpp"
#include "barretenberg/vm/aztec_constants.hpp"

// Relations
#include "barretenberg/vm/avm/generated/relations/alu.hpp"
Expand Down Expand Up @@ -223,6 +224,25 @@ class AvmFlavor {

static constexpr bool has_zero_row = true;

static constexpr size_t NUM_FRS_COM = field_conversion::calc_num_bn254_frs<Commitment>();
static constexpr size_t NUM_FRS_FR = field_conversion::calc_num_bn254_frs<FF>();

static_assert(AVM_PROOF_LENGTH_IN_FIELDS ==
(NUM_WITNESS_ENTITIES + 2) * NUM_FRS_COM + (NUM_ALL_ENTITIES + 1) * NUM_FRS_FR +
CONST_PROOF_SIZE_LOG_N * (NUM_FRS_COM + NUM_FRS_FR * BATCHED_RELATION_PARTIAL_LENGTH),
"\nUnexpected AVM proof length. This might be due to some changes in the\n"
"AVM circuit layout. In this case, modify AVM_PROOF_LENGTH_IN_FIELDS \n"
"in constants.nr accordingly.");

// VK is composed of
// - circuit size encoded as a fr field element
// - num of inputs encoded as a fr field element
// - NUM_PRECOMPUTED_ENTITIES commitments
static_assert(AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS == 2 * NUM_FRS_FR + NUM_PRECOMPUTED_ENTITIES * NUM_FRS_COM,
"\nUnexpected AVM VK length. This might be due to some changes in the\n"
"AVM circuit. In this case, modify AVM_VERIFICATION_LENGTH_IN_FIELDS \n"
"in constants.nr accordingly.");

template <typename DataType_> class PrecomputedEntities : public PrecomputedEntitiesBase {
public:
using DataType = DataType_;
Expand Down
1 change: 1 addition & 0 deletions barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#define PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH 691
#define PUBLIC_CONTEXT_INPUTS_LENGTH 42
#define AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS 66
#define AVM_PROOF_LENGTH_IN_FIELDS 3802
#define SENDER_SELECTOR 0
#define ADDRESS_SELECTOR 1
#define STORAGE_ADDRESS_SELECTOR 1
Expand Down
20 changes: 20 additions & 0 deletions bb-pilcom/bb-pil-backend/templates/flavor.hpp.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "barretenberg/flavor/flavor.hpp"

#include "barretenberg/vm/{{snakeCase name}}/generated/flavor_settings.hpp"
#include "barretenberg/vm/aztec_constants.hpp"

// Relations
{{#each relation_file_names as |r|}}
Expand Down Expand Up @@ -102,6 +103,25 @@ class {{name}}Flavor {

static constexpr bool has_zero_row = true;

static constexpr size_t NUM_FRS_COM = field_conversion::calc_num_bn254_frs<Commitment>();
static constexpr size_t NUM_FRS_FR = field_conversion::calc_num_bn254_frs<FF>();

static_assert(AVM_PROOF_LENGTH_IN_FIELDS ==
(NUM_WITNESS_ENTITIES + 2) * NUM_FRS_COM + (NUM_ALL_ENTITIES + 1) * NUM_FRS_FR +
CONST_PROOF_SIZE_LOG_N * (NUM_FRS_COM + NUM_FRS_FR * BATCHED_RELATION_PARTIAL_LENGTH),
"\nUnexpected AVM proof length. This might be due to some changes in the\n"
"AVM circuit layout. In this case, modify AVM_PROOF_LENGTH_IN_FIELDS \n"
"in constants.nr accordingly.");

// VK is composed of
// - circuit size encoded as a fr field element
// - num of inputs encoded as a fr field element
// - NUM_PRECOMPUTED_ENTITIES commitments
static_assert(AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS == 2 * NUM_FRS_FR + NUM_PRECOMPUTED_ENTITIES * NUM_FRS_COM,
"\nUnexpected AVM VK length. This might be due to some changes in the\n"
"AVM circuit. In this case, modify AVM_VERIFICATION_LENGTH_IN_FIELDS \n"
"in constants.nr accordingly.");

template <typename DataType_> class PrecomputedEntities : public PrecomputedEntitiesBase {
public:
using DataType = DataType_;
Expand Down
5 changes: 5 additions & 0 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -246,4 +246,9 @@ library Constants {
uint256 internal constant START_EMIT_NULLIFIER_WRITE_OFFSET = 144;
uint256 internal constant START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET = 160;
uint256 internal constant START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET = 162;
uint256 internal constant PROOF_TYPE_PLONK = 0;
uint256 internal constant PROOF_TYPE_HONK = 1;
uint256 internal constant PROOF_TYPE_OINK = 2;
uint256 internal constant PROOF_TYPE_PG = 3;
uint256 internal constant PROOF_TYPE_AVM = 4;
}
1 change: 1 addition & 0 deletions noir-projects/mock-protocol-circuits/Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ members = [
"crates/mock-private-kernel-inner",
"crates/mock-private-kernel-reset",
"crates/mock-private-kernel-tail",
"crates/mock-public-kernel",
]
4 changes: 4 additions & 0 deletions noir-projects/mock-protocol-circuits/Readme.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Mocked protocol circuits

These simplified circuits act as a way of testing the IVC integration between noir and barretenberg. They follow the same IVC scheme as the real circuits, but are much simpler and easier to reason about.

# Public Kernel

The folder public-kernel is currently used to test the noir integration of the avm recursive verifier.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "mock_public_kernel"
type = "bin"
authors = [""]
compiler_version = ">=0.32.0"

[dependencies]
types = { path = "../../../noir-protocol-circuits/crates/types" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use dep::types::constants::{AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS, AVM_PROOF_LENGTH_IN_FIELDS, PROOF_TYPE_AVM};

fn main(
verification_key: [Field; AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS],
proof: [Field; AVM_PROOF_LENGTH_IN_FIELDS]
) -> pub u8 {
std::verify_proof_with_type(verification_key, proof, [], 0, PROOF_TYPE_AVM);
1 // Dummy value to return for the mock kernel as void function creates some pain.
}
17 changes: 11 additions & 6 deletions noir-projects/noir-protocol-circuits/crates/types/src/constants.nr
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,10 @@ global NESTED_RECURSIVE_PROOF_LENGTH = 439;
global TUBE_PROOF_LENGTH = RECURSIVE_PROOF_LENGTH; // in the future these can differ

global VERIFICATION_KEY_LENGTH_IN_FIELDS = 128;
// VK is composed of
// - circuit size encoded as a fr field element (32 bytes)
// - num of inputs encoded as a fr field element (32 bytes)
// - 16 affine elements (curve base field fq) encoded as fr elements takes (16 * 4 * 32 bytes)
// 16 above refers to the constant AvmFlavor::NUM_PRECOMPUTED_ENTITIES
global AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 2 + 16 * 4;

// The length is 2 + AvmFlavor::NUM_PRECOMPUTED_ENTITIES * 4
global AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 2 + 16 * 4;
global AVM_PROOF_LENGTH_IN_FIELDS = 3802;
/**
* Enumerate the hash_indices which are used for pedersen hashing.
* We start from 1 to avoid the default generators. The generator indices are listed
Expand Down Expand Up @@ -530,3 +527,11 @@ global AVM_PEDERSENCOMMITMENT_DYN_L2_GAS: u16 = 0;
global AVM_TORADIXLE_DYN_L2_GAS: u16 = 200;
global AVM_SHA256COMPRESSION_DYN_L2_GAS: u16 = 0;
global AVM_KECCAKF1600_DYN_L2_GAS: u16 = 0;

// Constants related to proof type of a recursive proof verification.
// Keep following constants in sync with the enum acir_format::PROOF_TYPE in recursion_constraint.hpp
global PROOF_TYPE_PLONK : u32 = 0;
global PROOF_TYPE_HONK : u32 = 1;
global PROOF_TYPE_OINK : u32 = 2;
global PROOF_TYPE_PG : u32 = 3;
global PROOF_TYPE_AVM : u32 = 4;
2 changes: 1 addition & 1 deletion yarn-project/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ rollup-verifier-contract:

txe:
FROM +cli-base
RUN yarn workspaces focus @aztec/txe --production && yarn cache clean
RUN yarn workspaces focus @aztec/txe && yarn cache clean
ENTRYPOINT ["node", "--no-warnings", "/usr/src/yarn-project/txe/dest/bin/index.js"]
SAVE ARTIFACT /usr/src /usr/src

Expand Down
1 change: 1 addition & 0 deletions yarn-project/bb-prover/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
},
"devDependencies": {
"@aztec/ethereum": "workspace:^",
"@aztec/types": "workspace:^",
"@jest/globals": "^29.5.0",
"@types/jest": "^29.5.0",
"@types/memdown": "^3.0.0",
Expand Down
Loading

0 comments on commit dd09f05

Please sign in to comment.