Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scroll-dev-1019 -> v3.0.0 #19

Draft
wants to merge 2 commits into
base: upstream/v3.0.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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: 3 additions & 1 deletion Cargo.lock

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

1 change: 1 addition & 0 deletions crates/core/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ bincode = "1.3.3"
hashbrown = { version = "0.14.5", features = ["serde", "inline-more"] }
itertools = "0.13.0"
rand = "0.8.5"
generic-array = { version = "1.1.0", features = ["alloc", "serde"] }
num = { version = "0.4.3" }
typenum = "1.17.0"
nohash-hasher = "0.2.0"
Expand Down
15 changes: 15 additions & 0 deletions crates/core/executor/src/events/memcpy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use super::{LookupId, MemoryLocalEvent, MemoryReadRecord, MemoryWriteRecord};
use serde::{Deserialize, Serialize};

#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct MemCopyEvent {
pub lookup_id: LookupId,
pub shard: u32,
pub clk: u32,
pub src_ptr: u32,
pub dst_ptr: u32,
pub read_records: Vec<MemoryReadRecord>,
pub write_records: Vec<MemoryWriteRecord>,
/// The local memory access records.
pub local_mem_access: Vec<MemoryLocalEvent>,
}
2 changes: 2 additions & 0 deletions crates/core/executor/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
mod alu;
mod byte;
mod cpu;
mod memcpy;
mod memory;
mod precompiles;
mod syscall;
Expand All @@ -11,6 +12,7 @@ mod utils;
pub use alu::*;
pub use byte::*;
pub use cpu::*;
pub use memcpy::*;
pub use memory::*;
pub use precompiles::*;
pub use syscall::*;
Expand Down
166 changes: 166 additions & 0 deletions crates/core/executor/src/events/precompiles/bn254_scalar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
use num::BigUint;
use sp1_curves::{
params::{FieldParameters, NumWords},
weierstrass::bn254::Bn254ScalarField,
};
use typenum::Unsigned;

use serde::{Deserialize, Serialize};

use crate::{
events::{LookupId, MemoryLocalEvent, MemoryReadRecord, MemoryWriteRecord},
syscalls::SyscallContext,
};

use super::FieldOperation;

pub const NUM_WORDS_PER_FE: usize = 8;

#[derive(Default, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)]
pub enum Bn254FieldOperation {
#[default]
Invalid = 0,
Mul = 2,
Mac = 4,
}

impl Bn254FieldOperation {
pub const fn to_field_operation(&self) -> FieldOperation {
match self {
Bn254FieldOperation::Mul => FieldOperation::Mul,
Bn254FieldOperation::Mac => panic!("not supported"),
Bn254FieldOperation::Invalid => panic!("what??"),
}
}
}

#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct Bn254FieldArithEvent {
pub lookup_id: LookupId,
pub shard: u32,
pub clk: u32,
pub op: Bn254FieldOperation,
pub arg1: FieldArithMemoryAccess<MemoryWriteRecord>,
pub arg2: FieldArithMemoryAccess<MemoryReadRecord>,
pub a: Option<FieldArithMemoryAccess<MemoryReadRecord>>,
pub b: Option<FieldArithMemoryAccess<MemoryReadRecord>>,
/// The local memory access records.
pub local_mem_access: Vec<MemoryLocalEvent>,
}

