Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ keywords = ["blockchain", "zksync", "zk", "risc-v"]
categories = ["cryptography"]

[workspace.dependencies]
zksync_os_evm_errors = { version = "0.0.10", default-features = false }
zksync_os_interface = { version = "0.0.10"}
zksync_os_evm_errors = { git = "https://github.com/matter-labs/zksync-os-interface", branch = "alocascio-prover-input-gen", default-features = false }
zksync_os_interface = { git = "https://github.com/matter-labs/zksync-os-interface", branch = "alocascio-prover-input-gen", version = "0.0.10"}

risc_v_simulator = { git = "https://github.com/matter-labs/zksync-airbender", tag = "v0.4.3"}
blake2s_u32 = { git = "https://github.com/matter-labs/zksync-airbender", tag = "v0.4.3"}
Expand Down
53 changes: 2 additions & 51 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,54 +1,5 @@
#![feature(allocator_api)]

use std::{path::PathBuf, str::FromStr};

use forward_system::run::{
test_impl::{InMemoryPreimageSource, InMemoryTree},
BlockContext, StorageCommitment,
};
use oracle_provider::ReadWitnessSource;
use zksync_os_interface::traits::TxListSource;
pub mod helpers;

/// Runs the batch, and returns the output (that contains gas usage, transaction status etc.).
pub use forward_system::run::run_block;
use zk_ee::common_structs::da_commitment_scheme::DACommitmentScheme;
use zk_ee::common_structs::ProofData;

