Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

feat/#1665 Precompile ECRECOVER #1720

Merged
merged 28 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
63c5439
Precompile ECRECOVER (#529)
roynalnaruto Jul 4, 2023
ffca5b9
ecrecover soundness (address not recovered) (#930)
roynalnaruto Sep 13, 2023
c0d6123
fix: resolve build errors due to cherry-pick
KimiWu123 Dec 26, 2023
b76fd2f
feat: compiling error free
KimiWu123 Dec 27, 2023
2e72daf
test: pass first basic testing
KimiWu123 Jan 2, 2024
5851481
test: pass all testing for call, not for static_call, call_code and d…
KimiWu123 Jan 3, 2024
831556d
test: pass all the normal testing
KimiWu123 Jan 4, 2024
ce4d6a6
feat: support ecrecover oog case
KimiWu123 Jan 4, 2024
187768e
feat: upload missing ecc circult realted files
KimiWu123 Jan 5, 2024
ea52925
feat: commit missing sig_circuit
KimiWu123 Jan 8, 2024
21d2d19
dep: add halo2-base and halo2-ecc as dependencies
KimiWu123 Jan 9, 2024
b88a8af
fix: build error due to importing halo2_ecc and halo2_base
KimiWu123 Jan 10, 2024
2e2625c
feat: using sign_verify for sig_circuit, compilation error free
KimiWu123 Jan 25, 2024
d0d3c4a
fix error due to rebase
KimiWu123 Jan 26, 2024
772ae18
Revert "feat: using sign_verify for sig_circuit, compilation error free"
KimiWu123 Jan 26, 2024
3dc90c3
feat: fixed all errors coming from sig_circuit merging
KimiWu123 Jan 27, 2024
09dbea8
test: all testing passed in sig_circuit
KimiWu123 Jan 27, 2024
0e6ebbc
chore: fix clippy warnings
KimiWu123 Jan 28, 2024
1cd2ac4
feat: remove pow_of_rand_table
KimiWu123 Jan 28, 2024
e308fc5
chore: fix clippy and wasm error
KimiWu123 Jan 28, 2024
fc1065c
ci: set fixed number of threads for light unit test to avoid OOM
KimiWu123 Jan 29, 2024
4f09a7d
chore: some leftovers
KimiWu123 Jan 30, 2024
359ad7e
test: split out a time-consuming test to a separated one
KimiWu123 Jan 30, 2024
aed502b
chore: remove 'onephase' config and declare two constants for limbs
KimiWu123 Feb 5, 2024
7af89c8
Merge branch 'main' into feat/#1665-ecrecover
KimiWu123 Feb 5, 2024
4d5070f
chore: fix typo as review feedback
KimiWu123 Feb 5, 2024
d6bc6c1
Merge remote-tracking branch 'origin/main' into feat/#1665-ecrecover
KimiWu123 Feb 17, 2024
a9858ef
refactor to WordLoHi
KimiWu123 Feb 17, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/main-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks
args: --verbose --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks -- --test-threads 24
- name: Run testool internal tests
uses: actions-rs/cargo@v1
with:
Expand Down
49 changes: 49 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ members = [
[patch.crates-io]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v0.3.0" }

[patch."https://github.com/scroll-tech/halo2.git"]
halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", tag = "v0.3.0" }

[patch."https://github.com/privacy-scaling-explorations/halo2curves.git"]
halo2curves = { version = "0.1.0", features = ["derive_serde"] }

# Definition of benchmarks profile to use.
[profile.bench]
opt-level = 3
Expand Down
2 changes: 2 additions & 0 deletions bus-mapping/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.gi
itertools = "0.10"
lazy_static = "1.4"
log = "0.4.14"
num = "0.4"
rand = { version = "0.8", optional = true }
serde = {version = "1.0.130", features = ["derive"] }
serde_json = "1.0.66"
strum = "0.24"
Expand Down
8 changes: 8 additions & 0 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use eth_types::{
use ethers_providers::JsonRpcClient;
pub use execution::{
CopyDataType, CopyEvent, CopyStep, ExecState, ExecStep, ExpEvent, ExpStep, NumberOrHash,
PrecompileEvent, PrecompileEvents, N_BYTES_PER_PAIR, N_PAIRING_PER_OP,
};
pub use input_state_ref::CircuitInputStateRef;
use itertools::Itertools;
Expand Down Expand Up @@ -112,6 +113,11 @@ pub struct FixedCParams {
/// calculated, so the same circuit will not be able to prove different
/// witnesses.
pub max_keccak_rows: usize,
/// This number indicate what 100% usage means, for example if we can support up to 2
/// ecPairing inside circuit, and max_vertical_circuit_rows is set to 1_000_000,
/// then if there is 1 ecPairing in the input, we will return 500_000 as the "row usage"
/// for the ec circuit.
pub max_vertical_circuit_rows: usize,
}

/// Unset Circuits Parameters
Expand Down Expand Up @@ -153,6 +159,7 @@ impl Default for FixedCParams {
max_bytecode: 512,
max_evm_rows: 0,
max_keccak_rows: 0,
max_vertical_circuit_rows: 0,
}
}
}
Expand Down Expand Up @@ -497,6 +504,7 @@ impl CircuitInputBuilder<DynamicCParams> {
max_bytecode,
max_evm_rows,
max_keccak_rows,
max_vertical_circuit_rows: 0,
}
};
let mut cib = CircuitInputBuilder::<FixedCParams> {
Expand Down
11 changes: 10 additions & 1 deletion bus-mapping/src/circuit_input_builder/block.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Block-related utility module

use super::{
execution::ExecState, transaction::Transaction, CopyEvent, ExecStep, ExpEvent, Withdrawal,
execution::ExecState, transaction::Transaction, CopyEvent, ExecStep, ExpEvent, PrecompileEvent,
PrecompileEvents, Withdrawal,
};
use crate::{
operation::{OperationContainer, RWCounter},
Expand Down Expand Up @@ -87,6 +88,8 @@ pub struct Block {
pub sha3_inputs: Vec<Vec<u8>>,
/// Exponentiation events in the block.
pub exp_events: Vec<ExpEvent>,
/// IO to/from the precompiled contract calls.
pub precompile_events: PrecompileEvents,
/// Original block from geth
pub eth_block: eth_types::Block<eth_types::Transaction>,
}
Expand Down Expand Up @@ -145,6 +148,7 @@ impl Block {
copy_events: Vec::new(),
exp_events: Vec::new(),
sha3_inputs: Vec::new(),
precompile_events: PrecompileEvents { events: Vec::new() },
eth_block: eth_block.clone(),
})
}
Expand Down Expand Up @@ -191,4 +195,9 @@ impl Block {
pub fn add_exp_event(&mut self, event: ExpEvent) {
self.exp_events.push(event);
}

/// Push a precompile event to the block.
pub fn add_precompile_event(&mut self, event: PrecompileEvent) {
self.precompile_events.events.push(event);
}
}
48 changes: 46 additions & 2 deletions bus-mapping/src/circuit_input_builder/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use crate::{
error::{ExecError, OogError},
exec_trace::OperationRef,
operation::RWCounter,
precompile::PrecompileCalls,
precompile::{PrecompileAuxData, PrecompileCalls},
};
use eth_types::{evm_types::OpcodeId, GethExecStep, Word, H256};
use eth_types::{evm_types::OpcodeId, sign_types::SignData, GethExecStep, Word, H256};
use gadgets::impl_expr;
use halo2_proofs::plonk::Expression;
use strum_macros::EnumIter;
Expand Down Expand Up @@ -49,6 +49,8 @@ pub struct ExecStep {
pub copy_rw_counter_delta: u64,
/// Error generated by this step
pub error: Option<ExecError>,
/// Optional auxiliary data that is attached to precompile call internal states.
pub aux_data: Option<PrecompileAuxData>,
}

impl ExecStep {
Expand Down Expand Up @@ -77,6 +79,7 @@ impl ExecStep {
bus_mapping_instance: Vec::new(),
copy_rw_counter_delta: 0,
error: None,
aux_data: None,
}
}

Expand Down Expand Up @@ -364,3 +367,44 @@ impl Default for ExpEvent {
}
}
}