pub fn create_bn254_scalar_arith_event(
rt: &mut SyscallContext,
arg1: u32,
arg2: u32,
op: Bn254FieldOperation,
) -> Bn254FieldArithEvent {
let start_clk = rt.clk;
let p_ptr = arg1;
let q_ptr = arg2;

assert_eq!(p_ptr % 4, 0, "p_ptr({p_ptr:x}) is not aligned");
assert_eq!(q_ptr % 4, 0, "q_ptr({q_ptr:x}) is not aligned");

let nw_per_fe = <Bn254ScalarField as NumWords>::WordsFieldElement::USIZE;
debug_assert_eq!(nw_per_fe, NUM_WORDS_PER_FE);

let arg1: Vec<u32> = rt.slice_unsafe(p_ptr, nw_per_fe);
let arg2 = match op {
// 2 ptrs of real U256 values
Bn254FieldOperation::Mac => FieldArithMemoryAccess::read(rt, arg2, 2),
_ => FieldArithMemoryAccess::read(rt, arg2, nw_per_fe),
};

let bn_arg1 = BigUint::from_bytes_le(
&arg1.iter().copied().flat_map(u32::to_le_bytes).collect::<Vec<u8>>(),
);
let modulus = Bn254ScalarField::modulus();

let (a, b, bn_arg1_out) = if matches!(op, Bn254FieldOperation::Mac) {
let a = FieldArithMemoryAccess::read(rt, arg2.memory_records[0].value, nw_per_fe);
let b = FieldArithMemoryAccess::read(rt, arg2.memory_records[1].value, nw_per_fe);

let bn_a = a.value_as_biguint();
let bn_b = b.value_as_biguint();
let bn_arg1_out = (&bn_a * &bn_b + &bn_arg1) % modulus;

(Some(a), Some(b), bn_arg1_out)
} else {
let bn_arg2 = arg2.value_as_biguint();

let bn_arg1_out = match op {
Bn254FieldOperation::Mul => (&bn_arg1 * &bn_arg2) % modulus,
_ => unimplemented!("not supported"),
};
(None, None, bn_arg1_out)
};

log::trace!(
"shard: {}, clk: {}, op: {:?}, arg1: {:?}, arg2: {:?}, a: {:?}, b: {:?}",
rt.current_shard(),
rt.clk,
op,
arg1,
arg2,
a,
b
);
rt.clk += 1;

let mut result_words = bn_arg1_out.to_u32_digits();
result_words.resize(nw_per_fe, 0);

let arg1 = FieldArithMemoryAccess::write(rt, p_ptr, &result_words);

let shard = rt.current_shard();
Bn254FieldArithEvent {
lookup_id: rt.syscall_lookup_id,
shard,
clk: start_clk,
op,
arg1,
arg2,
a,
b,
local_mem_access: rt.postprocess(),
}
}

#[derive(Default, Clone, Debug, Serialize, Deserialize)]
pub struct FieldArithMemoryAccess<T> {
pub ptr: u32,
pub memory_records: Vec<T>,
}

impl FieldArithMemoryAccess<MemoryReadRecord> {
pub fn read(rt: &mut SyscallContext, ptr: u32, len: usize) -> Self {
let (memory_records, _) = rt.mr_slice(ptr, len);
Self { ptr, memory_records }
}

pub fn value_as_biguint(&self) -> BigUint {
BigUint::from_bytes_le(
&self
.memory_records
.iter()
.flat_map(|word| word.value.to_le_bytes())
.collect::<Vec<u8>>(),
)
}
}

impl FieldArithMemoryAccess<MemoryWriteRecord> {
pub fn write(rt: &mut SyscallContext, ptr: u32, values: &[u32]) -> Self {
Self { ptr, memory_records: rt.mw_slice(ptr, values) }
}

pub fn prev_value_as_biguint(&self) -> BigUint {
BigUint::from_bytes_le(
&self
.memory_records
.iter()
.flat_map(|word| word.prev_value.to_le_bytes())
.collect::<Vec<u8>>(),
)
}
}
17 changes: 17 additions & 0 deletions crates/core/executor/src/events/precompiles/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod bn254_scalar;
mod ec;
mod edwards;
mod fptower;
Expand All @@ -6,6 +7,9 @@ mod sha256_compress;
mod sha256_extend;
mod uint256;

pub use bn254_scalar::{
create_bn254_scalar_arith_event, Bn254FieldArithEvent, Bn254FieldOperation, NUM_WORDS_PER_FE,
};
pub use ec::*;
pub use edwards::*;
pub use fptower::*;
Expand All @@ -19,6 +23,7 @@ pub use uint256::*;

use crate::syscalls::SyscallCode;

use super::{MemCopyEvent};
use super::{MemoryLocalEvent, SyscallEvent};

#[derive(Clone, Debug, Serialize, Deserialize, EnumIter)]
Expand Down Expand Up @@ -52,6 +57,12 @@ pub enum PrecompileEvent {
Bn254Fp2AddSub(Fp2AddSubEvent),
/// Bn254 quadratic field mul precompile event.
Bn254Fp2Mul(Fp2MulEvent),

Bn254ScalarMac(Bn254FieldArithEvent),
Bn254ScalarMul(Bn254FieldArithEvent),
MemCopy32(MemCopyEvent),
MemCopy64(MemCopyEvent),

/// Bls12-381 curve add precompile event.
Bls12381Add(EllipticCurveAddEvent),
/// Bls12-381 curve double precompile event.
Expand Down Expand Up @@ -120,6 +131,12 @@ impl PrecompileLocalMemory for Vec<(SyscallEvent, PrecompileEvent)> {
PrecompileEvent::Bls12381Fp2Mul(e) | PrecompileEvent::Bn254Fp2Mul(e) => {
iterators.push(e.local_mem_access.iter());
}
PrecompileEvent::Bn254ScalarMac(e) | PrecompileEvent::Bn254ScalarMul(e) => {
iterators.push(e.local_mem_access.iter());
}
PrecompileEvent::MemCopy32(e) | PrecompileEvent::MemCopy64(e) => {
iterators.push(e.local_mem_access.iter());
}
}
}

