This commit is contained in:
Robin Salen 2023-08-19 10:46:01 -04:00
parent 9a4500683b
commit 8476fdcd93
No known key found for this signature in database
GPG Key ID: CF63FCA518B44159
2 changed files with 140 additions and 176 deletions

View File

@ -30,7 +30,6 @@ use crate::all_stark::{all_cross_table_lookups, AllStark, Table, NUM_TABLES};
use crate::arithmetic::arithmetic_stark::ArithmeticStark;
use crate::config::StarkConfig;
use crate::cpu::cpu_stark::CpuStark;
use crate::cpu::kernel::constants::global_metadata::GlobalMetadata;
use crate::cross_table_lookup::{verify_cross_table_lookups_circuit, CrossTableLookup};
use crate::generation::GenerationInputs;
use crate::get_challenges::observe_public_values_target;
@ -38,19 +37,16 @@ use crate::keccak::keccak_stark::KeccakStark;
use crate::keccak_sponge::keccak_sponge_stark::KeccakSpongeStark;
use crate::logic::LogicStark;
use crate::memory::memory_stark::MemoryStark;
use crate::memory::segments::Segment;
use crate::memory::VALUE_LIMBS;
use crate::permutation::{
get_grand_product_challenge_set_target, GrandProductChallenge, GrandProductChallengeSet,
};
use crate::permutation::{get_grand_product_challenge_set_target, GrandProductChallengeSet};
use crate::proof::{
BlockMetadataTarget, PublicValues, PublicValuesTarget, StarkProofWithMetadata, TrieRootsTarget,
};
use crate::prover::prove;
use crate::recursive_verifier::{
add_common_recursion_gates, add_virtual_public_values, recursive_stark_circuit,
set_block_metadata_target, set_public_value_targets, set_trie_roots_target,
PlonkWrapperCircuit, PublicInputs, StarkWrapperCircuit,
add_common_recursion_gates, add_virtual_public_values,
get_memory_extra_looking_products_circuit, recursive_stark_circuit, set_block_metadata_target,
set_public_value_targets, set_trie_roots_target, PlonkWrapperCircuit, PublicInputs,
StarkWrapperCircuit,
};
use crate::stark::Stark;
@ -498,7 +494,7 @@ where
// Memory
let memory_looking_products = (0..stark_config.num_challenges)
.map(|c| {
Self::get_memory_extra_looking_products_circuit(
get_memory_extra_looking_products_circuit(
&mut builder,
&public_values,
ctl_challenges.challenges[c],
@ -561,172 +557,6 @@ where
}
}
/// Recursive version of `get_memory_extra_looking_products`.
pub(crate) fn get_memory_extra_looking_products_circuit(
builder: &mut CircuitBuilder<F, D>,
public_values: &PublicValuesTarget,
challenge: GrandProductChallenge<Target>,
) -> Target {
let mut prod = builder.constant(F::ONE);
// Add metadata writes.
let block_fields_without_beneficiary_and_basefee = [
(
GlobalMetadata::BlockTimestamp,
public_values.block_metadata.block_timestamp,
),
(
GlobalMetadata::BlockNumber,
public_values.block_metadata.block_number,
),
(
GlobalMetadata::BlockDifficulty,
public_values.block_metadata.block_difficulty,
),
(
GlobalMetadata::BlockGasLimit,
public_values.block_metadata.block_gaslimit,
),
(
GlobalMetadata::BlockChainId,
public_values.block_metadata.block_chain_id,
),
];
let zero = builder.constant(F::ZERO);
let one = builder.constant(F::ONE);
let segment = builder.constant(F::from_canonical_u32(Segment::GlobalMetadata as u32));
// Include the block beneficiary.
let row = builder.add_virtual_targets(13);
// is_read
builder.connect(row[0], zero);
// context
builder.connect(row[1], zero);
// segment
builder.connect(row[2], segment);
// virtual
let field_target = builder.constant(F::from_canonical_usize(
GlobalMetadata::BlockBeneficiary as usize,
));
builder.connect(row[3], field_target);
// values
for j in 0..5 {
builder.connect(
row[4 + j],
public_values.block_metadata.block_beneficiary[j],
);
}
for j in 5..VALUE_LIMBS {
builder.connect(row[4 + j], zero);
}
// timestamp
builder.connect(row[12], one);
let combined = challenge.combine_base_circuit(builder, &row);
prod = builder.mul(prod, combined);
block_fields_without_beneficiary_and_basefee.map(|(field, target)| {
let row = builder.add_virtual_targets(13);
// is_read
builder.connect(row[0], zero);
// context
builder.connect(row[1], zero);
// segment
builder.connect(row[2], segment);
// virtual
let field_target = builder.constant(F::from_canonical_usize(field as usize));
builder.connect(row[3], field_target);
// These values only have one cell.
builder.connect(row[4], target);
for j in 1..VALUE_LIMBS {
builder.connect(row[4 + j], zero);
}
// timestamp
builder.connect(row[12], one);
let combined = challenge.combine_base_circuit(builder, &row);
prod = builder.mul(prod, combined);
});
// Include the block base fee.
let row = builder.add_virtual_targets(13);
// is_read
builder.connect(row[0], zero);
// context
builder.connect(row[1], zero);
// segment
builder.connect(row[2], segment);
// virtual
let field_target = builder.constant(F::from_canonical_usize(
GlobalMetadata::BlockBaseFee as usize,
));
builder.connect(row[3], field_target);
// values
for j in 0..2 {
builder.connect(row[4 + j], public_values.block_metadata.block_base_fee[j]);
}
for j in 2..VALUE_LIMBS {
builder.connect(row[4 + j], zero);
}
// timestamp
builder.connect(row[12], one);
let combined = challenge.combine_base_circuit(builder, &row);
prod = builder.mul(prod, combined);
// Add trie roots writes.
let trie_fields = [
(
GlobalMetadata::StateTrieRootDigestBefore,
public_values.trie_roots_before.state_root,
),
(
GlobalMetadata::TransactionTrieRootDigestBefore,
public_values.trie_roots_before.transactions_root,
),
(
GlobalMetadata::ReceiptTrieRootDigestBefore,
public_values.trie_roots_before.receipts_root,
),
(
GlobalMetadata::StateTrieRootDigestAfter,
public_values.trie_roots_after.state_root,
),
(
GlobalMetadata::TransactionTrieRootDigestAfter,
public_values.trie_roots_after.transactions_root,
),
(
GlobalMetadata::ReceiptTrieRootDigestAfter,
public_values.trie_roots_after.receipts_root,
),
];
trie_fields.map(|(field, targets)| {
let row = builder.add_virtual_targets(13);
// is_read
builder.connect(row[0], zero);
// context
builder.connect(row[1], zero);
// segment
builder.connect(row[2], segment);
// virtual
let field_target = builder.constant(F::from_canonical_usize(field as usize));
builder.connect(row[3], field_target);
// values
for j in 0..VALUE_LIMBS {
builder.connect(row[4 + j], targets[j]);
}
// timestamp
builder.connect(row[12], one);
let combined = challenge.combine_base_circuit(builder, &row);
prod = builder.mul(prod, combined);
});
prod
}
fn create_aggregation_circuit(
root: &RootCircuitData<F, C, D>,
) -> AggregationCircuitData<F, C, D> {

View File

@ -28,7 +28,10 @@ use plonky2_util::log2_ceil;
use crate::all_stark::{Table, NUM_TABLES};
use crate::config::StarkConfig;
use crate::constraint_consumer::RecursiveConstraintConsumer;
use crate::cpu::kernel::constants::global_metadata::GlobalMetadata;
use crate::cross_table_lookup::{verify_cross_table_lookups, CrossTableLookup, CtlCheckVarsTarget};
use crate::memory::segments::Segment;
use crate::memory::VALUE_LIMBS;
use crate::permutation::{
get_grand_product_challenge_set, GrandProductChallenge, GrandProductChallengeSet,
PermutationCheckDataTarget,
@ -494,6 +497,137 @@ fn verify_stark_proof_with_challenges_circuit<
);
}
/// Recursive version of `get_memory_extra_looking_products`.
pub(crate) fn get_memory_extra_looking_products_circuit<
F: RichField + Extendable<D>,
const D: usize,
>(
builder: &mut CircuitBuilder<F, D>,
public_values: &PublicValuesTarget,
challenge: GrandProductChallenge<Target>,
) -> Target {
let mut product = builder.one();
// Add metadata writes.
let block_fields_without_beneficiary_and_basefee = [
(
GlobalMetadata::BlockTimestamp as usize,
public_values.block_metadata.block_timestamp,
),
(
GlobalMetadata::BlockNumber as usize,
public_values.block_metadata.block_number,
),
(
GlobalMetadata::BlockDifficulty as usize,
public_values.block_metadata.block_difficulty,
),
(
GlobalMetadata::BlockGasLimit as usize,
public_values.block_metadata.block_gaslimit,
),
(
GlobalMetadata::BlockChainId as usize,
public_values.block_metadata.block_chain_id,
),
];
product = add_metadata_write(
builder,
challenge,
product,
GlobalMetadata::BlockBeneficiary as usize,
&public_values.block_metadata.block_beneficiary,
);
block_fields_without_beneficiary_and_basefee.map(|(field, target)| {
// Each of those fields fit in 32 bits, hence in a single Target.
product = add_metadata_write(builder, challenge, product, field, &[target]);
});
product = add_metadata_write(
builder,
challenge,
product,
GlobalMetadata::BlockBaseFee as usize,
&public_values.block_metadata.block_base_fee,
);
// Add trie roots writes.
let trie_fields = [
(
GlobalMetadata::StateTrieRootDigestBefore as usize,
public_values.trie_roots_before.state_root,
),
(
GlobalMetadata::TransactionTrieRootDigestBefore as usize,
public_values.trie_roots_before.transactions_root,
),
(
GlobalMetadata::ReceiptTrieRootDigestBefore as usize,
public_values.trie_roots_before.receipts_root,
),
(
GlobalMetadata::StateTrieRootDigestAfter as usize,
public_values.trie_roots_after.state_root,
),
(
GlobalMetadata::TransactionTrieRootDigestAfter as usize,
public_values.trie_roots_after.transactions_root,
),
(
GlobalMetadata::ReceiptTrieRootDigestAfter as usize,
public_values.trie_roots_after.receipts_root,
),
];
trie_fields.map(|(field, targets)| {
product = add_metadata_write(builder, challenge, product, field, &targets);
});
product
}
fn add_metadata_write<F: RichField + Extendable<D>, const D: usize>(
builder: &mut CircuitBuilder<F, D>,
challenge: GrandProductChallenge<Target>,
running_product: Target,
metadata_idx: usize,
metadata: &[Target],
) -> Target {
debug_assert!(metadata.len() <= VALUE_LIMBS);
let len = core::cmp::min(metadata.len(), VALUE_LIMBS);
let zero = builder.zero();
let one = builder.one();
let segment = builder.constant(F::from_canonical_u32(Segment::GlobalMetadata as u32));
let row = builder.add_virtual_targets(13);
// is_read
builder.connect(row[0], zero);
// context
builder.connect(row[1], zero);
// segment
builder.connect(row[2], segment);
// virtual
let field_target = builder.constant(F::from_canonical_usize(metadata_idx));
builder.connect(row[3], field_target);
// values
for j in 0..len {
builder.connect(row[4 + j], metadata[j]);
}
for j in len..VALUE_LIMBS {
builder.connect(row[4 + j], zero);
}
// timestamp
builder.connect(row[12], one);
let combined = challenge.combine_base_circuit(builder, &row);
builder.mul(running_product, combined)
}
fn eval_l_0_and_l_last_circuit<F: RichField + Extendable<D>, const D: usize>(
builder: &mut CircuitBuilder<F, D>,
log_n: usize,