/// I/Os from all precompiled contract calls in a block.
#[derive(Clone, Debug, Default)]
pub struct PrecompileEvents {
/// All events.
pub events: Vec<PrecompileEvent>,
}

impl PrecompileEvents {
/// Get all ecrecover events.
pub fn get_ecrecover_events(&self) -> Vec<SignData> {
self.events
.iter()
.map(|e| {
let PrecompileEvent::Ecrecover(sign_data) = e;
sign_data
})
.cloned()
.collect()
}
}

/// I/O from a precompiled contract call.
#[derive(Clone, Debug)]
pub enum PrecompileEvent {
/// Represents the I/O from Ecrecover call.
Ecrecover(SignData),
}

impl Default for PrecompileEvent {
fn default() -> Self {
Self::Ecrecover(SignData::default())
}
}

/// The number of pairing inputs per pairing operation. If the inputs provided to the precompile
/// call are < 4, we append (G1::infinity, G2::generator) until we have the required no. of inputs.
pub const N_PAIRING_PER_OP: usize = 4;

/// The number of bytes taken to represent a pair (G1, G2).
pub const N_BYTES_PER_PAIR: usize = 192;
8 changes: 6 additions & 2 deletions bus-mapping/src/circuit_input_builder/input_state_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use super::{
get_call_memory_offset_length, get_create_init_code, Block, BlockContext, Call, CallContext,
CallKind, CodeSource, CopyEvent, ExecState, ExecStep, ExpEvent, Transaction,
CallKind, CodeSource, CopyEvent, ExecState, ExecStep, ExpEvent, PrecompileEvent, Transaction,
TransactionContext,
};
use crate::{
Expand Down Expand Up @@ -121,7 +121,7 @@
}
}