Expand Down
37 changes: 37 additions & 0 deletions crates/core/executor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,10 @@ impl<'a> Executor<'a> {
let value = (memory_read_value).to_le_bytes()[(addr % 4) as usize];
a = ((value as i8) as i32) as u32;
memory_store_value = Some(memory_read_value);
//println!(
// "[clk: {}, pc: 0x{:x}] LB: {:?} <- {:x}",
// self.state.global_clk, self.state.pc, rd, a
//);
self.rw(rd, a);
}
Opcode::LH => {
Expand All @@ -913,6 +917,10 @@ impl<'a> Executor<'a> {
};
a = ((value as i16) as i32) as u32;
memory_store_value = Some(memory_read_value);
//println!(
// "[clk: {}, pc: 0x{:x}] LH: {:?} <- {:x}",
// self.state.global_clk, self.state.pc, rd, a
//);
self.rw(rd, a);
}
Opcode::LW => {
Expand All @@ -922,6 +930,10 @@ impl<'a> Executor<'a> {
}
a = memory_read_value;
memory_store_value = Some(memory_read_value);
//println!(
// "[clk: {}, pc: 0x{:x}] LW: {:?} <- {}",
// self.state.global_clk, self.state.pc, rd, a
//);
self.rw(rd, a);
}
Opcode::LBU => {
Expand Down Expand Up @@ -957,6 +969,10 @@ impl<'a> Executor<'a> {
_ => unreachable!(),
};
memory_store_value = Some(value);
//println!(
// "[clk: {}, pc: 0x{:x}] SB 0x{:x} <- 0x{:x}",
// self.state.global_clk, pc, addr, value
//);
self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory);
}
Opcode::SH => {
Expand All @@ -970,6 +986,10 @@ impl<'a> Executor<'a> {
_ => unreachable!(),
};
memory_store_value = Some(value);
//println!(
// "[clk: {}, pc: 0x{:x}] SH 0x{:x} <- 0x{:x}",
// self.state.global_clk, pc, addr, value
//);
self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory);
}
Opcode::SW => {
Expand All @@ -979,6 +999,10 @@ impl<'a> Executor<'a> {
}
let value = a;
memory_store_value = Some(value);
//println!(
// "[clk: {}, pc: 0x{:x}] SW 0x{:x} <- 0x{:x}",
// self.state.global_clk, pc, addr, value
//);
self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory);
}

Expand Down Expand Up @@ -1070,6 +1094,7 @@ impl<'a> Executor<'a> {
return Err(ExecutionError::InvalidSyscallUsage(syscall_id as u64));
}

let global_clk = self.state.global_clk;
// Update the syscall counts.
let syscall_for_count = syscall.count_map();
let syscall_count = self.state.syscall_counts.entry(syscall_for_count).or_insert(0);
Expand All @@ -1089,6 +1114,14 @@ impl<'a> Executor<'a> {
}
let mut precompile_rt = SyscallContext::new(self);
precompile_rt.syscall_lookup_id = syscall_lookup_id;
log::trace!(
"[clk: {}, pc: 0x{:x}] ecall syscall_id=0x{:x}, b: 0x{:x}, c: 0x{:x}",
global_clk,
pc,
syscall_id,
b,
c,
);
let (precompile_next_pc, precompile_cycles, returned_exit_code) =
if let Some(syscall_impl) = syscall_impl {
// Executing a syscall optionally returns a value to write to the t0
Expand Down Expand Up @@ -1125,6 +1158,10 @@ impl<'a> Executor<'a> {
next_pc = precompile_next_pc;
self.state.clk += precompile_cycles;
exit_code = returned_exit_code;

//log::info!(
// "execute_instruction {syscall:?} {syscall_count} {nonce} {syscall_lookup_id}"
//);
}
Opcode::EBREAK => {
return Err(ExecutionError::Breakpoint());
Expand Down
Loading
Loading