Skip to content

Commit

Permalink
scroll-dev-1019: squash all old diffs
Browse files Browse the repository at this point in the history
  • Loading branch information
lispc committed Oct 19, 2024
1 parent ff8f482 commit 700cdad
Show file tree
Hide file tree
Showing 34 changed files with 1,546 additions and 65 deletions.
1 change: 1 addition & 0 deletions 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
13 changes: 13 additions & 0 deletions crates/core/executor/src/syscalls/code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,15 @@ pub enum SyscallCode {

/// Executes the `BN254_FP2_MUL` precompile.
BN254_FP2_MUL = 0x00_01_01_2B,

/// Execute the `MEMCPY_32` precompile.
MEMCPY_32 = 0x00_01_01_90,
/// Execute the `MEMCPY_64` precompile.
MEMCPY_64 = 0x00_01_01_91,
/// Execute the `BN254_SCALAR_MUL` precompile.
BN254_SCALAR_MUL = 0x00_01_01_80,
/// Execute the `BN254_SCALAR_MAC` precompile.
BN254_SCALAR_MAC = 0x00_01_01_81,
}

impl SyscallCode {
Expand Down Expand Up @@ -170,6 +179,10 @@ impl SyscallCode {
0x00_01_01_2A => SyscallCode::BN254_FP2_SUB,
0x00_01_01_2B => SyscallCode::BN254_FP2_MUL,
0x00_00_01_1C => SyscallCode::BLS12381_DECOMPRESS,
0x00_01_01_90 => SyscallCode::MEMCPY_32,
0x00_01_01_91 => SyscallCode::MEMCPY_64,
0x00_01_01_80 => SyscallCode::BN254_SCALAR_MUL,
0x00_01_01_81 => SyscallCode::BN254_SCALAR_MAC,
_ => panic!("invalid syscall number: {value}"),
}
}
Expand Down
Loading

0 comments on commit 700cdad

Please sign in to comment.