Skip to content

Commit

Permalink
feat(avm): avm recursive TS/Noir integration (#8611)
Browse files Browse the repository at this point in the history
Reverts #8610

@jeanmon I have put an e2e-all label on this as it has broke master with
my changes, unfortunately, it seems we need to make sure we're not
importing jest mock outside of a dev setting

---------

Co-authored-by: jeanmon <[email protected]>
  • Loading branch information
ludamad and jeanmon authored Sep 18, 2024
1 parent 94718f1 commit e417231
Show file tree
Hide file tree
Showing 29 changed files with 478 additions and 125 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 @@ -16,8 +16,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 @@ -1020,15 +1022,19 @@ bool avm_verify(const std::filesystem::path& proof_path, const std::filesystem::
vinfo("circuit size: ", circuit_size, " (next or eq power: 2^", numeric::round_up_power_2(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
24 changes: 24 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,29 @@ 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>();

// After any circuit changes, hover `COMPUTED_AVM_PROOF_LENGTH_IN_FIELDS` in your IDE
// to see its value and then update `AVM_PROOF_LENGTH_IN_FIELDS` in constants.nr.
static constexpr size_t COMPUTED_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);

static_assert(AVM_PROOF_LENGTH_IN_FIELDS == COMPUTED_AVM_PROOF_LENGTH_IN_FIELDS,
"\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
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ template <typename FF_> class aluImpl {
[[maybe_unused]] const RelationParameters<FF>&,
[[maybe_unused]] const FF& scaling_factor)
{
const auto constants_MEM_TAG_U1 = FF(1);
const auto constants_MEM_TAG_U8 = FF(2);
const auto constants_MEM_TAG_U16 = FF(3);
const auto constants_MEM_TAG_U32 = FF(4);
Expand Down Expand Up @@ -123,12 +124,13 @@ template <typename FF_> class aluImpl {
{
using Accumulator = typename std::tuple_element_t<9, ContainerOverSubrelations>;
auto tmp =
(new_term.alu_in_tag - ((((((new_term.alu_u1_tag + (constants_MEM_TAG_U8 * new_term.alu_u8_tag)) +
(constants_MEM_TAG_U16 * new_term.alu_u16_tag)) +
(constants_MEM_TAG_U32 * new_term.alu_u32_tag)) +
(constants_MEM_TAG_U64 * new_term.alu_u64_tag)) +
(constants_MEM_TAG_U128 * new_term.alu_u128_tag)) +
(constants_MEM_TAG_FF * new_term.alu_ff_tag)));
(new_term.alu_in_tag -
(((((((constants_MEM_TAG_U1 * new_term.alu_u1_tag) + (constants_MEM_TAG_U8 * new_term.alu_u8_tag)) +
(constants_MEM_TAG_U16 * new_term.alu_u16_tag)) +
(constants_MEM_TAG_U32 * new_term.alu_u32_tag)) +
(constants_MEM_TAG_U64 * new_term.alu_u64_tag)) +
(constants_MEM_TAG_U128 * new_term.alu_u128_tag)) +
(constants_MEM_TAG_FF * new_term.alu_ff_tag)));
tmp *= scaling_factor;
std::get<9>(evals) += typename Accumulator::View(tmp);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ bool AvmVerifier::verify_proof(const HonkProof& proof,

// Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the
// unrolled protocol.

auto opening_claim = ZeroMorph::verify(circuit_size,
commitments.get_unshifted(),
commitments.get_to_be_shifted(),
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 3812
#define MEM_TAG_U1 1
#define MEM_TAG_U8 2
#define MEM_TAG_U16 3
Expand Down
24 changes: 24 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,29 @@ 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>();

// After any circuit changes, hover `COMPUTED_AVM_PROOF_LENGTH_IN_FIELDS` in your IDE
// to see its value and then update `AVM_PROOF_LENGTH_IN_FIELDS` in constants.nr.
static constexpr size_t COMPUTED_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);

static_assert(AVM_PROOF_LENGTH_IN_FIELDS == COMPUTED_AVM_PROOF_LENGTH_IN_FIELDS,
"\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
7 changes: 5 additions & 2 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ library Constants {
uint256 internal constant L2_GAS_PER_LOG_BYTE = 4;
uint256 internal constant L2_GAS_PER_NOTE_HASH = 32;
uint256 internal constant L2_GAS_PER_NULLIFIER = 64;
uint256 internal constant CANONICAL_KEY_REGISTRY_ADDRESS =
6823425185167517386380694778823032861295161686691976789058601691508103815523;
uint256 internal constant CANONICAL_AUTH_REGISTRY_ADDRESS =
19361441716519463065948254497947932755739298943049449145365332870925554042208;
uint256 internal constant DEPLOYER_CONTRACT_ADDRESS =
Expand Down Expand Up @@ -253,4 +251,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.
}
20 changes: 14 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 @@ -288,13 +288,13 @@ global NESTED_RECURSIVE_PROOF_LENGTH: u32 = 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;
// `AVM_PROOF_LENGTH_IN_FIELDS` must be updated when AVM circuit changes.
// To determine latest value, hover `COMPUTED_AVM_PROOF_LENGTH_IN_FIELDS`
// in barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp
global AVM_PROOF_LENGTH_IN_FIELDS = 3812;
/**
* 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 @@ -538,3 +538,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 e417231

Please sign in to comment.