/// Push an [`Operation`](crate::operation::Operation) into the

Check warning on line 124 in bus-mapping/src/circuit_input_builder/input_state_ref.rs

View workflow job for this annotation

GitHub Actions / Various lints

redundant explicit link target
/// [`OperationContainer`](crate::operation::OperationContainer) with the
/// next [`RWCounter`](crate::operation::RWCounter) and then adds a
/// reference to the stored operation ([`OperationRef`]) inside the
Expand Down Expand Up @@ -196,7 +196,7 @@
self.push_op(step, RW::WRITE, op)
}

/// Push an [`Operation`](crate::operation::Operation) with reversible to be

Check warning on line 199 in bus-mapping/src/circuit_input_builder/input_state_ref.rs

View workflow job for this annotation

GitHub Actions / Various lints

redundant explicit link target
/// true into the
/// [`OperationContainer`](crate::operation::OperationContainer) with the
/// next [`RWCounter`](crate::operation::RWCounter) and then adds a
Expand Down Expand Up @@ -1404,6 +1404,11 @@
self.block.add_exp_event(event)
}

/// Push an event representing auxiliary data for a precompile call to the state.
pub fn push_precompile_event(&mut self, event: PrecompileEvent) {
self.block.add_precompile_event(event)
}

pub(crate) fn get_step_err(
&self,
step: &GethExecStep,
Expand Down Expand Up @@ -1614,7 +1619,6 @@
PrecompileCalls::Sha256
| PrecompileCalls::Ripemd160
| PrecompileCalls::Blake2F
| PrecompileCalls::ECRecover
ChihChengLiang marked this conversation as resolved.
Show resolved Hide resolved
| PrecompileCalls::Bn128Add
| PrecompileCalls::Bn128Mul
| PrecompileCalls::Bn128Pairing
Expand Down
12 changes: 11 additions & 1 deletion bus-mapping/src/circuit_input_builder/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,24 @@ pub struct Transaction {
/// The transaction id
pub id: u64,
/// The raw transaction fields
tx: geth_types::Transaction,
pub tx: geth_types::Transaction,
/// Calls made in the transaction
pub(crate) calls: Vec<Call>,
/// Execution steps
steps: Vec<ExecStep>,
}

impl Transaction {
/// Create a dummy Transaction with zero values
pub fn dummy() -> Self {
Self {
id: 0,
calls: Vec::new(),
steps: Vec::new(),
tx: geth_types::Transaction::dummy(),
}
}

/// Create a new Self.
pub fn new(
id: u64,
Expand Down
24 changes: 18 additions & 6 deletions bus-mapping/src/evm/opcodes/callop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ impl<const N_ARGS: usize> Opcode for CallOpcode<N_ARGS> {

// insert a copy event (input) for this step and generate memory op
let rw_counter_start = state.block_ctx.rwc;
if call.call_data_length > 0 {
let input_bytes = if call.call_data_length > 0 {
let n_input_bytes = if let Some(input_len) = precompile_call.input_len() {
min(input_len, call.call_data_length as usize)
} else {
Expand Down Expand Up @@ -390,11 +390,14 @@ impl<const N_ARGS: usize> Opcode for CallOpcode<N_ARGS> {
bytes: input_bytes.iter().map(|s| (*s, false)).collect(),
},
);
}
Some(input_bytes)
} else {
None
};

// write the result in the callee's memory
let rw_counter_start = state.block_ctx.rwc;
if call.is_success && !result.is_empty() {
let output_bytes = if call.is_success && !result.is_empty() {
let (output_bytes, _prev_bytes) = state
.gen_copy_steps_for_precompile_callee_memory(&mut exec_step, &result)?;

Expand All @@ -413,11 +416,14 @@ impl<const N_ARGS: usize> Opcode for CallOpcode<N_ARGS> {
bytes: output_bytes.iter().map(|s| (*s, false)).collect(),
},
);
}
Some(output_bytes)
} else {
None
};

// insert another copy event (output) for this step.
let rw_counter_start = state.block_ctx.rwc;
if call.is_success && length > 0 {
let return_bytes = if call.is_success && length > 0 {
let return_bytes = state.gen_copy_steps_for_precompile_returndata(
&mut exec_step,
call.return_data_offset,
Expand All @@ -439,7 +445,10 @@ impl<const N_ARGS: usize> Opcode for CallOpcode<N_ARGS> {
bytes: return_bytes.iter().map(|s| (*s, false)).collect(),
},
);
}
Some(return_bytes)
} else {
None
};

if has_oog_err {
let mut oog_step = ErrorOOGPrecompile::gen_associated_ops(
Expand All @@ -462,6 +471,9 @@ impl<const N_ARGS: usize> Opcode for CallOpcode<N_ARGS> {
geth_steps[1].clone(),
call.clone(),
precompile_call,
&input_bytes.unwrap_or_default(),
&output_bytes.unwrap_or_default(),
&return_bytes.unwrap_or_default(),
)?;

// Set gas left and gas cost for precompile step.
Expand Down
Loading
Loading