/// Runs a block in RISC-V - using zksync_os binary - and returns the
/// witness that can be passed to the prover subsystem.
pub fn run_block_generate_witness(
block_context: BlockContext,
tree: InMemoryTree,
preimage_source: InMemoryPreimageSource,
tx_source: TxListSource,
proof_data: ProofData<StorageCommitment>,
da_commitment_scheme: DACommitmentScheme,
zksync_os_bin_path: &str,
) -> Vec<u32> {
use forward_system::run::*;

let oracle = make_oracle_for_proofs_and_dumps_for_init_data(
block_context,
tree,
preimage_source,
tx_source,
Some(proof_data),
Some(da_commitment_scheme),
false,
);

// We'll wrap the source, to collect all the reads.
let copy_source = ReadWitnessSource::new(oracle);

let items = copy_source.get_read_items();
// By default - enable diagnostics is false (which makes the test run faster).
let path = PathBuf::from_str(zksync_os_bin_path).unwrap();
let output = zksync_os_runner::run(path, None, 1 << 36, copy_source);

// We return 0s in case of failure.
assert_ne!(output, [0u32; 8]);

let result = items.borrow().clone();
result
}
pub use forward_system::run::{generate_proof_input, run_block};
pub mod helpers;
13 changes: 10 additions & 3 deletions basic_bootloader/src/bootloader/gas_helpers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use constants::{CALLDATA_NON_ZERO_BYTE_GAS_COST, CALLDATA_ZERO_BYTE_GAS_COST};
use evm_interpreter::native_resource_constants::COPY_BYTE_NATIVE_COST;
use evm_interpreter::ERGS_PER_GAS;
use metadata::basic_metadata::ZkSpecificPricingMetadata;
use zk_ee::internal_error;
use zk_ee::system::errors::internal::InternalError;
use zk_ee::system::{Computational, Resources};
Expand Down Expand Up @@ -156,9 +157,12 @@ pub fn get_resources_to_charge_for_pubdata<S: EthereumLikeTypes>(
system: &mut System<S>,
native_per_pubdata: U256,
base_pubdata: Option<u64>,
) -> Result<(u64, S::Resources), InternalError> {
) -> Result<(u64, S::Resources), InternalError>
where
S::Metadata: ZkSpecificPricingMetadata,
{
let current_pubdata_spent = system
.net_pubdata_used()?
.net_pubdata_used(system.repeated_write_index_encoding_length())?
.saturating_sub(base_pubdata.unwrap_or(0));
let native_per_pubdata = u256_to_u64_saturated(&native_per_pubdata);
let native = current_pubdata_spent
Expand All @@ -181,7 +185,10 @@ pub fn check_enough_resources_for_pubdata<S: EthereumLikeTypes>(
native_per_pubdata: U256,
resources: &S::Resources,
base_pubdata: Option<u64>,
) -> Result<(bool, S::Resources, u64), InternalError> {
) -> Result<(bool, S::Resources, u64), InternalError>
where
S::Metadata: ZkSpecificPricingMetadata,
{
let (pubdata_used, resources_for_pubdata) =
get_resources_to_charge_for_pubdata(system, native_per_pubdata, base_pubdata)?;
let _ = system.get_logger().write_fmt(format_args!(
Expand Down
10 changes: 6 additions & 4 deletions basic_system/src/system_functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ fn bytereverse(input: &mut [u8]) {
/// No std system functions implementations.
/// All of them are following EVM specs(for precompiles and keccak opcode).
///
pub struct NoStdSystemFunctions;
pub struct NoStdSystemFunctions<const USE_ADVICE: bool>;

impl<R: Resources> SystemFunctions<R> for NoStdSystemFunctions {
impl<R: Resources, const USE_ADVICE: bool> SystemFunctions<R> for NoStdSystemFunctions<USE_ADVICE> {
type Keccak256 = keccak256::Keccak256Impl;
type Sha256 = sha256::Sha256Impl;
type Secp256k1ECRecover = ecrecover::EcRecoverImpl;
Expand All @@ -47,6 +47,8 @@ impl<R: Resources> SystemFunctions<R> for NoStdSystemFunctions {
type PointEvaluation = point_evaluation::PointEvaluationImpl;
}

impl<R: Resources> SystemFunctionsExt<R> for NoStdSystemFunctions {
type ModExp = modexp::ModExpImpl;
impl<R: Resources, const USE_ADVICE: bool> SystemFunctionsExt<R>
for NoStdSystemFunctions<USE_ADVICE>
{
type ModExp = modexp::ModExpImpl<USE_ADVICE>;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Representation of big integers using primitives that are friendly for our delegations
extern crate alloc;

#[cfg(any(all(target_arch = "riscv32", feature = "proving"), test))]
use super::super::{ModExpAdviceParams, MODEXP_ADVICE_QUERY_ID};
use super::super::MODEXP_ADVICE_QUERY_ID;
use super::u256::*;
use crate::system_functions::modexp::ModExpAdviceParams64;

Check warning on line 6 in basic_system/src/system_functions/modexp/advice/bigint.rs

View workflow job for this annotation

GitHub Actions / Verify binary

unused import: `crate::system_functions::modexp::ModExpAdviceParams64`

Check warning on line 6 in basic_system/src/system_functions/modexp/advice/bigint.rs

View workflow job for this annotation

GitHub Actions / tests

unused import: `crate::system_functions::modexp::ModExpAdviceParams64`

Check warning on line 6 in basic_system/src/system_functions/modexp/advice/bigint.rs

View workflow job for this annotation

GitHub Actions / Run benchmarks

unused import: `crate::system_functions::modexp::ModExpAdviceParams64`

Check warning on line 6 in basic_system/src/system_functions/modexp/advice/bigint.rs

View workflow job for this annotation

GitHub Actions / e2e_prove

unused import: `crate::system_functions::modexp::ModExpAdviceParams64`

Check warning on line 6 in basic_system/src/system_functions/modexp/advice/bigint.rs

View workflow job for this annotation

GitHub Actions / Run fuzzer regressions

unused import: `crate::system_functions::modexp::ModExpAdviceParams64`

Check warning on line 6 in basic_system/src/system_functions/modexp/advice/bigint.rs

View workflow job for this annotation

GitHub Actions / Run fuzzer regressions

unused import: `crate::system_functions::modexp::ModExpAdviceParams64`
use alloc::vec::Vec;
use core::alloc::Allocator;
use core::fmt::Debug;
use core::mem::MaybeUninit;
use crypto::{bigint_op_delegation_raw, bigint_op_delegation_with_carry_bit_raw, BigIntOps};
#[cfg(any(all(target_arch = "riscv32", feature = "proving"), test))]
use ruint::aliases::U256;
use zk_ee::oracle::IOOracle;

// There is a small choice to make - either we do exponentiation walking as via LE or BE exponent.
Expand Down Expand Up @@ -812,32 +812,32 @@
}
}

#[cfg(any(all(target_arch = "riscv32", feature = "proving"), test))]
pub(crate) struct OracleAdvisor<'a, O: IOOracle> {
pub(crate) inner: &'a mut O,
}

#[cfg(any(all(target_arch = "riscv32", feature = "proving"), test))]
fn write_bigint(
it: &mut impl ExactSizeIterator<Item = usize>,
mut to_consume: usize,
dst: &mut BigintRepr<impl Allocator + Clone>,
) {
const {
assert!(core::mem::size_of::<usize>() == core::mem::size_of::<u32>());
}
// NOTE: even if oracle overstates the number of digits (so - iterator length), it is not important
// as long as caller checks that number of digits is within bounds of soundness
unsafe {
let num_digits = to_consume.next_multiple_of(8) / 8;
const BIGINT_DIGIT_USIZE_SIZE: usize = U256::BYTES / core::mem::size_of::<usize>();
let num_digits =
to_consume.next_multiple_of(BIGINT_DIGIT_USIZE_SIZE) / BIGINT_DIGIT_USIZE_SIZE;
let dst_capacity = dst.clear_as_capacity_mut();
for dst in dst_capacity[..num_digits].iter_mut() {
let dst: *mut u32 = dst.as_mut_ptr().cast::<[u32; 8]>().cast();
for i in 0..8 {
let dst: *mut usize = dst
.as_mut_ptr()
.cast::<[usize; BIGINT_DIGIT_USIZE_SIZE]>()
.cast();
for i in 0..BIGINT_DIGIT_USIZE_SIZE {
if to_consume > 0 {
to_consume -= 1;
let digit = it.next().unwrap();
dst.add(i).write(digit as u32);
dst.add(i).write(digit);
} else {
dst.add(i).write(0);
}
Expand All @@ -848,7 +848,6 @@
}
}

#[cfg(any(all(target_arch = "riscv32", feature = "proving"), test))]
impl<'a, O: IOOracle> ModexpAdvisor for OracleAdvisor<'a, O> {
fn get_reduction_op_advice<A: Allocator + Clone>(
&mut self,
Expand All @@ -857,37 +856,79 @@
quotient_dst: &mut BigintRepr<A>,
remainder_dst: &mut BigintRepr<A>,
) {
let arg: ModExpAdviceParams = {
let a_len = a.digits;
let a_ptr = a.backing.as_ptr();

let modulus_len = m.digits;
let modulus_ptr = m.backing.as_ptr();

assert!(modulus_len > 0);

ModExpAdviceParams {
op: 0,
a_ptr: a_ptr.addr() as u32,
a_len: a_len as u32,
b_ptr: 0,
b_len: 0,
modulus_ptr: modulus_ptr.addr() as u32,
modulus_len: modulus_len as u32,
}
// We use different advice params depending on architecture
// Both are mostly the same, main difference is the width of pointers
#[cfg(target_arch = "riscv32")]
let (mut it, q_len, r_len) = {
use crate::system_functions::modexp::ModExpAdviceParams;
let arg: ModExpAdviceParams = {
let a_len = a.digits;
let a_ptr = a.backing.as_ptr();

let modulus_len = m.digits;
let modulus_ptr = m.backing.as_ptr();

assert!(modulus_len > 0);

ModExpAdviceParams {
op: 0,
a_ptr: a_ptr.addr() as u32,
a_len: a_len as u32,
b_ptr: 0,
b_len: 0,
modulus_ptr: modulus_ptr.addr() as u32,
modulus_len: modulus_len as u32,
}
};
// We assume that oracle's response is well-formed lengths-wise, and we will check value-wise separately
let mut it = self
.inner
.raw_query(
MODEXP_ADVICE_QUERY_ID,
&((&arg as *const ModExpAdviceParams).addr() as u32),
)
.unwrap();
let q_len = it.next().expect("quotient length");
let r_len = it.next().expect("remainder length");
(it, q_len, r_len)
};

// We assume that oracle's response is well-formed lengths-wise, and we will check value-wise separately
let mut it = self
.inner
.raw_query(
MODEXP_ADVICE_QUERY_ID,
&((&arg as *const ModExpAdviceParams).addr() as u32),
)
.unwrap();

let q_len = it.next().expect("quotient length");
let r_len = it.next().expect("remainder length");
#[cfg(not(target_arch = "riscv32"))]
let (mut it, q_len, r_len) = {
let arg: ModExpAdviceParams64 = {
let a_len = a.digits;
let a_ptr = a.backing.as_ptr();

let modulus_len = m.digits;
let modulus_ptr = m.backing.as_ptr();

assert!(modulus_len > 0);

ModExpAdviceParams64 {
op: 0,
a_ptr: a_ptr.addr() as u64,
a_len: a_len as u64,
b_ptr: 0,
b_len: 0,
modulus_ptr: modulus_ptr.addr() as u64,
modulus_len: modulus_len as u64,
}
};
// We assume that oracle's response is well-formed lengths-wise, and we will check value-wise separately
let mut it = self
.inner
.raw_query(
MODEXP_ADVICE_QUERY_ID,
&((&arg as *const ModExpAdviceParams64).addr() as u64),
)
.unwrap();
// Oracle provides lengths as u32, so in this case they are
// packed into a single usize
let packed_lens = it.next().expect("packed lengths");
let q_len = (packed_lens & 0xFFFF_FFFF) as usize;
let r_len = (packed_lens >> 32) as usize;
(it, q_len / 2, r_len / 2)
};

let max_quotient_digits = if a.digits < m.digits {
0
Expand All @@ -899,10 +940,6 @@

let max_remainder_digits = m.digits;

const {
assert!(core::mem::size_of::<usize>() == core::mem::size_of::<u32>());
}

// check that hint is "sane" in upper bound

assert!(q_len.next_multiple_of(8) / 8 <= max_quotient_digits);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use zk_ee::system::logger::Logger;
#[cfg(feature = "testing")]
use zk_ee::system::logger::NullLogger;

#[cfg(any(all(target_arch = "riscv32", feature = "proving"), test))]
pub(super) fn modexp<O: zk_ee::oracle::IOOracle, L: Logger, A: Allocator + Clone>(
base: &[u8],
exp: &[u8],
Expand Down
Loading
Loading