From c3d4d36e3ef94d02324ccb88eceb627d441ec414 Mon Sep 17 00:00:00 2001 From: Chris Tian Date: Tue, 29 Oct 2024 18:40:14 +0000 Subject: [PATCH 01/17] Revert "feat: executor optimizations (#1692)" This reverts commit 209d2e26d27a4d3236392b4bf5216e48e56b4bf3, reversing changes made to a2dfd90abab4cf5e22acf78dd3bcbd3e77760220. --- Cargo.lock | 1 - Cargo.toml | 6 + crates/core/executor/src/dependencies.rs | 119 ++--- crates/core/executor/src/disassembler/rrs.rs | 57 +- crates/core/executor/src/events/alu.rs | 4 +- crates/core/executor/src/events/byte.rs | 2 +- crates/core/executor/src/events/cpu.rs | 8 + crates/core/executor/src/events/memory.rs | 8 +- crates/core/executor/src/events/utils.rs | 37 +- crates/core/executor/src/executor.rs | 488 ++++++++++-------- crates/core/executor/src/instruction.rs | 4 +- crates/core/executor/src/memory.rs | 27 +- crates/core/executor/src/opcode.rs | 2 +- crates/core/executor/src/program.rs | 7 - crates/core/executor/src/record.rs | 71 +-- crates/core/executor/src/register.rs | 4 +- .../src/syscalls/precompiles/sha256/extend.rs | 10 +- crates/core/machine/Cargo.toml | 1 - crates/core/machine/src/alu/add_sub/mod.rs | 66 ++- crates/core/machine/src/alu/divrem/mod.rs | 28 +- crates/core/machine/src/alu/lt/mod.rs | 51 +- crates/core/machine/src/alu/mul/mod.rs | 283 +++++----- crates/core/machine/src/alu/sr/mod.rs | 73 ++- .../machine/src/cpu/columns/instruction.rs | 6 +- crates/core/machine/src/cpu/columns/opcode.rs | 2 +- crates/core/machine/src/cpu/trace.rs | 213 ++++---- crates/core/machine/src/memory/local.rs | 76 ++- crates/core/machine/src/memory/program.rs | 61 +-- crates/core/machine/src/program/mod.rs | 58 +-- crates/core/machine/src/runtime/utils.rs | 8 +- .../precompiles/edwards/ed_decompress.rs | 2 +- crates/prover/src/lib.rs | 8 +- crates/prover/src/shapes.rs | 21 +- .../recursion/circuit/src/machine/deferred.rs | 2 +- .../compiler/src/circuit/compiler.rs | 5 +- .../core/src/chips/poseidon2_skinny/trace.rs | 4 - .../core/src/chips/poseidon2_wide/trace.rs | 4 - crates/recursion/core/src/machine.rs | 16 +- crates/recursion/core/src/runtime/memory.rs | 2 +- crates/recursion/core/src/runtime/mod.rs | 15 - 40 files changed, 936 insertions(+), 924 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61fc6701dc..78c87ae95b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6221,7 +6221,6 @@ dependencies = [ "tracing-forest", "tracing-subscriber", "typenum", - "vec_map", "web-time", ] diff --git a/Cargo.toml b/Cargo.toml index 593b072f55..8f971a139a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,10 +47,13 @@ debug-assertions = true [workspace.dependencies] # sp1 sp1-build = { path = "crates/build", version = "3.0.0" } +sp1-cli = { path = "crates/cli", version = "3.0.0", default-features = false } sp1-core-machine = { path = "crates/core/machine", version = "3.0.0" } sp1-core-executor = { path = "crates/core/executor", version = "3.0.0" } sp1-curves = { path = "crates/curves", version = "3.0.0" } sp1-derive = { path = "crates/derive", version = "3.0.0" } +sp1-eval = { path = "crates/eval", version = "3.0.0" } +sp1-helper = { path = "crates/helper", version = "3.0.0", default-features = false } sp1-primitives = { path = "crates/primitives", version = "3.0.0" } sp1-prover = { path = "crates/prover", version = "3.0.0" } sp1-recursion-compiler = { path = "crates/recursion/compiler", version = "3.0.0" } @@ -77,8 +80,11 @@ p3-util = "0.1.4-succinct" p3-challenger = "0.1.4-succinct" p3-dft = "0.1.4-succinct" p3-fri = "0.1.4-succinct" +p3-goldilocks = "0.1.4-succinct" +p3-keccak = "0.1.4-succinct" p3-keccak-air = "0.1.4-succinct" p3-blake3 = "0.1.4-succinct" +p3-mds = "0.1.4-succinct" p3-merkle-tree = "0.1.4-succinct" p3-poseidon2 = "0.1.4-succinct" p3-symmetric = "0.1.4-succinct" diff --git a/crates/core/executor/src/dependencies.rs b/crates/core/executor/src/dependencies.rs index 6b0bbbe33c..194d8d0eb2 100644 --- a/crates/core/executor/src/dependencies.rs +++ b/crates/core/executor/src/dependencies.rs @@ -1,5 +1,5 @@ use crate::{ - events::AluEvent, + events::{create_alu_lookups, AluEvent, CpuEvent}, utils::{get_msb, get_quotient_and_remainder, is_signed_operation}, Executor, Opcode, }; @@ -7,7 +7,6 @@ use crate::{ /// Emits the dependencies for division and remainder operations. #[allow(clippy::too_many_lines)] pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { - let shard = executor.shard(); let (quotient, remainder) = get_quotient_and_remainder(event.b, event.c, event.opcode); let c_msb = get_msb(event.c); let rem_msb = get_msb(remainder); @@ -20,29 +19,27 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { } if c_neg == 1 { - let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(AluEvent { lookup_id: event.sub_lookups[4], - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: 0, b: event.c, c: (event.c as i32).unsigned_abs(), - sub_lookups: ids, + sub_lookups: create_alu_lookups(), }); } if rem_neg == 1 { - let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(AluEvent { lookup_id: event.sub_lookups[5], - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: 0, b: remainder, c: (remainder as i32).unsigned_abs(), - sub_lookups: ids, + sub_lookups: create_alu_lookups(), }); } @@ -58,19 +55,19 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { let lower_multiplication = AluEvent { lookup_id: event.sub_lookups[0], - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::MUL, a: lower_word, c: event.c, b: quotient, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.mul_events.push(lower_multiplication); let upper_multiplication = AluEvent { lookup_id: event.sub_lookups[1], - shard, + shard: event.shard, clk: event.clk, opcode: { if is_signed_operation { @@ -82,31 +79,31 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { a: upper_word, c: event.c, b: quotient, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.mul_events.push(upper_multiplication); let lt_event = if is_signed_operation { AluEvent { lookup_id: event.sub_lookups[2], - shard, + shard: event.shard, opcode: Opcode::SLTU, a: 1, b: (remainder as i32).unsigned_abs(), c: u32::max(1, (event.c as i32).unsigned_abs()), clk: event.clk, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), } } else { AluEvent { lookup_id: event.sub_lookups[3], - shard, + shard: event.shard, opcode: Opcode::SLTU, a: 1, b: remainder, c: u32::max(1, event.c), clk: event.clk, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), } }; @@ -117,12 +114,9 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { /// Emit the dependencies for CPU events. #[allow(clippy::too_many_lines)] -pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { - let event = executor.record.cpu_events[index]; - let shard = executor.shard(); - let instruction = &executor.program.fetch(event.pc); +pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { if matches!( - instruction.opcode, + event.instruction.opcode, Opcode::LB | Opcode::LH | Opcode::LW @@ -136,57 +130,58 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { // Add event to ALU check to check that addr == b + c let add_event = AluEvent { lookup_id: event.memory_add_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: memory_addr, b: event.b, c: event.c, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); let addr_offset = (memory_addr % 4_u32) as u8; let mem_value = event.memory_record.unwrap().value(); - if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { - let (unsigned_mem_val, most_sig_mem_value_byte, sign_value) = match instruction.opcode { - Opcode::LB => { - let most_sig_mem_value_byte = mem_value.to_le_bytes()[addr_offset as usize]; - let sign_value = 256; - (most_sig_mem_value_byte as u32, most_sig_mem_value_byte, sign_value) - } - Opcode::LH => { - let sign_value = 65536; - let unsigned_mem_val = match (addr_offset >> 1) % 2 { - 0 => mem_value & 0x0000FFFF, - 1 => (mem_value & 0xFFFF0000) >> 16, - _ => unreachable!(), - }; - let most_sig_mem_value_byte = unsigned_mem_val.to_le_bytes()[1]; - (unsigned_mem_val, most_sig_mem_value_byte, sign_value) - } - _ => unreachable!(), - }; + if matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) { + let (unsigned_mem_val, most_sig_mem_value_byte, sign_value) = + match event.instruction.opcode { + Opcode::LB => { + let most_sig_mem_value_byte = mem_value.to_le_bytes()[addr_offset as usize]; + let sign_value = 256; + (most_sig_mem_value_byte as u32, most_sig_mem_value_byte, sign_value) + } + Opcode::LH => { + let sign_value = 65536; + let unsigned_mem_val = match (addr_offset >> 1) % 2 { + 0 => mem_value & 0x0000FFFF, + 1 => (mem_value & 0xFFFF0000) >> 16, + _ => unreachable!(), + }; + let most_sig_mem_value_byte = unsigned_mem_val.to_le_bytes()[1]; + (unsigned_mem_val, most_sig_mem_value_byte, sign_value) + } + _ => unreachable!(), + }; if most_sig_mem_value_byte >> 7 & 0x01 == 1 { let sub_event = AluEvent { lookup_id: event.memory_sub_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::SUB, a: event.a, b: unsigned_mem_val, c: sign_value, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(sub_event); } } } - if instruction.is_branch_instruction() { + if event.instruction.is_branch_instruction() { let a_eq_b = event.a == event.b; - let use_signed_comparison = matches!(instruction.opcode, Opcode::BLT | Opcode::BGE); + let use_signed_comparison = matches!(event.instruction.opcode, Opcode::BLT | Opcode::BGE); let a_lt_b = if use_signed_comparison { (event.a as i32) < (event.b as i32) } else { @@ -202,27 +197,27 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { // Add the ALU events for the comparisons let lt_comp_event = AluEvent { lookup_id: event.branch_lt_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: alu_op_code, a: a_lt_b as u32, b: event.a, c: event.b, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; let gt_comp_event = AluEvent { lookup_id: event.branch_gt_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: alu_op_code, a: a_gt_b as u32, b: event.b, c: event.a, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.lt_events.push(lt_comp_event); executor.record.lt_events.push(gt_comp_event); - let branching = match instruction.opcode { + let branching = match event.instruction.opcode { Opcode::BEQ => a_eq_b, Opcode::BNE => !a_eq_b, Opcode::BLT | Opcode::BLTU => a_lt_b, @@ -233,31 +228,31 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { let next_pc = event.pc.wrapping_add(event.c); let add_event = AluEvent { lookup_id: event.branch_add_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, c: event.c, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); } } - if instruction.is_jump_instruction() { - match instruction.opcode { + if event.instruction.is_jump_instruction() { + match event.instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); let add_event = AluEvent { lookup_id: event.jump_jal_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, c: event.b, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); } @@ -265,13 +260,13 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { let next_pc = event.b.wrapping_add(event.c); let add_event = AluEvent { lookup_id: event.jump_jalr_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.b, c: event.c, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); } @@ -279,16 +274,16 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { } } - if matches!(instruction.opcode, Opcode::AUIPC) { + if matches!(event.instruction.opcode, Opcode::AUIPC) { let add_event = AluEvent { lookup_id: event.auipc_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: event.a, b: event.pc, c: event.b, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); } diff --git a/crates/core/executor/src/disassembler/rrs.rs b/crates/core/executor/src/disassembler/rrs.rs index a105e10a81..711dbe4e4a 100644 --- a/crates/core/executor/src/disassembler/rrs.rs +++ b/crates/core/executor/src/disassembler/rrs.rs @@ -9,31 +9,52 @@ impl Instruction { /// Create a new [`Instruction`] from an R-type instruction. #[must_use] pub const fn from_r_type(opcode: Opcode, dec_insn: &RType) -> Self { - Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.rs2 as u32, false, false) + Self::new( + opcode, + dec_insn.rd as u32, + dec_insn.rs1 as u32, + dec_insn.rs2 as u32, + false, + false, + ) } /// Create a new [`Instruction`] from an I-type instruction. #[must_use] pub const fn from_i_type(opcode: Opcode, dec_insn: &IType) -> Self { - Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) + Self::new(opcode, dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) } /// Create a new [`Instruction`] from an I-type instruction with a shamt. #[must_use] pub const fn from_i_type_shamt(opcode: Opcode, dec_insn: &ITypeShamt) -> Self { - Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.shamt, false, true) + Self::new(opcode, dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.shamt, false, true) } /// Create a new [`Instruction`] from an S-type instruction. #[must_use] pub const fn from_s_type(opcode: Opcode, dec_insn: &SType) -> Self { - Self::new(opcode, dec_insn.rs2 as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) + Self::new( + opcode, + dec_insn.rs2 as u32, + dec_insn.rs1 as u32, + dec_insn.imm as u32, + false, + true, + ) } /// Create a new [`Instruction`] from a B-type instruction. #[must_use] pub const fn from_b_type(opcode: Opcode, dec_insn: &BType) -> Self { - Self::new(opcode, dec_insn.rs1 as u8, dec_insn.rs2 as u32, dec_insn.imm as u32, false, true) + Self::new( + opcode, + dec_insn.rs1 as u32, + dec_insn.rs2 as u32, + dec_insn.imm as u32, + false, + true, + ) } /// Create a new [`Instruction`] that is not implemented. @@ -61,9 +82,9 @@ impl Instruction { #[must_use] pub fn r_type(&self) -> (Register, Register, Register) { ( - Register::from_u8(self.op_a), - Register::from_u8(self.op_b as u8), - Register::from_u8(self.op_c as u8), + Register::from_u32(self.op_a), + Register::from_u32(self.op_b), + Register::from_u32(self.op_c), ) } @@ -71,35 +92,35 @@ impl Instruction { #[inline] #[must_use] pub fn i_type(&self) -> (Register, Register, u32) { - (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) + (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) } /// Decode the [`Instruction`] in the S-type format. #[inline] #[must_use] pub fn s_type(&self) -> (Register, Register, u32) { - (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) + (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) } /// Decode the [`Instruction`] in the B-type format. #[inline] #[must_use] pub fn b_type(&self) -> (Register, Register, u32) { - (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) + (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) } /// Decode the [`Instruction`] in the J-type format. #[inline] #[must_use] pub fn j_type(&self) -> (Register, u32) { - (Register::from_u8(self.op_a), self.op_b) + (Register::from_u32(self.op_a), self.op_b) } /// Decode the [`Instruction`] in the U-type format. #[inline] #[must_use] pub fn u_type(&self) -> (Register, u32) { - (Register::from_u8(self.op_a), self.op_b) + (Register::from_u32(self.op_a), self.op_b) } } @@ -242,13 +263,13 @@ impl InstructionProcessor for InstructionTranspiler { } fn process_jal(&mut self, dec_insn: JType) -> Self::InstructionResult { - Instruction::new(Opcode::JAL, dec_insn.rd as u8, dec_insn.imm as u32, 0, true, true) + Instruction::new(Opcode::JAL, dec_insn.rd as u32, dec_insn.imm as u32, 0, true, true) } fn process_jalr(&mut self, dec_insn: IType) -> Self::InstructionResult { Instruction::new( Opcode::JALR, - dec_insn.rd as u8, + dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.imm as u32, false, @@ -261,14 +282,14 @@ impl InstructionProcessor for InstructionTranspiler { // // Notably, LUI instructions are converted to an SLL instruction with `imm_b` and `imm_c` // turned on. Additionally the `op_c` should be set to 12. - Instruction::new(Opcode::ADD, dec_insn.rd as u8, 0, dec_insn.imm as u32, true, true) + Instruction::new(Opcode::ADD, dec_insn.rd as u32, 0, dec_insn.imm as u32, true, true) } /// AUIPC instructions have the third operand set to imm << 12. fn process_auipc(&mut self, dec_insn: UType) -> Self::InstructionResult { Instruction::new( Opcode::AUIPC, - dec_insn.rd as u8, + dec_insn.rd as u32, dec_insn.imm as u32, dec_insn.imm as u32, true, @@ -279,7 +300,7 @@ impl InstructionProcessor for InstructionTranspiler { fn process_ecall(&mut self) -> Self::InstructionResult { Instruction::new( Opcode::ECALL, - Register::X5 as u8, + Register::X5 as u32, Register::X10 as u32, Register::X11 as u32, false, diff --git a/crates/core/executor/src/events/alu.rs b/crates/core/executor/src/events/alu.rs index 2d2b14fe03..bf79a65e4c 100644 --- a/crates/core/executor/src/events/alu.rs +++ b/crates/core/executor/src/events/alu.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::Opcode; -use super::{create_random_lookup_ids, LookupId}; +use super::{create_alu_lookups, LookupId}; /// Arithmetic Logic Unit (ALU) Event. /// @@ -40,7 +40,7 @@ impl AluEvent { a, b, c, - sub_lookups: create_random_lookup_ids(), + sub_lookups: create_alu_lookups(), } } } diff --git a/crates/core/executor/src/events/byte.rs b/crates/core/executor/src/events/byte.rs index 3db5c7647b..4e5f254373 100644 --- a/crates/core/executor/src/events/byte.rs +++ b/crates/core/executor/src/events/byte.rs @@ -233,7 +233,7 @@ impl ByteOpcode { ByteOpcode::MSB, ByteOpcode::U16Range, ]; - debug_assert_eq!(opcodes.len(), NUM_BYTE_OPS); + assert_eq!(opcodes.len(), NUM_BYTE_OPS); opcodes } diff --git a/crates/core/executor/src/events/cpu.rs b/crates/core/executor/src/events/cpu.rs index f609e941c0..b2d775cf12 100644 --- a/crates/core/executor/src/events/cpu.rs +++ b/crates/core/executor/src/events/cpu.rs @@ -1,5 +1,7 @@ use serde::{Deserialize, Serialize}; +use crate::Instruction; + use super::{memory::MemoryRecordEnum, LookupId}; /// CPU Event. @@ -8,12 +10,16 @@ use super::{memory::MemoryRecordEnum, LookupId}; /// shard, opcode, operands, and other relevant information. #[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub struct CpuEvent { + /// The shard number. + pub shard: u32, /// The clock cycle. pub clk: u32, /// The program counter. pub pc: u32, /// The next program counter. pub next_pc: u32, + /// The instruction. + pub instruction: Instruction, /// The first operand. pub a: u32, /// The first operand memory record. @@ -26,6 +32,8 @@ pub struct CpuEvent { pub c: u32, /// The third operand memory record. pub c_record: Option, + /// The memory value. + pub memory: Option, /// The memory record. pub memory_record: Option, /// The exit code. diff --git a/crates/core/executor/src/events/memory.rs b/crates/core/executor/src/events/memory.rs index 655e0fc21d..4372f21267 100644 --- a/crates/core/executor/src/events/memory.rs +++ b/crates/core/executor/src/events/memory.rs @@ -150,9 +150,7 @@ impl MemoryReadRecord { prev_shard: u32, prev_timestamp: u32, ) -> Self { - debug_assert!( - shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)) - ); + assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp))); Self { value, shard, timestamp, prev_shard, prev_timestamp } } } @@ -168,9 +166,7 @@ impl MemoryWriteRecord { prev_shard: u32, prev_timestamp: u32, ) -> Self { - debug_assert!( - shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)), - ); + assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)),); Self { value, shard, timestamp, prev_value, prev_shard, prev_timestamp } } } diff --git a/crates/core/executor/src/events/utils.rs b/crates/core/executor/src/events/utils.rs index d4b38df745..681bc6cc78 100644 --- a/crates/core/executor/src/events/utils.rs +++ b/crates/core/executor/src/events/utils.rs @@ -5,16 +5,43 @@ use std::{ iter::{Map, Peekable}, }; +use rand::{thread_rng, Rng}; + /// A unique identifier for lookups. +/// +/// We use 4 u32s instead of a u128 to make it compatible with C. #[derive(Deserialize, Serialize, Debug, Clone, Copy, Default, Eq, Hash, PartialEq)] -pub struct LookupId(pub u64); +pub struct LookupId { + /// First part of the id. + pub a: u32, + /// Second part of the id. + pub b: u32, + /// Third part of the id. + pub c: u32, + /// Fourth part of the id. + pub d: u32, +} + +/// Creates a new ALU lookup id with ``LookupId`` +#[must_use] +pub fn create_alu_lookup_id() -> LookupId { + let mut rng = thread_rng(); + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() } +} -/// Create a random lookup id. This is slower than `record.create_lookup_id()` but is useful for -/// testing. +/// Creates a new ALU lookup id with ``LookupId`` #[must_use] -pub(crate) fn create_random_lookup_ids() -> [LookupId; 6] { - std::array::from_fn(|_| LookupId(rand::random())) +pub fn create_alu_lookups() -> [LookupId; 6] { + let mut rng = thread_rng(); + [ + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + ] } /// Returns sorted and formatted rows of a table of counts (e.g. `opcode_counts`). diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index a815ae5776..cfbc8cacd5 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -13,8 +13,9 @@ use crate::{ context::SP1Context, dependencies::{emit_cpu_dependencies, emit_divrem_dependencies}, events::{ - AluEvent, CpuEvent, LookupId, MemoryAccessPosition, MemoryInitializeFinalizeEvent, - MemoryLocalEvent, MemoryReadRecord, MemoryRecord, MemoryWriteRecord, SyscallEvent, + create_alu_lookup_id, create_alu_lookups, AluEvent, CpuEvent, LookupId, + MemoryAccessPosition, MemoryInitializeFinalizeEvent, MemoryLocalEvent, MemoryReadRecord, + MemoryRecord, MemoryWriteRecord, SyscallEvent, }, hook::{HookEnv, HookRegistry}, memory::{Entry, PagedMemory}, @@ -268,7 +269,7 @@ impl<'a> Executor<'a> { pub fn registers(&mut self) -> [u32; 32] { let mut registers = [0; 32]; for i in 0..32 { - let addr = Register::from_u8(i as u8) as u32; + let addr = Register::from_u32(i as u32) as u32; let record = self.state.memory.get(addr); // Only add the previous memory state to checkpoint map if we're in checkpoint mode, @@ -406,7 +407,7 @@ impl<'a> Executor<'a> { record.shard = shard; record.timestamp = timestamp; - if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { + if !self.unconstrained { let local_memory_access = if let Some(local_memory_access) = local_memory_access { local_memory_access } else { @@ -485,7 +486,7 @@ impl<'a> Executor<'a> { record.shard = shard; record.timestamp = timestamp; - if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { + if !self.unconstrained { let local_memory_access = if let Some(local_memory_access) = local_memory_access { local_memory_access } else { @@ -552,19 +553,19 @@ impl<'a> Executor<'a> { if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { match position { MemoryAccessPosition::A => { - debug_assert!(self.memory_accesses.a.is_none()); + assert!(self.memory_accesses.a.is_none()); self.memory_accesses.a = Some(record.into()); } MemoryAccessPosition::B => { - debug_assert!(self.memory_accesses.b.is_none()); + assert!(self.memory_accesses.b.is_none()); self.memory_accesses.b = Some(record.into()); } MemoryAccessPosition::C => { - debug_assert!(self.memory_accesses.c.is_none()); + assert!(self.memory_accesses.c.is_none()); self.memory_accesses.c = Some(record.into()); } MemoryAccessPosition::Memory => { - debug_assert!(self.memory_accesses.memory.is_none()); + assert!(self.memory_accesses.memory.is_none()); self.memory_accesses.memory = Some(record.into()); } } @@ -592,50 +593,49 @@ impl<'a> Executor<'a> { #[allow(clippy::too_many_arguments)] fn emit_cpu( &mut self, + shard: u32, clk: u32, pc: u32, next_pc: u32, + instruction: Instruction, a: u32, b: u32, c: u32, + memory_store_value: Option, record: MemoryAccessRecord, exit_code: u32, lookup_id: LookupId, syscall_lookup_id: LookupId, ) { - let memory_add_lookup_id = self.record.create_lookup_id(); - let memory_sub_lookup_id = self.record.create_lookup_id(); - let branch_lt_lookup_id = self.record.create_lookup_id(); - let branch_gt_lookup_id = self.record.create_lookup_id(); - let branch_add_lookup_id = self.record.create_lookup_id(); - let jump_jal_lookup_id = self.record.create_lookup_id(); - let jump_jalr_lookup_id = self.record.create_lookup_id(); - let auipc_lookup_id = self.record.create_lookup_id(); - self.record.cpu_events.push(CpuEvent { + let cpu_event = CpuEvent { + shard, clk, pc, next_pc, + instruction, a, a_record: record.a, b, b_record: record.b, c, c_record: record.c, + memory: memory_store_value, memory_record: record.memory, exit_code, alu_lookup_id: lookup_id, syscall_lookup_id, - memory_add_lookup_id, - memory_sub_lookup_id, - branch_lt_lookup_id, - branch_gt_lookup_id, - branch_add_lookup_id, - jump_jal_lookup_id, - jump_jalr_lookup_id, - auipc_lookup_id, - }); + memory_add_lookup_id: create_alu_lookup_id(), + memory_sub_lookup_id: create_alu_lookup_id(), + branch_lt_lookup_id: create_alu_lookup_id(), + branch_gt_lookup_id: create_alu_lookup_id(), + branch_add_lookup_id: create_alu_lookup_id(), + jump_jal_lookup_id: create_alu_lookup_id(), + jump_jalr_lookup_id: create_alu_lookup_id(), + auipc_lookup_id: create_alu_lookup_id(), + }; - emit_cpu_dependencies(self, self.record.cpu_events.len() - 1); + self.record.cpu_events.push(cpu_event); + emit_cpu_dependencies(self, &cpu_event); } /// Emit an ALU event. @@ -648,7 +648,7 @@ impl<'a> Executor<'a> { a, b, c, - sub_lookups: self.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; match opcode { Opcode::ADD => { @@ -696,7 +696,7 @@ impl<'a> Executor<'a> { arg1, arg2, lookup_id, - nonce: self.record.nonce_lookup[lookup_id.0 as usize], + nonce: self.record.nonce_lookup[&lookup_id], } } @@ -725,9 +725,9 @@ impl<'a> Executor<'a> { let (rd, b, c) = (rd, self.rr(rs1, MemoryAccessPosition::B), imm); (rd, b, c) } else { - debug_assert!(instruction.imm_b && instruction.imm_c); + assert!(instruction.imm_b && instruction.imm_c); let (rd, b, c) = - (Register::from_u8(instruction.op_a), instruction.op_b, instruction.op_c); + (Register::from_u32(instruction.op_a), instruction.op_b, instruction.op_c); (rd, b, c) } } @@ -780,7 +780,8 @@ impl<'a> Executor<'a> { /// Fetch the instruction at the current program counter. #[inline] fn fetch(&self) -> Instruction { - *self.program.fetch(self.state.pc) + let idx = ((self.state.pc - self.program.pc_base) / 4) as usize; + self.program.instructions[idx] } /// Execute the given instruction over the current state of the runtime. @@ -792,23 +793,26 @@ impl<'a> Executor<'a> { let mut next_pc = self.state.pc.wrapping_add(4); + let rd: Register; let (a, b, c): (u32, u32, u32); + let (addr, memory_read_value): (u32, u32); + let mut memory_store_value: Option = None; if self.executor_mode == ExecutorMode::Trace { self.memory_accesses = MemoryAccessRecord::default(); } let lookup_id = if self.executor_mode == ExecutorMode::Trace { - self.record.create_lookup_id() + create_alu_lookup_id() } else { LookupId::default() }; let syscall_lookup_id = if self.executor_mode == ExecutorMode::Trace { - self.record.create_lookup_id() + create_alu_lookup_id() } else { LookupId::default() }; - if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { + if !self.unconstrained { self.report.opcode_counts[instruction.opcode] += 1; self.report.event_counts[instruction.opcode] += 1; match instruction.opcode { @@ -838,40 +842,182 @@ impl<'a> Executor<'a> { match instruction.opcode { // Arithmetic instructions. - Opcode::ADD - | Opcode::SUB - | Opcode::XOR - | Opcode::OR - | Opcode::AND - | Opcode::SLL - | Opcode::SRL - | Opcode::SRA - | Opcode::SLT - | Opcode::SLTU - | Opcode::MUL - | Opcode::MULH - | Opcode::MULHU - | Opcode::MULHSU - | Opcode::DIV - | Opcode::DIVU - | Opcode::REM - | Opcode::REMU => { - (a, b, c) = self.execute_alu(instruction, lookup_id); + Opcode::ADD => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_add(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SUB => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_sub(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::XOR => { + (rd, b, c) = self.alu_rr(instruction); + a = b ^ c; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::OR => { + (rd, b, c) = self.alu_rr(instruction); + a = b | c; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::AND => { + (rd, b, c) = self.alu_rr(instruction); + a = b & c; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SLL => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_shl(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SRL => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_shr(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SRA => { + (rd, b, c) = self.alu_rr(instruction); + a = (b as i32).wrapping_shr(c) as u32; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SLT => { + (rd, b, c) = self.alu_rr(instruction); + a = if (b as i32) < (c as i32) { 1 } else { 0 }; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SLTU => { + (rd, b, c) = self.alu_rr(instruction); + a = if b < c { 1 } else { 0 }; + self.alu_rw(instruction, rd, a, b, c, lookup_id); } // Load instructions. - Opcode::LB | Opcode::LH | Opcode::LW | Opcode::LBU | Opcode::LHU => { - (a, b, c) = self.execute_load(instruction)?; + Opcode::LB => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + 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); + self.rw(rd, a); + } + Opcode::LH => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LH, addr)); + } + let value = match (addr >> 1) % 2 { + 0 => memory_read_value & 0x0000_FFFF, + 1 => (memory_read_value & 0xFFFF_0000) >> 16, + _ => unreachable!(), + }; + a = ((value as i16) as i32) as u32; + memory_store_value = Some(memory_read_value); + self.rw(rd, a); + } + Opcode::LW => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + if addr % 4 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LW, addr)); + } + a = memory_read_value; + memory_store_value = Some(memory_read_value); + self.rw(rd, a); + } + Opcode::LBU => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + let value = (memory_read_value).to_le_bytes()[(addr % 4) as usize]; + a = value as u32; + memory_store_value = Some(memory_read_value); + self.rw(rd, a); + } + Opcode::LHU => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LHU, addr)); + } + let value = match (addr >> 1) % 2 { + 0 => memory_read_value & 0x0000_FFFF, + 1 => (memory_read_value & 0xFFFF_0000) >> 16, + _ => unreachable!(), + }; + a = (value as u16) as u32; + memory_store_value = Some(memory_read_value); + self.rw(rd, a); } // Store instructions. - Opcode::SB | Opcode::SH | Opcode::SW => { - (a, b, c) = self.execute_store(instruction)?; + Opcode::SB => { + (a, b, c, addr, memory_read_value) = self.store_rr(instruction); + let value = match addr % 4 { + 0 => (a & 0x0000_00FF) + (memory_read_value & 0xFFFF_FF00), + 1 => ((a & 0x0000_00FF) << 8) + (memory_read_value & 0xFFFF_00FF), + 2 => ((a & 0x0000_00FF) << 16) + (memory_read_value & 0xFF00_FFFF), + 3 => ((a & 0x0000_00FF) << 24) + (memory_read_value & 0x00FF_FFFF), + _ => unreachable!(), + }; + memory_store_value = Some(value); + self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); + } + Opcode::SH => { + (a, b, c, addr, memory_read_value) = self.store_rr(instruction); + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::SH, addr)); + } + let value = match (addr >> 1) % 2 { + 0 => (a & 0x0000_FFFF) + (memory_read_value & 0xFFFF_0000), + 1 => ((a & 0x0000_FFFF) << 16) + (memory_read_value & 0x0000_FFFF), + _ => unreachable!(), + }; + memory_store_value = Some(value); + self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); + } + Opcode::SW => { + (a, b, c, addr, _) = self.store_rr(instruction); + if addr % 4 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::SW, addr)); + } + let value = a; + memory_store_value = Some(value); + self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); } - // Branch instructions. - Opcode::BEQ | Opcode::BNE | Opcode::BLT | Opcode::BGE | Opcode::BLTU | Opcode::BGEU => { - (a, b, c, next_pc) = self.execute_branch(instruction, next_pc); + // B-type instructions. + Opcode::BEQ => { + (a, b, c) = self.branch_rr(instruction); + if a == b { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BNE => { + (a, b, c) = self.branch_rr(instruction); + if a != b { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BLT => { + (a, b, c) = self.branch_rr(instruction); + if (a as i32) < (b as i32) { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BGE => { + (a, b, c) = self.branch_rr(instruction); + if (a as i32) >= (b as i32) { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BLTU => { + (a, b, c) = self.branch_rr(instruction); + if a < b { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BGEU => { + (a, b, c) = self.branch_rr(instruction); + if a >= b { + next_pc = self.state.pc.wrapping_add(c); + } } // Jump instructions. @@ -934,7 +1080,7 @@ impl<'a> Executor<'a> { _ => (self.opts.split_opts.deferred, 1), }; let nonce = (((*syscall_count as usize) % threshold) * multiplier) as u32; - self.record.nonce_lookup[syscall_lookup_id.0 as usize] = nonce; + self.record.nonce_lookup.insert(syscall_lookup_id, nonce); *syscall_count += 1; let syscall_impl = self.get_syscall(syscall).cloned(); @@ -984,181 +1130,95 @@ impl<'a> Executor<'a> { return Err(ExecutionError::Breakpoint()); } - // See https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#instruction-aliases - Opcode::UNIMP => { - return Err(ExecutionError::Unimplemented()); + // Multiply instructions. + Opcode::MUL => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_mul(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); } - } - - // Update the program counter. - self.state.pc = next_pc; - - // Update the clk to the next cycle. - self.state.clk += 4; - - // Emit the CPU event for this cycle. - if self.executor_mode == ExecutorMode::Trace { - self.emit_cpu( - clk, - pc, - next_pc, - a, - b, - c, - self.memory_accesses, - exit_code, - lookup_id, - syscall_lookup_id, - ); - }; - Ok(()) - } - - fn execute_alu(&mut self, instruction: &Instruction, lookup_id: LookupId) -> (u32, u32, u32) { - let (rd, b, c) = self.alu_rr(instruction); - let a = match instruction.opcode { - Opcode::ADD => b.wrapping_add(c), - Opcode::SUB => b.wrapping_sub(c), - Opcode::XOR => b ^ c, - Opcode::OR => b | c, - Opcode::AND => b & c, - Opcode::SLL => b.wrapping_shl(c), - Opcode::SRL => b.wrapping_shr(c), - Opcode::SRA => (b as i32).wrapping_shr(c) as u32, - Opcode::SLT => { - if (b as i32) < (c as i32) { - 1 - } else { - 0 - } + Opcode::MULH => { + (rd, b, c) = self.alu_rr(instruction); + a = (((b as i32) as i64).wrapping_mul((c as i32) as i64) >> 32) as u32; + self.alu_rw(instruction, rd, a, b, c, lookup_id); } - Opcode::SLTU => { - if b < c { - 1 - } else { - 0 - } + Opcode::MULHU => { + (rd, b, c) = self.alu_rr(instruction); + a = ((b as u64).wrapping_mul(c as u64) >> 32) as u32; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::MULHSU => { + (rd, b, c) = self.alu_rr(instruction); + a = (((b as i32) as i64).wrapping_mul(c as i64) >> 32) as u32; + self.alu_rw(instruction, rd, a, b, c, lookup_id); } - Opcode::MUL => b.wrapping_mul(c), - Opcode::MULH => (((b as i32) as i64).wrapping_mul((c as i32) as i64) >> 32) as u32, - Opcode::MULHU => ((b as u64).wrapping_mul(c as u64) >> 32) as u32, - Opcode::MULHSU => (((b as i32) as i64).wrapping_mul(c as i64) >> 32) as u32, Opcode::DIV => { + (rd, b, c) = self.alu_rr(instruction); if c == 0 { - u32::MAX + a = u32::MAX; } else { - (b as i32).wrapping_div(c as i32) as u32 + a = (b as i32).wrapping_div(c as i32) as u32; } + self.alu_rw(instruction, rd, a, b, c, lookup_id); } Opcode::DIVU => { + (rd, b, c) = self.alu_rr(instruction); if c == 0 { - u32::MAX + a = u32::MAX; } else { - b.wrapping_div(c) + a = b.wrapping_div(c); } + self.alu_rw(instruction, rd, a, b, c, lookup_id); } Opcode::REM => { + (rd, b, c) = self.alu_rr(instruction); if c == 0 { - b + a = b; } else { - (b as i32).wrapping_rem(c as i32) as u32 + a = (b as i32).wrapping_rem(c as i32) as u32; } + self.alu_rw(instruction, rd, a, b, c, lookup_id); } Opcode::REMU => { + (rd, b, c) = self.alu_rr(instruction); if c == 0 { - b + a = b; } else { - b.wrapping_rem(c) + a = b.wrapping_rem(c); } + self.alu_rw(instruction, rd, a, b, c, lookup_id); } - _ => unreachable!(), - }; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - (a, b, c) - } - fn execute_load( - &mut self, - instruction: &Instruction, - ) -> Result<(u32, u32, u32), ExecutionError> { - let (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - let a = match instruction.opcode { - Opcode::LB => ((memory_read_value >> ((addr % 4) * 8)) & 0xFF) as i8 as i32 as u32, - Opcode::LH => { - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LH, addr)); - } - ((memory_read_value >> (((addr / 2) % 2) * 16)) & 0xFFFF) as i16 as i32 as u32 - } - Opcode::LW => { - if addr % 4 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LW, addr)); - } - memory_read_value - } - Opcode::LBU => (memory_read_value >> ((addr % 4) * 8)) & 0xFF, - Opcode::LHU => { - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LHU, addr)); - } - (memory_read_value >> (((addr / 2) % 2) * 16)) & 0xFFFF + // See https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#instruction-aliases + Opcode::UNIMP => { + return Err(ExecutionError::Unimplemented()); } - _ => unreachable!(), - }; - self.rw(rd, a); - Ok((a, b, c)) - } + } - fn execute_store( - &mut self, - instruction: &Instruction, - ) -> Result<(u32, u32, u32), ExecutionError> { - let (a, b, c, addr, memory_read_value) = self.store_rr(instruction); - let memory_store_value = match instruction.opcode { - Opcode::SB => { - let shift = (addr % 4) * 8; - ((a & 0xFF) << shift) | (memory_read_value & !(0xFF << shift)) - } - Opcode::SH => { - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::SH, addr)); - } - let shift = ((addr / 2) % 2) * 16; - ((a & 0xFFFF) << shift) | (memory_read_value & !(0xFFFF << shift)) - } - Opcode::SW => { - if addr % 4 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::SW, addr)); - } - a - } - _ => unreachable!(), - }; - self.mw_cpu(align(addr), memory_store_value, MemoryAccessPosition::Memory); - Ok((a, b, c)) - } + // Update the program counter. + self.state.pc = next_pc; - fn execute_branch( - &mut self, - instruction: &Instruction, - mut next_pc: u32, - ) -> (u32, u32, u32, u32) { - let (a, b, c) = self.branch_rr(instruction); - let branch = match instruction.opcode { - Opcode::BEQ => a == b, - Opcode::BNE => a != b, - Opcode::BLT => (a as i32) < (b as i32), - Opcode::BGE => (a as i32) >= (b as i32), - Opcode::BLTU => a < b, - Opcode::BGEU => a >= b, - _ => { - unreachable!() - } + // Update the clk to the next cycle. + self.state.clk += 4; + + // Emit the CPU event for this cycle. + if self.executor_mode == ExecutorMode::Trace { + self.emit_cpu( + self.shard(), + clk, + pc, + next_pc, + *instruction, + a, + b, + c, + memory_store_value, + self.memory_accesses, + exit_code, + lookup_id, + syscall_lookup_id, + ); }; - if branch { - next_pc = self.state.pc.wrapping_add(c); - } - (a, b, c, next_pc) + Ok(()) } /// Executes one cycle of the program, returning whether the program has finished. @@ -1337,7 +1397,6 @@ impl<'a> Executor<'a> { std::mem::replace(&mut self.record, ExecutionRecord::new(self.program.clone())); let public_values = removed_record.public_values; self.record.public_values = public_values; - self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; self.records.push(removed_record); } @@ -1412,8 +1471,6 @@ impl<'a> Executor<'a> { } fn initialize(&mut self) { - self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; - self.state.clk = 0; tracing::debug!("loading memory image"); @@ -1449,11 +1506,6 @@ impl<'a> Executor<'a> { /// Executes up to `self.shard_batch_size` cycles of the program, returning whether the program /// has finished. pub fn execute(&mut self) -> Result { - // Initialize the nonce lookup table if it's uninitialized. - if self.record.nonce_lookup.len() <= 2 { - self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; - } - // Get the program. let program = self.program.clone(); diff --git a/crates/core/executor/src/instruction.rs b/crates/core/executor/src/instruction.rs index 10dfa5476d..bc1df27ba0 100644 --- a/crates/core/executor/src/instruction.rs +++ b/crates/core/executor/src/instruction.rs @@ -15,7 +15,7 @@ pub struct Instruction { /// The operation to execute. pub opcode: Opcode, /// The first operand. - pub op_a: u8, + pub op_a: u32, /// The second operand. pub op_b: u32, /// The third operand. @@ -31,7 +31,7 @@ impl Instruction { #[must_use] pub const fn new( opcode: Opcode, - op_a: u8, + op_a: u32, op_b: u32, op_c: u32, imm_b: bool, diff --git a/crates/core/executor/src/memory.rs b/crates/core/executor/src/memory.rs index a036bbf5ca..6e375753d4 100644 --- a/crates/core/executor/src/memory.rs +++ b/crates/core/executor/src/memory.rs @@ -11,10 +11,10 @@ impl Default for Page { } } -const LOG_PAGE_LEN: usize = 14; +const LOG_PAGE_LEN: usize = 15; const PAGE_LEN: usize = 1 << LOG_PAGE_LEN; const MAX_PAGE_COUNT: usize = ((1 << 31) - (1 << 27)) / 4 / PAGE_LEN + 1; -const NO_PAGE: u16 = u16::MAX; +const NO_PAGE: usize = usize::MAX; const PAGE_MASK: usize = PAGE_LEN - 1; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -41,7 +41,7 @@ impl Default for NewPage { pub struct PagedMemory { /// The internal page table. pub page_table: Vec>, - pub index: Vec, + pub index: Vec, } impl PagedMemory { @@ -50,7 +50,8 @@ impl PagedMemory { /// The number of registers in the virtual machine. const NUM_REGISTERS: usize = 32; /// The offset subtracted from the main address space to make it contiguous. - const ADDR_COMPRESS_OFFSET: usize = Self::NUM_REGISTERS; + const ADDR_COMPRESS_OFFSET: usize = + Self::NUM_REGISTERS - (Self::NUM_REGISTERS >> Self::NUM_IGNORED_LOWER_BITS); /// Create a `PagedMemory` with capacity `MAX_PAGE_COUNT`. pub fn new_preallocated() -> Self { @@ -64,7 +65,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index as usize].0[lower].as_ref() + self.page_table[index].0[lower].as_ref() } } @@ -75,7 +76,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index as usize].0[lower].as_mut() + self.page_table[index].0[lower].as_mut() } } @@ -84,11 +85,11 @@ impl PagedMemory { let (upper, lower) = Self::indices(addr); let mut index = self.index[upper]; if index == NO_PAGE { - index = self.page_table.len() as u16; + index = self.page_table.len(); self.index[upper] = index; self.page_table.push(NewPage::new()); } - self.page_table[index as usize].0[lower].replace(value) + self.page_table[index].0[lower].replace(value) } /// Remove the value at the given address if it exists, returning it. @@ -98,7 +99,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index as usize].0[lower].take() + self.page_table[index].0[lower].take() } } @@ -108,11 +109,11 @@ impl PagedMemory { let index = self.index[upper]; if index == NO_PAGE { let index = self.page_table.len(); - self.index[upper] = index as u16; + self.index[upper] = index; self.page_table.push(NewPage::new()); Entry::Vacant(VacantEntry { entry: &mut self.page_table[index].0[lower] }) } else { - let option = &mut self.page_table[index as usize].0[lower]; + let option = &mut self.page_table[index].0[lower]; match option { Some(_) => Entry::Occupied(OccupiedEntry { entry: option }), None => Entry::Vacant(VacantEntry { entry: option }), @@ -124,7 +125,7 @@ impl PagedMemory { pub fn keys(&self) -> impl Iterator + '_ { self.index.iter().enumerate().filter(|(_, &i)| i != NO_PAGE).flat_map(|(i, index)| { let upper = i << LOG_PAGE_LEN; - self.page_table[*index as usize] + self.page_table[*index] .0 .iter() .enumerate() @@ -274,7 +275,7 @@ impl IntoIterator for PagedMemory { move |(i, index)| { let upper = i << LOG_PAGE_LEN; let replacement = NewPage::new(); - std::mem::replace(&mut self.page_table[index as usize], replacement) + std::mem::replace(&mut self.page_table[index], replacement) .0 .into_iter() .enumerate() diff --git a/crates/core/executor/src/opcode.rs b/crates/core/executor/src/opcode.rs index 818b5b1f2b..6d0589ca91 100644 --- a/crates/core/executor/src/opcode.rs +++ b/crates/core/executor/src/opcode.rs @@ -100,7 +100,7 @@ pub enum Opcode { /// rd ← rs1 % rs2 (unsigned), pc ← pc + 4 REMU = 37, /// Unimplemented instruction. - UNIMP = 38, + UNIMP = 39, } /// Byte Opcode. diff --git a/crates/core/executor/src/program.rs b/crates/core/executor/src/program.rs index 09bb70cac4..29743a4c8f 100644 --- a/crates/core/executor/src/program.rs +++ b/crates/core/executor/src/program.rs @@ -89,13 +89,6 @@ impl Program { }) .copied() } - - #[must_use] - /// Fetch the instruction at the given program counter. - pub fn fetch(&self, pc: u32) -> &Instruction { - let idx = ((pc - self.pc_base) / 4) as usize; - &self.instructions[idx] - } } impl MachineProgram for Program { diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index f9e89acb4c..b6c23c45f8 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -23,7 +23,7 @@ use crate::{ /// A record of the execution of a program. /// /// The trace of the execution is represented as a list of "events" that occur every cycle. -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Default, Clone, Debug, Serialize, Deserialize)] pub struct ExecutionRecord { /// The program. pub program: Arc, @@ -60,63 +60,16 @@ pub struct ExecutionRecord { /// The public values. pub public_values: PublicValues, /// The nonce lookup. - pub nonce_lookup: Vec, - /// The next nonce to use for a new lookup. - pub next_nonce: u64, + pub nonce_lookup: HashMap, /// The shape of the proof. pub shape: Option, } -impl Default for ExecutionRecord { - fn default() -> Self { - let mut res = Self { - program: Arc::default(), - cpu_events: Vec::default(), - add_events: Vec::default(), - mul_events: Vec::default(), - sub_events: Vec::default(), - bitwise_events: Vec::default(), - shift_left_events: Vec::default(), - shift_right_events: Vec::default(), - divrem_events: Vec::default(), - lt_events: Vec::default(), - byte_lookups: HashMap::default(), - precompile_events: PrecompileEvents::default(), - global_memory_initialize_events: Vec::default(), - global_memory_finalize_events: Vec::default(), - cpu_local_memory_access: Vec::default(), - syscall_events: Vec::default(), - public_values: PublicValues::default(), - nonce_lookup: Vec::default(), - next_nonce: 0, - shape: None, - }; - res.nonce_lookup.insert(0, 0); - res - } -} - impl ExecutionRecord { /// Create a new [`ExecutionRecord`]. #[must_use] pub fn new(program: Arc) -> Self { - let mut res = Self { program, ..Default::default() }; - res.nonce_lookup.insert(0, 0); - res - } - - /// Create a lookup id for an event. - pub fn create_lookup_id(&mut self) -> LookupId { - // let id = self.nonce_lookup.len() as u64; - let id = self.next_nonce; - self.next_nonce += 1; - // self.nonce_lookup.insert(id as usize, 0); - LookupId(id) - } - - /// Create 6 lookup ids for an ALU event. - pub fn create_lookup_ids(&mut self) -> [LookupId; 6] { - std::array::from_fn(|_| self.create_lookup_id()) + Self { program, ..Default::default() } } /// Add a mul event to the execution record. @@ -346,7 +299,7 @@ impl MachineRecord for ExecutionRecord { ); stats.insert("local_memory_access_events".to_string(), self.cpu_local_memory_access.len()); if !self.cpu_events.is_empty() { - let shard = self.public_values.shard; + let shard = self.cpu_events[0].shard; stats.insert( "byte_lookups".to_string(), self.byte_lookups.get(&shard).map_or(0, hashbrown::HashMap::len), @@ -384,35 +337,35 @@ impl MachineRecord for ExecutionRecord { fn register_nonces(&mut self, _opts: &Self::Config) { self.add_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.sub_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = (self.add_events.len() + i) as u32; + self.nonce_lookup.insert(event.lookup_id, (self.add_events.len() + i) as u32); }); self.mul_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.bitwise_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.shift_left_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.shift_right_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.divrem_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.lt_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); } diff --git a/crates/core/executor/src/register.rs b/crates/core/executor/src/register.rs index c24b75decc..176ef1c951 100644 --- a/crates/core/executor/src/register.rs +++ b/crates/core/executor/src/register.rs @@ -70,14 +70,14 @@ pub enum Register { } impl Register { - /// Create a new register from a u8. + /// Create a new register from a u32. /// /// # Panics /// /// This function will panic if the register is invalid. #[inline] #[must_use] - pub fn from_u8(value: u8) -> Self { + pub fn from_u32(value: u32) -> Self { match value { 0 => Register::X0, 1 => Register::X1, diff --git a/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs b/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs index 1d4a2a769e..36f1b56542 100644 --- a/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs +++ b/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs @@ -22,11 +22,11 @@ impl Syscall for Sha256ExtendSyscall { assert!(arg2 == 0, "arg2 must be 0"); let w_ptr_init = w_ptr; - let mut w_i_minus_15_reads = Vec::with_capacity(48); - let mut w_i_minus_2_reads = Vec::with_capacity(48); - let mut w_i_minus_16_reads = Vec::with_capacity(48); - let mut w_i_minus_7_reads = Vec::with_capacity(48); - let mut w_i_writes = Vec::with_capacity(48); + let mut w_i_minus_15_reads = Vec::new(); + let mut w_i_minus_2_reads = Vec::new(); + let mut w_i_minus_16_reads = Vec::new(); + let mut w_i_minus_7_reads = Vec::new(); + let mut w_i_writes = Vec::new(); for i in 16..64 { // Read w[i-15]. let (record, w_i_minus_15) = rt.mr(w_ptr + (i - 15) * 4); diff --git a/crates/core/machine/Cargo.toml b/crates/core/machine/Cargo.toml index 3b0b0f34f9..7e2bd5a50a 100644 --- a/crates/core/machine/Cargo.toml +++ b/crates/core/machine/Cargo.toml @@ -54,7 +54,6 @@ static_assertions = "1.1.0" sp1-stark = { workspace = true } sp1-core-executor = { workspace = true } sp1-curves = { workspace = true } -vec_map = "0.8.2" [dev-dependencies] tiny-keccak = { version = "2.0.2", features = ["keccak"] } diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index d276820755..bf6dabef42 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ events::{AluEvent, ByteLookupEvent, ByteRecord}, ExecutionRecord, Opcode, Program, @@ -19,10 +19,7 @@ use sp1_stark::{ Word, }; -use crate::{ - operations::AddOperation, - utils::{next_power_of_two, zeroed_f_vec}, -}; +use crate::{operations::AddOperation, utils::pad_rows_fixed}; /// The number of main trace columns for `AddSubChip`. pub const NUM_ADD_SUB_COLS: usize = size_of::>(); @@ -82,29 +79,46 @@ impl MachineAir for AddSubChip { std::cmp::max((input.add_events.len() + input.sub_events.len()) / num_cpus::get(), 1); let merged_events = input.add_events.iter().chain(input.sub_events.iter()).collect::>(); - let nb_rows = merged_events.len(); - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_ADD_SUB_COLS); - - values.chunks_mut(chunk_size * NUM_ADD_SUB_COLS).enumerate().par_bridge().for_each( - |(i, rows)| { - rows.chunks_mut(NUM_ADD_SUB_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - let cols: &mut AddSubCols = row.borrow_mut(); - - if idx < merged_events.len() { - let mut byte_lookup_events = Vec::new(); - let event = &merged_events[idx]; - self.event_to_row(event, cols, &mut byte_lookup_events); - } - cols.nonce = F::from_canonical_usize(idx); - }); - }, - ); + let row_batches = merged_events + .par_chunks(chunk_size) + .map(|events| { + let rows = events + .iter() + .map(|event| { + let mut row = [F::zero(); NUM_ADD_SUB_COLS]; + let cols: &mut AddSubCols = row.as_mut_slice().borrow_mut(); + let mut blu = Vec::new(); + self.event_to_row(event, cols, &mut blu); + row + }) + .collect::>(); + rows + }) + .collect::>(); + + let mut rows: Vec<[F; NUM_ADD_SUB_COLS]> = vec![]; + for row_batch in row_batches { + rows.extend(row_batch); + } + + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_ADD_SUB_COLS], + input.fixed_log2_rows::(self), + ); // Convert the trace to a row major matrix. - RowMajorMatrix::new(values, NUM_ADD_SUB_COLS) + let mut trace = + RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_ADD_SUB_COLS); + + // Write the nonces to the trace. + for i in 0..trace.height() { + let cols: &mut AddSubCols = + trace.values[i * NUM_ADD_SUB_COLS..(i + 1) * NUM_ADD_SUB_COLS].borrow_mut(); + cols.nonce = F::from_canonical_usize(i); + } + + trace } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index 4491cacd0a..d811b90d45 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -279,19 +279,11 @@ impl MachineAir for DivRemChip { // Set the `alu_event` flags. cols.abs_c_alu_event = cols.c_neg * cols.is_real; cols.abs_c_alu_event_nonce = F::from_canonical_u32( - input - .nonce_lookup - .get(event.sub_lookups[4].0 as usize) - .copied() - .unwrap_or_default(), + input.nonce_lookup.get(&event.sub_lookups[4]).copied().unwrap_or_default(), ); cols.abs_rem_alu_event = cols.rem_neg * cols.is_real; cols.abs_rem_alu_event_nonce = F::from_canonical_u32( - input - .nonce_lookup - .get(event.sub_lookups[5].0 as usize) - .copied() - .unwrap_or_default(), + input.nonce_lookup.get(&event.sub_lookups[5]).copied().unwrap_or_default(), ); // Insert the MSB lookup events. @@ -352,24 +344,16 @@ impl MachineAir for DivRemChip { // Insert the necessary multiplication & LT events. { cols.lower_nonce = F::from_canonical_u32( - input - .nonce_lookup - .get(event.sub_lookups[0].0 as usize) - .copied() - .unwrap_or_default(), + input.nonce_lookup.get(&event.sub_lookups[0]).copied().unwrap_or_default(), ); cols.upper_nonce = F::from_canonical_u32( - input - .nonce_lookup - .get(event.sub_lookups[1].0 as usize) - .copied() - .unwrap_or_default(), + input.nonce_lookup.get(&event.sub_lookups[1]).copied().unwrap_or_default(), ); if is_signed_operation(event.opcode) { cols.abs_nonce = F::from_canonical_u32( input .nonce_lookup - .get(event.sub_lookups[2].0 as usize) + .get(&event.sub_lookups[2]) .copied() .unwrap_or_default(), ); @@ -377,7 +361,7 @@ impl MachineAir for DivRemChip { cols.abs_nonce = F::from_canonical_u32( input .nonce_lookup - .get(event.sub_lookups[3].0 as usize) + .get(&event.sub_lookups[3]) .copied() .unwrap_or_default(), ); diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index b8c5900447..a9462b8def 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -19,7 +19,7 @@ use sp1_stark::{ Word, }; -use crate::utils::{next_power_of_two, zeroed_f_vec}; +use crate::utils::pad_rows_fixed; /// The number of main trace columns for `LtChip`. pub const NUM_LT_COLS: usize = size_of::>(); @@ -107,31 +107,38 @@ impl MachineAir for LtChip { _: &mut ExecutionRecord, ) -> RowMajorMatrix { // Generate the trace rows for each event. - let nb_rows = input.lt_events.len(); - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_LT_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values.chunks_mut(chunk_size * NUM_LT_COLS).enumerate().par_bridge().for_each( - |(i, rows)| { - rows.chunks_mut(NUM_LT_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - let cols: &mut LtCols = row.borrow_mut(); - - if idx < nb_rows { - let mut byte_lookup_events = Vec::new(); - let event = &input.lt_events[idx]; - self.event_to_row(event, cols, &mut byte_lookup_events); - } - cols.nonce = F::from_canonical_usize(idx); - }); - }, + let mut rows = input + .lt_events + .par_iter() + .map(|event| { + let mut row = [F::zero(); NUM_LT_COLS]; + let mut new_byte_lookup_events: Vec = Vec::new(); + let cols: &mut LtCols = row.as_mut_slice().borrow_mut(); + self.event_to_row(event, cols, &mut new_byte_lookup_events); + + row + }) + .collect::>(); + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_LT_COLS], + input.fixed_log2_rows::(self), ); // Convert the trace to a row major matrix. + let mut trace = + RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_LT_COLS); + + // Write the nonces to the trace. + for i in 0..trace.height() { + let cols: &mut LtCols = + trace.values[i * NUM_LT_COLS..(i + 1) * NUM_LT_COLS].borrow_mut(); + cols.nonce = F::from_canonical_usize(i); + } - RowMajorMatrix::new(values, NUM_LT_COLS) + trace } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index 299e0931aa..a9a32cd5c4 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -35,24 +35,19 @@ use core::{ mem::size_of, }; -use hashbrown::HashMap; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{AluEvent, ByteLookupEvent, ByteRecord}, + events::{ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; use sp1_primitives::consts::WORD_SIZE; -use sp1_stark::{air::MachineAir, Word}; +use sp1_stark::{air::MachineAir, MachineRecord, Word}; -use crate::{ - air::SP1CoreAirBuilder, - alu::mul::utils::get_msb, - utils::{next_power_of_two, zeroed_f_vec}, -}; +use crate::{air::SP1CoreAirBuilder, alu::mul::utils::get_msb, utils::pad_rows_fixed}; /// The number of main trace columns for `MulChip`. pub const NUM_MUL_COLS: usize = size_of::>(); @@ -136,54 +131,148 @@ impl MachineAir for MulChip { fn generate_trace( &self, input: &ExecutionRecord, - _: &mut ExecutionRecord, + output: &mut ExecutionRecord, ) -> RowMajorMatrix { - // Generate the trace rows for each event. - let nb_rows = input.mul_events.len(); - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_MUL_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values.chunks_mut(chunk_size * NUM_MUL_COLS).enumerate().par_bridge().for_each( - |(i, rows)| { - rows.chunks_mut(NUM_MUL_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - let cols: &mut MulCols = row.borrow_mut(); - - if idx < nb_rows { - let mut byte_lookup_events = Vec::new(); - let event = &input.mul_events[idx]; - self.event_to_row(event, cols, &mut byte_lookup_events); - } - cols.nonce = F::from_canonical_usize(idx); - }); - }, - ); + let mul_events = input.mul_events.clone(); + // Compute the chunk size based on the number of events and the number of CPUs. + let chunk_size = std::cmp::max(mul_events.len() / num_cpus::get(), 1); - // Convert the trace to a row major matrix. - - RowMajorMatrix::new(values, NUM_MUL_COLS) - } - - fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { - let chunk_size = std::cmp::max(input.mul_events.len() / num_cpus::get(), 1); - - let blu_batches = input - .mul_events + // Generate the trace rows & corresponding records for each chunk of events in parallel. + let rows_and_records = mul_events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); - events.iter().for_each(|event| { - let mut row = [F::zero(); NUM_MUL_COLS]; - let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); - self.event_to_row(event, cols, &mut blu); - }); - blu + let mut record = ExecutionRecord::default(); + let rows = events + .iter() + .map(|event| { + // Ensure that the opcode is MUL, MULHU, MULH, or MULHSU. + assert!( + event.opcode == Opcode::MUL + || event.opcode == Opcode::MULHU + || event.opcode == Opcode::MULH + || event.opcode == Opcode::MULHSU + ); + let mut row = [F::zero(); NUM_MUL_COLS]; + let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); + + let a_word = event.a.to_le_bytes(); + let b_word = event.b.to_le_bytes(); + let c_word = event.c.to_le_bytes(); + + let mut b = b_word.to_vec(); + let mut c = c_word.to_vec(); + + // Handle b and c's signs. + { + let b_msb = get_msb(b_word); + cols.b_msb = F::from_canonical_u8(b_msb); + let c_msb = get_msb(c_word); + cols.c_msb = F::from_canonical_u8(c_msb); + + // If b is signed and it is negative, sign extend b. + if (event.opcode == Opcode::MULH || event.opcode == Opcode::MULHSU) + && b_msb == 1 + { + cols.b_sign_extend = F::one(); + b.resize(PRODUCT_SIZE, BYTE_MASK); + } + + // If c is signed and it is negative, sign extend c. + if event.opcode == Opcode::MULH && c_msb == 1 { + cols.c_sign_extend = F::one(); + c.resize(PRODUCT_SIZE, BYTE_MASK); + } + + // Insert the MSB lookup events. + { + let words = [b_word, c_word]; + let mut blu_events: Vec = vec![]; + for word in words.iter() { + let most_significant_byte = word[WORD_SIZE - 1]; + blu_events.push(ByteLookupEvent { + shard: event.shard, + opcode: ByteOpcode::MSB, + a1: get_msb(*word) as u16, + a2: 0, + b: most_significant_byte, + c: 0, + }); + } + record.add_byte_lookup_events(blu_events); + } + } + + let mut product = [0u32; PRODUCT_SIZE]; + for i in 0..b.len() { + for j in 0..c.len() { + if i + j < PRODUCT_SIZE { + product[i + j] += (b[i] as u32) * (c[j] as u32); + } + } + } + + // Calculate the correct product using the `product` array. We store the + // correct carry value for verification. + let base = (1 << BYTE_SIZE) as u32; + let mut carry = [0u32; PRODUCT_SIZE]; + for i in 0..PRODUCT_SIZE { + carry[i] = product[i] / base; + product[i] %= base; + if i + 1 < PRODUCT_SIZE { + product[i + 1] += carry[i]; + } + cols.carry[i] = F::from_canonical_u32(carry[i]); + } + + cols.product = product.map(F::from_canonical_u32); + cols.a = Word(a_word.map(F::from_canonical_u8)); + cols.b = Word(b_word.map(F::from_canonical_u8)); + cols.c = Word(c_word.map(F::from_canonical_u8)); + cols.is_real = F::one(); + cols.is_mul = F::from_bool(event.opcode == Opcode::MUL); + cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); + cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); + cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); + cols.shard = F::from_canonical_u32(event.shard); + + // Range check. + { + record.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); + record.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); + } + row + }) + .collect::>(); + (rows, record) }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect::>()); + // Generate the trace rows for each event. + let mut rows: Vec<[F; NUM_MUL_COLS]> = vec![]; + for mut row_and_record in rows_and_records { + rows.extend(row_and_record.0); + output.append(&mut row_and_record.1); + } + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_MUL_COLS], + input.fixed_log2_rows::(self), + ); + + // Convert the trace to a row major matrix. + let mut trace = + RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_MUL_COLS); + + // Write the nonces to the trace. + for i in 0..trace.height() { + let cols: &mut MulCols = + trace.values[i * NUM_MUL_COLS..(i + 1) * NUM_MUL_COLS].borrow_mut(); + cols.nonce = F::from_canonical_usize(i); + } + + trace } fn included(&self, shard: &Self::Record) -> bool { @@ -195,100 +284,6 @@ impl MachineAir for MulChip { } } -impl MulChip { - /// Create a row from an event. - fn event_to_row( - &self, - event: &AluEvent, - cols: &mut MulCols, - blu: &mut impl ByteRecord, - ) { - let a_word = event.a.to_le_bytes(); - let b_word = event.b.to_le_bytes(); - let c_word = event.c.to_le_bytes(); - - let mut b = b_word.to_vec(); - let mut c = c_word.to_vec(); - - // Handle b and c's signs. - { - let b_msb = get_msb(b_word); - cols.b_msb = F::from_canonical_u8(b_msb); - let c_msb = get_msb(c_word); - cols.c_msb = F::from_canonical_u8(c_msb); - - // If b is signed and it is negative, sign extend b. - if (event.opcode == Opcode::MULH || event.opcode == Opcode::MULHSU) && b_msb == 1 { - cols.b_sign_extend = F::one(); - b.resize(PRODUCT_SIZE, BYTE_MASK); - } - - // If c is signed and it is negative, sign extend c. - if event.opcode == Opcode::MULH && c_msb == 1 { - cols.c_sign_extend = F::one(); - c.resize(PRODUCT_SIZE, BYTE_MASK); - } - - // Insert the MSB lookup events. - { - let words = [b_word, c_word]; - let mut blu_events: Vec = vec![]; - for word in words.iter() { - let most_significant_byte = word[WORD_SIZE - 1]; - blu_events.push(ByteLookupEvent { - shard: event.shard, - opcode: ByteOpcode::MSB, - a1: get_msb(*word) as u16, - a2: 0, - b: most_significant_byte, - c: 0, - }); - } - blu.add_byte_lookup_events(blu_events); - } - } - - let mut product = [0u32; PRODUCT_SIZE]; - for i in 0..b.len() { - for j in 0..c.len() { - if i + j < PRODUCT_SIZE { - product[i + j] += (b[i] as u32) * (c[j] as u32); - } - } - } - - // Calculate the correct product using the `product` array. We store the - // correct carry value for verification. - let base = (1 << BYTE_SIZE) as u32; - let mut carry = [0u32; PRODUCT_SIZE]; - for i in 0..PRODUCT_SIZE { - carry[i] = product[i] / base; - product[i] %= base; - if i + 1 < PRODUCT_SIZE { - product[i + 1] += carry[i]; - } - cols.carry[i] = F::from_canonical_u32(carry[i]); - } - - cols.product = product.map(F::from_canonical_u32); - cols.a = Word(a_word.map(F::from_canonical_u8)); - cols.b = Word(b_word.map(F::from_canonical_u8)); - cols.c = Word(c_word.map(F::from_canonical_u8)); - cols.is_real = F::one(); - cols.is_mul = F::from_bool(event.opcode == Opcode::MUL); - cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); - cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); - cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); - cols.shard = F::from_canonical_u32(event.shard); - - // Range check. - { - blu.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); - blu.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); - } - } -} - impl BaseAir for MulChip { fn width(&self) -> usize { NUM_MUL_COLS diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index 86dd4d2d32..84990a9c0b 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -52,7 +52,7 @@ use itertools::Itertools; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; use sp1_core_executor::{ events::{AluEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, @@ -65,7 +65,7 @@ use crate::{ air::SP1CoreAirBuilder, alu::sr::utils::{nb_bits_to_shift, nb_bytes_to_shift}, bytes::utils::shr_carry, - utils::{next_power_of_two, zeroed_f_vec}, + utils::pad_rows_fixed, }; /// The number of main trace columns for `ShiftRightChip`. @@ -149,33 +149,54 @@ impl MachineAir for ShiftRightChip { _: &mut ExecutionRecord, ) -> RowMajorMatrix { // Generate the trace rows for each event. - let nb_rows = input.shift_right_events.len(); - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_SHIFT_RIGHT_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values.chunks_mut(chunk_size * NUM_SHIFT_RIGHT_COLS).enumerate().par_bridge().for_each( - |(i, rows)| { - rows.chunks_mut(NUM_SHIFT_RIGHT_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - let cols: &mut ShiftRightCols = row.borrow_mut(); - - if idx < nb_rows { - let mut byte_lookup_events = Vec::new(); - let event = &input.shift_right_events[idx]; - self.event_to_row(event, cols, &mut byte_lookup_events); - } else { - cols.shift_by_n_bits[0] = F::one(); - cols.shift_by_n_bytes[0] = F::one(); - } - cols.nonce = F::from_canonical_usize(idx); - }); - }, + let mut rows: Vec<[F; NUM_SHIFT_RIGHT_COLS]> = Vec::new(); + let sr_events = input.shift_right_events.clone(); + for event in sr_events.iter() { + assert!(event.opcode == Opcode::SRL || event.opcode == Opcode::SRA); + let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; + let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); + let mut blu = Vec::new(); + self.event_to_row(event, cols, &mut blu); + rows.push(row); + } + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_SHIFT_RIGHT_COLS], + input.fixed_log2_rows::(self), ); // Convert the trace to a row major matrix. - RowMajorMatrix::new(values, NUM_SHIFT_RIGHT_COLS) + let mut trace = RowMajorMatrix::new( + rows.into_iter().flatten().collect::>(), + NUM_SHIFT_RIGHT_COLS, + ); + + // Create the template for the padded rows. These are fake rows that don't fail on some + // sanity checks. + let padded_row_template = { + let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; + let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); + // Shift 0 by 0 bits and 0 bytes. + // cols.is_srl = F::one(); + cols.shift_by_n_bits[0] = F::one(); + cols.shift_by_n_bytes[0] = F::one(); + row + }; + debug_assert!(padded_row_template.len() == NUM_SHIFT_RIGHT_COLS); + for i in input.shift_right_events.len() * NUM_SHIFT_RIGHT_COLS..trace.values.len() { + trace.values[i] = padded_row_template[i % NUM_SHIFT_RIGHT_COLS]; + } + + // Write the nonces to the trace. + for i in 0..trace.height() { + let cols: &mut ShiftRightCols = + trace.values[i * NUM_SHIFT_RIGHT_COLS..(i + 1) * NUM_SHIFT_RIGHT_COLS].borrow_mut(); + cols.nonce = F::from_canonical_usize(i); + } + + trace } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/cpu/columns/instruction.rs b/crates/core/machine/src/cpu/columns/instruction.rs index 27dd1f6a91..a16de4fb08 100644 --- a/crates/core/machine/src/cpu/columns/instruction.rs +++ b/crates/core/machine/src/cpu/columns/instruction.rs @@ -27,13 +27,13 @@ pub struct InstructionCols { } impl InstructionCols { - pub fn populate(&mut self, instruction: &Instruction) { + pub fn populate(&mut self, instruction: Instruction) { self.opcode = instruction.opcode.as_field::(); - self.op_a = (instruction.op_a as u32).into(); + self.op_a = instruction.op_a.into(); self.op_b = instruction.op_b.into(); self.op_c = instruction.op_c.into(); - self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u8); + self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u32); } } diff --git a/crates/core/machine/src/cpu/columns/opcode.rs b/crates/core/machine/src/cpu/columns/opcode.rs index 4de8f11ba7..9b4344d036 100644 --- a/crates/core/machine/src/cpu/columns/opcode.rs +++ b/crates/core/machine/src/cpu/columns/opcode.rs @@ -63,7 +63,7 @@ pub struct OpcodeSelectorCols { } impl OpcodeSelectorCols { - pub fn populate(&mut self, instruction: &Instruction) { + pub fn populate(&mut self, instruction: Instruction) { self.imm_b = F::from_bool(instruction.imm_b); self.imm_c = F::from_bool(instruction.imm_c); diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index c9831c66c0..01b1489127 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -1,10 +1,10 @@ use hashbrown::HashMap; use itertools::Itertools; use sp1_core_executor::{ - events::{ByteLookupEvent, ByteRecord, CpuEvent, MemoryRecordEnum}, + events::{ByteLookupEvent, ByteRecord, CpuEvent, LookupId, MemoryRecordEnum}, syscalls::SyscallCode, ByteOpcode::{self, U16Range}, - ExecutionRecord, Instruction, Opcode, Program, + CoreShape, ExecutionRecord, Opcode, Program, Register::X0, }; use sp1_primitives::consts::WORD_SIZE; @@ -13,10 +13,15 @@ use std::{array, borrow::BorrowMut}; use p3_field::{PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ + IntoParallelRefMutIterator, ParallelBridge, ParallelIterator, ParallelSlice, +}; use tracing::instrument; -use super::{columns::NUM_CPU_COLS, CpuChip}; +use super::{ + columns::{CPU_COL_MAP, NUM_CPU_COLS}, + CpuChip, +}; use crate::{cpu::columns::CpuCols, memory::MemoryCols, utils::zeroed_f_vec}; impl MachineAir for CpuChip { @@ -33,16 +38,7 @@ impl MachineAir for CpuChip { input: &ExecutionRecord, _: &mut ExecutionRecord, ) -> RowMajorMatrix { - let n_real_rows = input.cpu_events.len(); - let padded_nb_rows = if let Some(shape) = &input.shape { - 1 << shape.inner[&MachineAir::::name(self)] - } else if n_real_rows < 16 { - 16 - } else { - n_real_rows.next_power_of_two() - }; - let mut values = zeroed_f_vec(padded_nb_rows * NUM_CPU_COLS); - let shard = input.public_values.shard; + let mut values = zeroed_f_vec(input.cpu_events.len() * NUM_CPU_COLS); let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); values.chunks_mut(chunk_size * NUM_CPU_COLS).enumerate().par_bridge().for_each( @@ -50,36 +46,30 @@ impl MachineAir for CpuChip { rows.chunks_mut(NUM_CPU_COLS).enumerate().for_each(|(j, row)| { let idx = i * chunk_size + j; let cols: &mut CpuCols = row.borrow_mut(); - - if idx >= input.cpu_events.len() { - cols.selectors.imm_b = F::one(); - cols.selectors.imm_c = F::one(); - } else { - let mut byte_lookup_events = Vec::new(); - let event = &input.cpu_events[idx]; - let instruction = &input.program.fetch(event.pc); - self.event_to_row( - event, - &input.nonce_lookup, - cols, - &mut byte_lookup_events, - shard, - instruction, - ); - } + let mut byte_lookup_events = Vec::new(); + self.event_to_row( + &input.cpu_events[idx], + &input.nonce_lookup, + cols, + &mut byte_lookup_events, + ); }); }, ); // Convert the trace to a row major matrix. - RowMajorMatrix::new(values, NUM_CPU_COLS) + let mut trace = RowMajorMatrix::new(values, NUM_CPU_COLS); + + // Pad the trace to a power of two. + Self::pad_to_power_of_two::(self, &input.shape, &mut trace.values); + + trace } #[instrument(name = "generate cpu dependencies", level = "debug", skip_all)] fn generate_dependencies(&self, input: &ExecutionRecord, output: &mut ExecutionRecord) { // Generate the trace rows for each event. let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); - let shard = input.public_values.shard; let blu_events: Vec<_> = input .cpu_events @@ -90,15 +80,7 @@ impl MachineAir for CpuChip { ops.iter().for_each(|op| { let mut row = [F::zero(); NUM_CPU_COLS]; let cols: &mut CpuCols = row.as_mut_slice().borrow_mut(); - let instruction = &input.program.fetch(op.pc); - self.event_to_row::( - op, - &input.nonce_lookup, - cols, - &mut blu, - shard, - instruction, - ); + self.event_to_row::(op, &HashMap::new(), cols, &mut blu); }); blu }) @@ -121,25 +103,23 @@ impl CpuChip { fn event_to_row( &self, event: &CpuEvent, - nonce_lookup: &[u32], + nonce_lookup: &HashMap, cols: &mut CpuCols, blu_events: &mut impl ByteRecord, - shard: u32, - instruction: &Instruction, ) { // Populate shard and clk columns. - self.populate_shard_clk(cols, event, blu_events, shard); + self.populate_shard_clk(cols, event, blu_events); // Populate the nonce. cols.nonce = F::from_canonical_u32( - nonce_lookup.get(event.alu_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.alu_lookup_id).copied().unwrap_or_default(), ); // Populate basic fields. cols.pc = F::from_canonical_u32(event.pc); cols.next_pc = F::from_canonical_u32(event.next_pc); - cols.instruction.populate(instruction); - cols.selectors.populate(instruction); + cols.instruction.populate(event.instruction); + cols.selectors.populate(event.instruction); *cols.op_a_access.value_mut() = event.a.into(); *cols.op_b_access.value_mut() = event.b.into(); *cols.op_c_access.value_mut() = event.c.into(); @@ -165,7 +145,7 @@ impl CpuChip { .map(|x| x.as_canonical_u32()) .collect::>(); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, + shard: event.shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -173,7 +153,7 @@ impl CpuChip { c: a_bytes[1] as u8, }); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, + shard: event.shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -182,20 +162,23 @@ impl CpuChip { }); // Populate memory accesses for reading from memory. + assert_eq!(event.memory_record.is_some(), event.memory.is_some()); let memory_columns = cols.opcode_specific_columns.memory_mut(); if let Some(record) = event.memory_record { memory_columns.memory_access.populate(record, blu_events) } // Populate memory, branch, jump, and auipc specific fields. - self.populate_memory(cols, event, blu_events, nonce_lookup, shard, instruction); - self.populate_branch(cols, event, nonce_lookup, instruction); - self.populate_jump(cols, event, nonce_lookup, instruction); - self.populate_auipc(cols, event, nonce_lookup, instruction); + self.populate_memory(cols, event, blu_events, nonce_lookup); + self.populate_branch(cols, event, nonce_lookup); + self.populate_jump(cols, event, nonce_lookup); + self.populate_auipc(cols, event, nonce_lookup); let is_halt = self.populate_ecall(cols, event, nonce_lookup); cols.is_sequential_instr = F::from_bool( - !instruction.is_branch_instruction() && !instruction.is_jump_instruction() && !is_halt, + !event.instruction.is_branch_instruction() + && !event.instruction.is_jump_instruction() + && !is_halt, ); // Assert that the instruction is not a no-op. @@ -208,9 +191,8 @@ impl CpuChip { cols: &mut CpuCols, event: &CpuEvent, blu_events: &mut impl ByteRecord, - shard: u32, ) { - cols.shard = F::from_canonical_u32(shard); + cols.shard = F::from_canonical_u32(event.shard); cols.clk = F::from_canonical_u32(event.clk); let clk_16bit_limb = (event.clk & 0xffff) as u16; @@ -219,15 +201,15 @@ impl CpuChip { cols.clk_8bit_limb = F::from_canonical_u8(clk_8bit_limb); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, + event.shard, U16Range, - shard as u16, + event.shard as u16, 0, 0, 0, )); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, + event.shard, U16Range, clk_16bit_limb, 0, @@ -235,7 +217,7 @@ impl CpuChip { 0, )); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, + event.shard, ByteOpcode::U8Range, 0, 0, @@ -250,12 +232,10 @@ impl CpuChip { cols: &mut CpuCols, event: &CpuEvent, blu_events: &mut impl ByteRecord, - nonce_lookup: &[u32], - shard: u32, - instruction: &Instruction, + nonce_lookup: &HashMap, ) { if !matches!( - instruction.opcode, + event.instruction.opcode, Opcode::LB | Opcode::LH | Opcode::LW @@ -282,7 +262,7 @@ impl CpuChip { let bits: [bool; 8] = array::from_fn(|i| aligned_addr_ls_byte & (1 << i) != 0); memory_columns.aa_least_sig_byte_decomp = array::from_fn(|i| F::from_bool(bits[i + 2])); memory_columns.addr_word_nonce = F::from_canonical_u32( - nonce_lookup.get(event.memory_add_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.memory_add_lookup_id).copied().unwrap_or_default(), ); // Populate memory offsets. @@ -295,10 +275,10 @@ impl CpuChip { // If it is a load instruction, set the unsigned_mem_val column. let mem_value = event.memory_record.unwrap().value(); if matches!( - instruction.opcode, + event.instruction.opcode, Opcode::LB | Opcode::LBU | Opcode::LH | Opcode::LHU | Opcode::LW ) { - match instruction.opcode { + match event.instruction.opcode { Opcode::LB | Opcode::LBU => { cols.unsigned_mem_val = (mem_value.to_le_bytes()[addr_offset as usize] as u32).into(); @@ -318,8 +298,8 @@ impl CpuChip { } // For the signed load instructions, we need to check if the loaded value is negative. - if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { - let most_sig_mem_value_byte = if matches!(instruction.opcode, Opcode::LB) { + if matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) { + let most_sig_mem_value_byte = if matches!(event.instruction.opcode, Opcode::LB) { cols.unsigned_mem_val.to_u32().to_le_bytes()[0] } else { cols.unsigned_mem_val.to_u32().to_le_bytes()[1] @@ -330,22 +310,20 @@ impl CpuChip { F::from_canonical_u8(most_sig_mem_value_byte >> i & 0x01); } if memory_columns.most_sig_byte_decomp[7] == F::one() { - cols.mem_value_is_neg_not_x0 = F::from_bool(instruction.op_a != (X0 as u8)); + cols.mem_value_is_neg_not_x0 = + F::from_bool(event.instruction.op_a != (X0 as u32)); cols.unsigned_mem_val_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.memory_sub_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), + nonce_lookup.get(&event.memory_sub_lookup_id).copied().unwrap_or_default(), ); } } // Set the `mem_value_is_pos_not_x0` composite flag. cols.mem_value_is_pos_not_x0 = F::from_bool( - ((matches!(instruction.opcode, Opcode::LB | Opcode::LH) + ((matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) && (memory_columns.most_sig_byte_decomp[7] == F::zero())) - || matches!(instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) - && instruction.op_a != (X0 as u8), + || matches!(event.instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) + && event.instruction.op_a != (X0 as u32), ); } @@ -353,7 +331,7 @@ impl CpuChip { let addr_bytes = memory_addr.to_le_bytes(); for byte_pair in addr_bytes.chunks_exact(2) { blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, + shard: event.shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -368,15 +346,15 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &[u32], - instruction: &Instruction, + nonce_lookup: &HashMap, ) { - if instruction.is_branch_instruction() { + if event.instruction.is_branch_instruction() { let branch_columns = cols.opcode_specific_columns.branch_mut(); let a_eq_b = event.a == event.b; - let use_signed_comparison = matches!(instruction.opcode, Opcode::BLT | Opcode::BGE); + let use_signed_comparison = + matches!(event.instruction.opcode, Opcode::BLT | Opcode::BGE); let a_lt_b = if use_signed_comparison { (event.a as i32) < (event.b as i32) @@ -390,18 +368,18 @@ impl CpuChip { }; branch_columns.a_lt_b_nonce = F::from_canonical_u32( - nonce_lookup.get(event.branch_lt_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.branch_lt_lookup_id).copied().unwrap_or_default(), ); branch_columns.a_gt_b_nonce = F::from_canonical_u32( - nonce_lookup.get(event.branch_gt_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.branch_gt_lookup_id).copied().unwrap_or_default(), ); branch_columns.a_eq_b = F::from_bool(a_eq_b); branch_columns.a_lt_b = F::from_bool(a_lt_b); branch_columns.a_gt_b = F::from_bool(a_gt_b); - let branching = match instruction.opcode { + let branching = match event.instruction.opcode { Opcode::BEQ => a_eq_b, Opcode::BNE => !a_eq_b, Opcode::BLT | Opcode::BLTU => a_lt_b, @@ -418,10 +396,7 @@ impl CpuChip { if branching { cols.branching = F::one(); branch_columns.next_pc_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.branch_add_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), + nonce_lookup.get(&event.branch_add_lookup_id).copied().unwrap_or_default(), ); } else { cols.not_branching = F::one(); @@ -434,13 +409,12 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &[u32], - instruction: &Instruction, + nonce_lookup: &HashMap, ) { - if instruction.is_jump_instruction() { + if event.instruction.is_jump_instruction() { let jump_columns = cols.opcode_specific_columns.jump_mut(); - match instruction.opcode { + match event.instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); jump_columns.op_a_range_checker.populate(event.a); @@ -449,10 +423,7 @@ impl CpuChip { jump_columns.next_pc = Word::from(next_pc); jump_columns.next_pc_range_checker.populate(next_pc); jump_columns.jal_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.jump_jal_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), + nonce_lookup.get(&event.jump_jal_lookup_id).copied().unwrap_or_default(), ); } Opcode::JALR => { @@ -461,10 +432,7 @@ impl CpuChip { jump_columns.next_pc = Word::from(next_pc); jump_columns.next_pc_range_checker.populate(next_pc); jump_columns.jalr_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.jump_jalr_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), + nonce_lookup.get(&event.jump_jalr_lookup_id).copied().unwrap_or_default(), ); } _ => unreachable!(), @@ -477,16 +445,15 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &[u32], - instruction: &Instruction, + nonce_lookup: &HashMap, ) { - if matches!(instruction.opcode, Opcode::AUIPC) { + if matches!(event.instruction.opcode, Opcode::AUIPC) { let auipc_columns = cols.opcode_specific_columns.auipc_mut(); auipc_columns.pc = Word::from(event.pc); auipc_columns.pc_range_checker.populate(event.pc); auipc_columns.auipc_nonce = F::from_canonical_u32( - nonce_lookup.get(event.auipc_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.auipc_lookup_id).copied().unwrap_or_default(), ); } } @@ -496,7 +463,7 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &[u32], + nonce_lookup: &HashMap, ) -> bool { let mut is_halt = false; @@ -549,8 +516,9 @@ impl CpuChip { } // Write the syscall nonce. - ecall_cols.syscall_nonce = - F::from_canonical_u32(nonce_lookup[event.syscall_lookup_id.0 as usize]); + ecall_cols.syscall_nonce = F::from_canonical_u32( + nonce_lookup.get(&event.syscall_lookup_id).copied().unwrap_or_default(), + ); is_halt = syscall_id == F::from_canonical_u32(SyscallCode::HALT.syscall_id()); @@ -572,4 +540,29 @@ impl CpuChip { is_halt } + + fn pad_to_power_of_two(&self, shape: &Option, values: &mut Vec) { + let n_real_rows = values.len() / NUM_CPU_COLS; + let padded_nb_rows = if let Some(shape) = shape { + 1 << shape.inner[&MachineAir::::name(self)] + } else if n_real_rows < 16 { + 16 + } else { + n_real_rows.next_power_of_two() + }; + values.resize(padded_nb_rows * NUM_CPU_COLS, F::zero()); + + // Interpret values as a slice of arrays of length `NUM_CPU_COLS` + let rows = unsafe { + core::slice::from_raw_parts_mut( + values.as_mut_ptr() as *mut [F; NUM_CPU_COLS], + values.len() / NUM_CPU_COLS, + ) + }; + + rows[n_real_rows..].par_iter_mut().for_each(|padded_row| { + padded_row[CPU_COL_MAP.selectors.imm_b] = F::one(); + padded_row[CPU_COL_MAP.selectors.imm_c] = F::one(); + }); + } } diff --git a/crates/core/machine/src/memory/local.rs b/crates/core/machine/src/memory/local.rs index 8be4377031..bf109d028e 100644 --- a/crates/core/machine/src/memory/local.rs +++ b/crates/core/machine/src/memory/local.rs @@ -3,11 +3,11 @@ use std::{ mem::size_of, }; -use crate::utils::{next_power_of_two, zeroed_f_vec}; +use crate::utils::pad_rows_fixed; +use itertools::Itertools; use p3_air::{Air, BaseAir}; use p3_field::PrimeField32; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -86,45 +86,39 @@ impl MachineAir for MemoryLocalChip { input: &ExecutionRecord, _output: &mut ExecutionRecord, ) -> RowMajorMatrix { - // Generate the trace rows for each event. - let events = input.get_local_mem_events().collect::>(); - let nb_rows = (events.len() + 3) / 4; - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_MEMORY_LOCAL_INIT_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values - .chunks_mut(chunk_size * NUM_MEMORY_LOCAL_INIT_COLS) - .enumerate() - .par_bridge() - .for_each(|(i, rows)| { - rows.chunks_mut(NUM_MEMORY_LOCAL_INIT_COLS).enumerate().for_each(|(j, row)| { - let idx = (i * chunk_size + j) * NUM_LOCAL_MEMORY_ENTRIES_PER_ROW; - - let cols: &mut MemoryLocalCols = row.borrow_mut(); - for k in 0..NUM_LOCAL_MEMORY_ENTRIES_PER_ROW { - let cols = &mut cols.memory_local_entries[k]; - if idx + k < events.len() { - let event = &events[idx + k]; - cols.addr = F::from_canonical_u32(event.addr); - cols.initial_shard = - F::from_canonical_u32(event.initial_mem_access.shard); - cols.final_shard = F::from_canonical_u32(event.final_mem_access.shard); - cols.initial_clk = - F::from_canonical_u32(event.initial_mem_access.timestamp); - cols.final_clk = - F::from_canonical_u32(event.final_mem_access.timestamp); - cols.initial_value = event.initial_mem_access.value.into(); - cols.final_value = event.final_mem_access.value.into(); - cols.is_real = F::one(); - } - } - }); - }); - - // Convert the trace to a row major matrix. - RowMajorMatrix::new(values, NUM_MEMORY_LOCAL_INIT_COLS) + let mut rows = Vec::<[F; NUM_MEMORY_LOCAL_INIT_COLS]>::new(); + + for local_mem_events in + &input.get_local_mem_events().chunks(NUM_LOCAL_MEMORY_ENTRIES_PER_ROW) + { + let mut row = [F::zero(); NUM_MEMORY_LOCAL_INIT_COLS]; + let cols: &mut MemoryLocalCols = row.as_mut_slice().borrow_mut(); + + for (cols, event) in cols.memory_local_entries.iter_mut().zip(local_mem_events) { + cols.addr = F::from_canonical_u32(event.addr); + cols.initial_shard = F::from_canonical_u32(event.initial_mem_access.shard); + cols.final_shard = F::from_canonical_u32(event.final_mem_access.shard); + cols.initial_clk = F::from_canonical_u32(event.initial_mem_access.timestamp); + cols.final_clk = F::from_canonical_u32(event.final_mem_access.timestamp); + cols.initial_value = event.initial_mem_access.value.into(); + cols.final_value = event.final_mem_access.value.into(); + cols.is_real = F::one(); + } + + rows.push(row); + } + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_MEMORY_LOCAL_INIT_COLS], + input.fixed_log2_rows::(self), + ); + + RowMajorMatrix::new( + rows.into_iter().flatten().collect::>(), + NUM_MEMORY_LOCAL_INIT_COLS, + ) } fn included(&self, shard: &Self::Record) -> bool { diff --git a/crates/core/machine/src/memory/program.rs b/crates/core/machine/src/memory/program.rs index 699e052c0d..7b68661624 100644 --- a/crates/core/machine/src/memory/program.rs +++ b/crates/core/machine/src/memory/program.rs @@ -7,7 +7,6 @@ use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, PairBuilder}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -18,10 +17,7 @@ use sp1_stark::{ InteractionKind, Word, }; -use crate::{ - operations::IsZeroOperation, - utils::{next_power_of_two, pad_rows_fixed, zeroed_f_vec}, -}; +use crate::{operations::IsZeroOperation, utils::pad_rows_fixed}; pub const NUM_MEMORY_PROGRAM_PREPROCESSED_COLS: usize = size_of::>(); @@ -75,36 +71,35 @@ impl MachineAir for MemoryProgramChip { } fn generate_preprocessed_trace(&self, program: &Self::Program) -> Option> { - // Generate the trace rows for each event. - let nb_rows = program.memory_image.len(); - let size_log2 = program.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_MEMORY_PROGRAM_PREPROCESSED_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - let memory = program.memory_image.iter().collect::>(); - values - .chunks_mut(chunk_size * NUM_MEMORY_PROGRAM_PREPROCESSED_COLS) - .enumerate() - .par_bridge() - .for_each(|(i, rows)| { - rows.chunks_mut(NUM_MEMORY_PROGRAM_PREPROCESSED_COLS).enumerate().for_each( - |(j, row)| { - let idx = i * chunk_size + j; - - if idx < nb_rows { - let (addr, word) = memory[idx]; - let cols: &mut MemoryProgramPreprocessedCols = row.borrow_mut(); - cols.addr = F::from_canonical_u32(*addr); - cols.value = Word::from(*word); - cols.is_real = F::one(); - } - }, - ); - }); + let program_memory = &program.memory_image; + // Note that BTreeMap is guaranteed to be sorted by key. This makes the row order + // deterministic. + let mut rows = program_memory + .iter() + .sorted() + .map(|(&addr, &word)| { + let mut row = [F::zero(); NUM_MEMORY_PROGRAM_PREPROCESSED_COLS]; + let cols: &mut MemoryProgramPreprocessedCols = row.as_mut_slice().borrow_mut(); + cols.addr = F::from_canonical_u32(addr); + cols.value = Word::from(word); + cols.is_real = F::one(); + row + }) + .collect::>(); + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_MEMORY_PROGRAM_PREPROCESSED_COLS], + program.fixed_log2_rows::(self), + ); // Convert the trace to a row major matrix. - Some(RowMajorMatrix::new(values, NUM_MEMORY_PROGRAM_PREPROCESSED_COLS)) + let trace = RowMajorMatrix::new( + rows.into_iter().flatten().collect::>(), + NUM_MEMORY_PROGRAM_PREPROCESSED_COLS, + ); + Some(trace) } fn generate_dependencies(&self, _input: &ExecutionRecord, _output: &mut ExecutionRecord) { diff --git a/crates/core/machine/src/program/mod.rs b/crates/core/machine/src/program/mod.rs index f6c1f3bc0c..39dfb6a765 100644 --- a/crates/core/machine/src/program/mod.rs +++ b/crates/core/machine/src/program/mod.rs @@ -4,14 +4,10 @@ use core::{ }; use std::collections::HashMap; -use crate::{ - air::ProgramAirBuilder, - utils::{next_power_of_two, pad_rows_fixed, zeroed_f_vec}, -}; +use crate::{air::ProgramAirBuilder, utils::pad_rows_fixed}; use p3_air::{Air, BaseAir, PairBuilder}; use p3_field::PrimeField; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::air::{MachineAir, SP1AirBuilder}; @@ -69,34 +65,36 @@ impl MachineAir for ProgramChip { !program.instructions.is_empty() || program.preprocessed_shape.is_some(), "empty program" ); - // Generate the trace rows for each event. - let nb_rows = program.instructions.len(); - let size_log2 = program.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_PROGRAM_PREPROCESSED_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values - .chunks_mut(chunk_size * NUM_PROGRAM_PREPROCESSED_COLS) + let mut rows = program + .instructions + .iter() .enumerate() - .par_bridge() - .for_each(|(i, rows)| { - rows.chunks_mut(NUM_PROGRAM_PREPROCESSED_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - - if idx < nb_rows { - let cols: &mut ProgramPreprocessedCols = row.borrow_mut(); - let instruction = &program.instructions[idx]; - let pc = program.pc_base + (idx as u32 * 4); - cols.pc = F::from_canonical_u32(pc); - cols.instruction.populate(instruction); - cols.selectors.populate(instruction); - } - }); - }); + .map(|(i, &instruction)| { + let pc = program.pc_base + (i as u32 * 4); + let mut row = [F::zero(); NUM_PROGRAM_PREPROCESSED_COLS]; + let cols: &mut ProgramPreprocessedCols = row.as_mut_slice().borrow_mut(); + cols.pc = F::from_canonical_u32(pc); + cols.instruction.populate(instruction); + cols.selectors.populate(instruction); + + row + }) + .collect::>(); + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_PROGRAM_PREPROCESSED_COLS], + program.fixed_log2_rows::(self), + ); // Convert the trace to a row major matrix. - Some(RowMajorMatrix::new(values, NUM_PROGRAM_PREPROCESSED_COLS)) + let trace = RowMajorMatrix::new( + rows.into_iter().flatten().collect::>(), + NUM_PROGRAM_PREPROCESSED_COLS, + ); + + Some(trace) } fn generate_dependencies(&self, _input: &ExecutionRecord, _output: &mut ExecutionRecord) { diff --git a/crates/core/machine/src/runtime/utils.rs b/crates/core/machine/src/runtime/utils.rs index 483400e294..7c0ad541e7 100644 --- a/crates/core/machine/src/runtime/utils.rs +++ b/crates/core/machine/src/runtime/utils.rs @@ -19,7 +19,7 @@ macro_rules! assert_valid_memory_access { assert!($addr > 40); } _ => { - Register::from_u8($addr); + Register::from_u32($addr); } }; } @@ -69,7 +69,11 @@ impl<'a> Runtime<'a> { ); if !self.unconstrained && self.state.global_clk % 10_000_000 == 0 { - log::info!("clk = {} pc = 0x{:x?}", self.state.global_clk, self.state.pc); + log::info!( + "clk = {} pc = 0x{:x?}", + self.state.global_clk, + self.state.pc + ); } } } diff --git a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs index 97d0e526fe..c9c5ae93c8 100644 --- a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs +++ b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs @@ -72,7 +72,7 @@ impl EdDecompressCols { self.clk = F::from_canonical_u32(event.clk); self.ptr = F::from_canonical_u32(event.ptr); self.nonce = F::from_canonical_u32( - record.nonce_lookup.get(event.lookup_id.0 as usize).copied().unwrap_or_default(), + record.nonce_lookup.get(&event.lookup_id).copied().unwrap_or_default(), ); self.sign = F::from_bool(event.sign); for i in 0..8 { diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index fb46afd4ed..be4d816264 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -33,7 +33,11 @@ use std::{ }; use lru::LruCache; + +use tracing::instrument; + use p3_baby_bear::BabyBear; + use p3_challenger::CanObserve; use p3_field::{AbstractField, PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; @@ -76,7 +80,6 @@ use sp1_stark::{ MachineProver, SP1CoreOpts, SP1ProverOpts, ShardProof, StarkGenericConfig, StarkVerifyingKey, Val, Word, DIGEST_SIZE, }; -use tracing::instrument; pub use types::*; use utils::{sp1_committed_values_digest_bn254, sp1_vkey_digest_bn254, words_to_bytes}; @@ -353,9 +356,8 @@ impl SP1Prover { input: &SP1CompressWithVKeyWitnessValues, ) -> Arc> { let mut cache = self.compress_programs.lock().unwrap_or_else(|e| e.into_inner()); - let shape = input.shape(); cache - .get_or_insert(shape.clone(), || { + .get_or_insert(input.shape(), || { let misses = self.compress_cache_misses.fetch_add(1, Ordering::Relaxed); tracing::debug!("compress cache miss, misses: {}", misses); // Get the operations. diff --git a/crates/prover/src/shapes.rs b/crates/prover/src/shapes.rs index 74f7ba177e..b7adddc0e5 100644 --- a/crates/prover/src/shapes.rs +++ b/crates/prover/src/shapes.rs @@ -1,13 +1,11 @@ use std::{ collections::{BTreeMap, BTreeSet, HashSet}, fs::File, - hash::{DefaultHasher, Hash, Hasher}, panic::{catch_unwind, AssertUnwindSafe}, path::PathBuf, sync::{Arc, Mutex}, }; -use eyre::Result; use thiserror::Error; use p3_baby_bear::BabyBear; @@ -31,7 +29,7 @@ pub enum SP1ProofShape { Shrink(ProofShape), } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub enum SP1CompressProgramShape { Recursion(SP1RecursionShape), Compress(SP1CompressWithVkeyShape), @@ -39,14 +37,6 @@ pub enum SP1CompressProgramShape { Shrink(SP1CompressWithVkeyShape), } -impl SP1CompressProgramShape { - pub fn hash_u64(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - Hash::hash(&self, &mut hasher); - hasher.finish() - } -} - #[derive(Debug, Error)] pub enum VkBuildError { #[error("IO error: {0}")] @@ -241,15 +231,6 @@ impl SP1ProofShape { ) } - pub fn generate_compress_shapes( - recursion_shape_config: &'_ RecursionShapeConfig>, - reduce_batch_size: usize, - ) -> impl Iterator + '_ { - (1..=reduce_batch_size).flat_map(|batch_size| { - recursion_shape_config.get_all_shape_combinations(batch_size).map(Self::Compress) - }) - } - pub fn dummy_vk_map<'a>( core_shape_config: &'a CoreShapeConfig, recursion_shape_config: &'a RecursionShapeConfig>, diff --git a/crates/recursion/circuit/src/machine/deferred.rs b/crates/recursion/circuit/src/machine/deferred.rs index d5ab720973..0f38620a7d 100644 --- a/crates/recursion/circuit/src/machine/deferred.rs +++ b/crates/recursion/circuit/src/machine/deferred.rs @@ -43,7 +43,7 @@ pub struct SP1DeferredVerifier { _phantom: std::marker::PhantomData<(C, SC, A)>, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub struct SP1DeferredShape { inner: SP1CompressShape, height: usize, diff --git a/crates/recursion/compiler/src/circuit/compiler.rs b/crates/recursion/compiler/src/circuit/compiler.rs index b44b38a1dd..d75c0d3d6e 100644 --- a/crates/recursion/compiler/src/circuit/compiler.rs +++ b/crates/recursion/compiler/src/circuit/compiler.rs @@ -17,9 +17,6 @@ use sp1_recursion_core::*; use crate::prelude::*; -/// The number of instructions to preallocate in a recursion program -const PREALLOC_INSTRUCTIONS: usize = 10000000; - /// The backend for the circuit compiler. #[derive(Debug, Clone, Default)] pub struct AsmCompiler { @@ -514,7 +511,7 @@ where // Compile each IR instruction into a list of ASM instructions, then combine them. // This step also counts the number of times each address is read from. let (mut instrs, traces) = tracing::debug_span!("compile_one loop").in_scope(|| { - let mut instrs = Vec::with_capacity(PREALLOC_INSTRUCTIONS); + let mut instrs = Vec::with_capacity(operations.vec.len()); let mut traces = vec![]; if debug_mode { let mut span_builder = diff --git a/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs b/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs index 7e67f54362..ecd9c57550 100644 --- a/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs @@ -41,10 +41,6 @@ impl MachineAir for Poseidon2SkinnyChip format!("Poseidon2SkinnyDeg{}", DEGREE) } - fn generate_dependencies(&self, _: &Self::Record, _: &mut Self::Record) { - // This is a no-op. - } - #[instrument(name = "generate poseidon2 skinny trace", level = "debug", skip_all, fields(rows = input.poseidon2_events.len()))] fn generate_trace( &self, diff --git a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs index 19a3b6f287..0d5c666265 100644 --- a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs @@ -37,10 +37,6 @@ impl MachineAir for Poseidon2WideChip, const DEGREE: u #[derive(Debug, Clone, Copy, Default)] pub struct RecursionAirEventCount { - pub mem_const_events: usize, - pub mem_var_events: usize, - pub base_alu_events: usize, - pub ext_alu_events: usize, - pub poseidon2_wide_events: usize, - pub fri_fold_events: usize, - pub select_events: usize, - pub exp_reverse_bits_len_events: usize, + mem_const_events: usize, + mem_var_events: usize, + base_alu_events: usize, + ext_alu_events: usize, + poseidon2_wide_events: usize, + fri_fold_events: usize, + select_events: usize, + exp_reverse_bits_len_events: usize, } impl, const DEGREE: usize> RecursionAir { diff --git a/crates/recursion/core/src/runtime/memory.rs b/crates/recursion/core/src/runtime/memory.rs index d0b7f0f229..a82337b684 100644 --- a/crates/recursion/core/src/runtime/memory.rs +++ b/crates/recursion/core/src/runtime/memory.rs @@ -5,7 +5,7 @@ use vec_map::{Entry, VecMap}; use crate::{air::Block, Address}; -#[derive(Debug, Clone, Default, Copy)] +#[derive(Debug, Clone, Default)] pub struct MemoryEntry { pub val: Block, pub mult: F, diff --git a/crates/recursion/core/src/runtime/mod.rs b/crates/recursion/core/src/runtime/mod.rs index 63d6ce2643..f95ef87a14 100644 --- a/crates/recursion/core/src/runtime/mod.rs +++ b/crates/recursion/core/src/runtime/mod.rs @@ -8,7 +8,6 @@ mod record; use backtrace::Backtrace as Trace; pub use instruction::Instruction; use instruction::{FieldEltType, HintBitsInstr, HintExt2FeltsInstr, HintInstr, PrintInstr}; -use machine::RecursionAirEventCount; use memory::*; pub use opcode::*; pub use program::*; @@ -250,7 +249,6 @@ where pub fn run(&mut self) -> Result<(), RuntimeError> { let early_exit_ts = std::env::var("RECURSION_EARLY_EXIT_TS") .map_or(usize::MAX, |ts: String| ts.parse().unwrap()); - self.preallocate_record(); while self.pc < F::from_canonical_u32(self.program.instructions.len() as u32) { let idx = self.pc.as_canonical_u32() as usize; let instruction = self.program.instructions[idx].clone(); @@ -546,17 +544,4 @@ where } Ok(()) } - - pub fn preallocate_record(&mut self) { - let event_counts = self - .program - .instructions - .iter() - .fold(RecursionAirEventCount::default(), |heights, instruction| heights + instruction); - self.record.poseidon2_events.reserve(event_counts.poseidon2_wide_events); - self.record.mem_var_events.reserve(event_counts.mem_var_events); - self.record.base_alu_events.reserve(event_counts.base_alu_events); - self.record.ext_alu_events.reserve(event_counts.ext_alu_events); - self.record.exp_reverse_bits_len_events.reserve(event_counts.exp_reverse_bits_len_events); - } } From 465581f631e8693517452e8d3f467b59602dc063 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Tue, 29 Oct 2024 11:48:06 -0700 Subject: [PATCH 02/17] feat: remove assign in airs (#1710) --- .github/workflows/pr.yml | 2 - Cargo.lock | 96 ++++++++----------- Cargo.toml | 80 ++++++++-------- crates/core/machine/src/alu/divrem/mod.rs | 16 ++-- crates/core/machine/src/alu/lt/mod.rs | 6 +- crates/core/machine/src/alu/mul/mod.rs | 2 +- crates/core/machine/src/alu/sll/mod.rs | 7 +- crates/core/machine/src/alu/sr/mod.rs | 14 +-- crates/core/machine/src/cpu/air/ecall.rs | 10 +- crates/core/machine/src/cpu/air/memory.rs | 4 +- crates/core/machine/src/cpu/air/mod.rs | 25 +++-- crates/core/machine/src/lib.rs | 1 + crates/core/machine/src/memory/global.rs | 8 +- crates/core/machine/src/operations/add4.rs | 2 +- crates/core/machine/src/operations/add5.rs | 6 +- .../machine/src/operations/baby_bear_range.rs | 3 +- .../machine/src/operations/field/range.rs | 8 +- crates/core/machine/src/operations/lt.rs | 16 ++-- .../precompiles/sha256/compress/air.rs | 10 +- .../core/src/chips/poseidon2_skinny/mod.rs | 4 +- .../core/src/chips/poseidon2_wide/mod.rs | 4 +- crates/stark/src/air/builder.rs | 2 +- crates/stark/src/air/extension.rs | 5 +- crates/stark/src/air/polynomial.rs | 2 +- crates/stark/src/permutation.rs | 13 +-- 25 files changed, 166 insertions(+), 180 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 500033f728..bacc95b914 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -52,7 +52,6 @@ jobs: env: RUSTFLAGS: -Copt-level=3 -Cdebug-assertions -Coverflow-checks=y -Cdebuginfo=0 -C target-cpu=native RUST_BACKTRACE: 1 - # FRI_QUERIES: 1 SP1_DEV: 1 test-arm: @@ -89,7 +88,6 @@ jobs: env: RUSTFLAGS: -Copt-level=3 -Cdebug-assertions -Coverflow-checks=y -Cdebuginfo=0 -C target-cpu=native RUST_BACKTRACE: 1 - # FRI_QUERIES: 1 SP1_DEV: 1 lint: diff --git a/Cargo.lock b/Cargo.lock index 78c87ae95b..83bceecc46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4194,9 +4194,8 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "p3-air" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066f571b2e645505ed5972dd0e1e252ba03352150830c9566769ca711c0f1e9b" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -4204,9 +4203,8 @@ dependencies = [ [[package]] name = "p3-baby-bear" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff00f571044d299310d9659c6e51c98422de3bf94b8577f7f30cf59cf2043e40" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "num-bigint 0.4.6", "p3-field", @@ -4219,9 +4217,8 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4cb69ae54a279bbbd477566d1bdb71aa879b528fd658d0fcfc36f54b00217c" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "blake3", "p3-symmetric", @@ -4229,9 +4226,8 @@ dependencies = [ [[package]] name = "p3-bn254-fr" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf19917f986d45e9abb6d177e875824ced6eed096480d574fce16f2c45c721ea" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "ff 0.13.0", "num-bigint 0.4.6", @@ -4244,9 +4240,8 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be7e4fbce4566a93091107eadfafa0b5374bd1ffd3e0f6b850da3ff72eb183f" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -4258,13 +4253,11 @@ dependencies = [ [[package]] name = "p3-commit" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a03eb0f99d68a712c41e658e9a7782a0705d4ffcfb6232a43bd3f1ef9591002" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-challenger", - "p3-dft", "p3-field", "p3-matrix", "p3-util", @@ -4273,9 +4266,8 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1556de968523fbe5d804ab50600ea306fcceea3500cfd7601e40882480524664" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -4286,9 +4278,8 @@ dependencies = [ [[package]] name = "p3-field" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2af6e1ac47a2035af5165e668d64612c4b9ccabd06df37fc1fd381fdf8a71" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "num-bigint 0.4.6", @@ -4300,9 +4291,8 @@ dependencies = [ [[package]] name = "p3-fri" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f351ee9f9d4256455164565cd91e3e6d2487cc2a5355515fa2b6d479269188dd" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -4319,9 +4309,8 @@ dependencies = [ [[package]] name = "p3-interpolation" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24d0f2907a374ebe4545fcff3120d6376d9630cf0bef30feedcfc5908ea2c37" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -4330,9 +4319,8 @@ dependencies = [ [[package]] name = "p3-keccak-air" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e66badd47cedf6570e91a0cabc389b80dfd53ba1a6e9a45a3923fd54b86122ff" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-air", "p3-field", @@ -4344,9 +4332,8 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa272f3ae77ed8d73478aa7c89e712efb15bda3ff4aff10fadfe11a012cd5389" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-field", @@ -4359,18 +4346,16 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eecad6292021858f282d643d9d1284ab112a200494d589863a9c4080e578ef0" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "rayon", ] [[package]] name = "p3-mds" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716c4dbe68a02f1541eb09149d07b8663a3a5951b1864a31cd67ff3bb0826e57" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -4383,9 +4368,8 @@ dependencies = [ [[package]] name = "p3-merkle-tree" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad7ebab52a03c26025988663a135aed62f5084a2e2ea262176dc8748efb593e5" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -4400,9 +4384,8 @@ dependencies = [ [[package]] name = "p3-poseidon2" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c042efa15beab7a8c4d0ca9b9e4cbda7582be0c08e121e830fec45f082935b" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "gcd", "p3-field", @@ -4414,9 +4397,8 @@ dependencies = [ [[package]] name = "p3-symmetric" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9896a831f5b688adc13f6fbe1dcf66ecfaa4622a500f81aa745610e777acb72" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-field", @@ -4425,9 +4407,8 @@ dependencies = [ [[package]] name = "p3-uni-stark" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437ebcd060c8a5479898030b114a93da8a86eb4c2e5f313d9eeaaf40c6e6f61" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-air", @@ -4444,9 +4425,8 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dedb9d27ba47ac314c6fac4ca54e55c3e486c864d51ec5ba55dbe47b75121157" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "serde", ] diff --git a/Cargo.toml b/Cargo.toml index 8f971a139a..cc98876c1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,49 +71,49 @@ sp1-lib = { path = "crates/zkvm/lib", version = "3.0.0", default-features = fals sp1-zkvm = { path = "crates/zkvm/entrypoint", version = "3.0.1", default-features = false } # p3 -p3-air = "0.1.4-succinct" -p3-field = "0.1.4-succinct" -p3-commit = "0.1.4-succinct" -p3-matrix = "0.1.4-succinct" -p3-baby-bear = { version = "0.1.4-succinct", features = ["nightly-features"] } -p3-util = "0.1.4-succinct" -p3-challenger = "0.1.4-succinct" -p3-dft = "0.1.4-succinct" -p3-fri = "0.1.4-succinct" -p3-goldilocks = "0.1.4-succinct" -p3-keccak = "0.1.4-succinct" -p3-keccak-air = "0.1.4-succinct" -p3-blake3 = "0.1.4-succinct" -p3-mds = "0.1.4-succinct" -p3-merkle-tree = "0.1.4-succinct" -p3-poseidon2 = "0.1.4-succinct" -p3-symmetric = "0.1.4-succinct" -p3-uni-stark = "0.1.4-succinct" -p3-maybe-rayon = "0.1.4-succinct" -p3-bn254-fr = "0.1.4-succinct" +# p3-air = "0.1.4-succinct" +# p3-field = "0.1.4-succinct" +# p3-commit = "0.1.4-succinct" +# p3-matrix = "0.1.4-succinct" +# p3-baby-bear = { version = "0.1.4-succinct", features = ["nightly-features"] } +# p3-util = "0.1.4-succinct" +# p3-challenger = "0.1.4-succinct" +# p3-dft = "0.1.4-succinct" +# p3-fri = "0.1.4-succinct" +# p3-goldilocks = "0.1.4-succinct" +# p3-keccak = "0.1.4-succinct" +# p3-keccak-air = "0.1.4-succinct" +# p3-blake3 = "0.1.4-succinct" +# p3-mds = "0.1.4-succinct" +# p3-merkle-tree = "0.1.4-succinct" +# p3-poseidon2 = "0.1.4-succinct" +# p3-symmetric = "0.1.4-succinct" +# p3-uni-stark = "0.1.4-succinct" +# p3-maybe-rayon = "0.1.4-succinct" +# p3-bn254-fr = "0.1.4-succinct" # For local development. -# p3-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-field = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-commit = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-matrix = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-util = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-challenger = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-dft = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-fri = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-keccak = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-keccak-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-blake3 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-mds = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-symmetric = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-uni-stark = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } -# p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v3" } +p3-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-field = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-commit = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-matrix = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-util = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-challenger = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-dft = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-fri = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-keccak = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-keccak-air = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-blake3 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-mds = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-merkle-tree = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-poseidon2 = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-symmetric = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-uni-stark = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-maybe-rayon = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } +p3-bn254-fr = { git = "https://github.com/Plonky3/Plonky3", branch = "sp1-v4" } # p3-air = { path = "../Plonky3/air" } # p3-field = { path = "../Plonky3/field" } diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index d811b90d45..9170b87b5f 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -556,16 +556,20 @@ where // Add remainder. if i < WORD_SIZE { - c_times_quotient_plus_remainder[i] += local.remainder[i].into(); + c_times_quotient_plus_remainder[i] = + c_times_quotient_plus_remainder[i].clone() + local.remainder[i].into(); } else { // If rem is negative, add 0xff to the upper 4 bytes. - c_times_quotient_plus_remainder[i] += sign_extension.clone(); + c_times_quotient_plus_remainder[i] = + c_times_quotient_plus_remainder[i].clone() + sign_extension.clone(); } // Propagate carry. - c_times_quotient_plus_remainder[i] -= local.carry[i] * base; + c_times_quotient_plus_remainder[i] = + c_times_quotient_plus_remainder[i].clone() - local.carry[i] * base; if i > 0 { - c_times_quotient_plus_remainder[i] += local.carry[i - 1].into(); + c_times_quotient_plus_remainder[i] = + c_times_quotient_plus_remainder[i].clone() + local.carry[i - 1].into(); } } @@ -612,8 +616,8 @@ where let mut rem_byte_sum = zero.clone(); let mut b_byte_sum = zero.clone(); for i in 0..WORD_SIZE { - rem_byte_sum += local.remainder[i].into(); - b_byte_sum += local.b[i].into(); + rem_byte_sum = rem_byte_sum.clone() + local.remainder[i].into(); + b_byte_sum = b_byte_sum + local.b[i].into(); } // 1. If remainder < 0, then b < 0. diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index a9462b8def..211cf5d912 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -397,10 +397,10 @@ where { // Once the byte flag was set to one, we turn off the quality check flag. // We can do this by calculating the sum of the flags since only `1` is set to `1`. - is_inequality_visited += flag.into(); + is_inequality_visited = is_inequality_visited.clone() + flag.into(); - b_comparison_byte += b_byte.clone() * flag; - c_comparison_byte += c_byte.clone() * flag; + b_comparison_byte = b_comparison_byte.clone() + b_byte.clone() * flag; + c_comparison_byte = c_comparison_byte.clone() + c_byte.clone() * flag; // If inequality is not visited, assert that the bytes are equal. builder diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index a9a32cd5c4..0453cb5f87 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -356,7 +356,7 @@ where for i in 0..PRODUCT_SIZE { for j in 0..PRODUCT_SIZE { if i + j < PRODUCT_SIZE { - m[i + j] += b[i].clone() * c[j].clone(); + m[i + j] = m[i + j].clone() + b[i].clone() * c[j].clone(); } } } diff --git a/crates/core/machine/src/alu/sll/mod.rs b/crates/core/machine/src/alu/sll/mod.rs index 1b2f6cbd3d..af00dd47a5 100644 --- a/crates/core/machine/src/alu/sll/mod.rs +++ b/crates/core/machine/src/alu/sll/mod.rs @@ -290,7 +290,7 @@ where let mut c_byte_sum = zero.clone(); for i in 0..BYTE_SIZE { let val: AB::Expr = AB::F::from_canonical_u32(1 << i).into(); - c_byte_sum += val * local.c_least_sig_byte[i]; + c_byte_sum = c_byte_sum.clone() + val * local.c_least_sig_byte[i]; } builder.assert_eq(c_byte_sum, local.c[0]); @@ -300,7 +300,8 @@ where // 3 is the maximum number of bits necessary to represent num_bits_to_shift as // num_bits_to_shift is in [0, 7]. for i in 0..3 { - num_bits_to_shift += local.c_least_sig_byte[i] * AB::F::from_canonical_u32(1 << i); + num_bits_to_shift = num_bits_to_shift.clone() + + local.c_least_sig_byte[i] * AB::F::from_canonical_u32(1 << i); } for i in 0..BYTE_SIZE { builder @@ -321,7 +322,7 @@ where let mut v = local.b[i] * local.bit_shift_multiplier - local.bit_shift_result_carry[i] * base.clone(); if i > 0 { - v += local.bit_shift_result_carry[i - 1].into(); + v = v.clone() + local.bit_shift_result_carry[i - 1].into(); } builder.assert_eq(local.bit_shift_result[i], v); } diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index 84990a9c0b..9c19b4491c 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -373,7 +373,7 @@ where let mut c_byte_sum = AB::Expr::zero(); for i in 0..BYTE_SIZE { let val: AB::Expr = AB::F::from_canonical_u32(1 << i).into(); - c_byte_sum += val * local.c_least_sig_byte[i]; + c_byte_sum = c_byte_sum.clone() + val * local.c_least_sig_byte[i]; } builder.assert_eq(c_byte_sum, local.c[0]); @@ -383,7 +383,8 @@ where // of bits to shift. let mut num_bits_to_shift = AB::Expr::zero(); for i in 0..3 { - num_bits_to_shift += local.c_least_sig_byte[i] * AB::F::from_canonical_u32(1 << i); + num_bits_to_shift = num_bits_to_shift.clone() + + local.c_least_sig_byte[i] * AB::F::from_canonical_u32(1 << i); } for i in 0..BYTE_SIZE { builder @@ -444,15 +445,16 @@ where // The carry multiplier is 2^(8 - num_bits_to_shift). let mut carry_multiplier = AB::Expr::from_canonical_u8(0); for i in 0..BYTE_SIZE { - carry_multiplier += - AB::Expr::from_canonical_u32(1u32 << (8 - i)) * local.shift_by_n_bits[i]; + carry_multiplier = carry_multiplier.clone() + + AB::Expr::from_canonical_u32(1u32 << (8 - i)) * local.shift_by_n_bits[i]; } // The 3-bit number represented by the 3 least significant bits of c equals the number // of bits to shift. let mut num_bits_to_shift = AB::Expr::zero(); for i in 0..3 { - num_bits_to_shift += local.c_least_sig_byte[i] * AB::F::from_canonical_u32(1 << i); + num_bits_to_shift = num_bits_to_shift.clone() + + local.c_least_sig_byte[i] * AB::F::from_canonical_u32(1 << i); } // Calculate ShrCarry. @@ -471,7 +473,7 @@ where for i in (0..LONG_WORD_SIZE).rev() { let mut v: AB::Expr = local.shr_carry_output_shifted_byte[i].into(); if i + 1 < LONG_WORD_SIZE { - v += local.shr_carry_output_carry[i + 1] * carry_multiplier.clone(); + v = v.clone() + local.shr_carry_output_carry[i + 1] * carry_multiplier.clone(); } builder.assert_eq(v, local.bit_shift_result[i]); } diff --git a/crates/core/machine/src/cpu/air/ecall.rs b/crates/core/machine/src/cpu/air/ecall.rs index 9c05105bcc..59785123fb 100644 --- a/crates/core/machine/src/cpu/air/ecall.rs +++ b/crates/core/machine/src/cpu/air/ecall.rs @@ -118,8 +118,8 @@ impl CpuChip { &self, builder: &mut AB, local: &CpuCols, - commit_digest: [Word; PV_DIGEST_NUM_WORDS], - deferred_proofs_digest: [AB::Expr; POSEIDON_NUM_WORDS], + commit_digest: [Word; PV_DIGEST_NUM_WORDS], + deferred_proofs_digest: [AB::PublicVar; POSEIDON_NUM_WORDS], ) { let (is_commit, is_commit_deferred_proofs) = self.get_is_commit_related_syscall(builder, local); @@ -132,7 +132,7 @@ impl CpuChip { // They should all be bools. for bit in ecall_columns.index_bitmap.iter() { builder.when(local.selectors.is_ecall).assert_bool(*bit); - bitmap_sum += (*bit).into(); + bitmap_sum = bitmap_sum.clone() + (*bit).into(); } // When the syscall is COMMIT or COMMIT_DEFERRED_PROOFS, there should be one set bit. builder @@ -199,7 +199,7 @@ impl CpuChip { builder: &mut AB, local: &CpuCols, next: &CpuCols, - public_values: &PublicValues, AB::Expr>, + public_values: &PublicValues, AB::PublicVar>, ) { let is_halt = self.get_is_halt_syscall(builder, local); @@ -219,7 +219,7 @@ impl CpuChip { builder .when(is_halt.clone()) - .assert_eq(local.op_b_access.value().reduce::(), public_values.exit_code.clone()); + .assert_eq(local.op_b_access.value().reduce::(), public_values.exit_code); } /// Returns a boolean expression indicating whether the instruction is a HALT instruction. diff --git a/crates/core/machine/src/cpu/air/memory.rs b/crates/core/machine/src/cpu/air/memory.rs index 7269334a6d..79054d1abf 100644 --- a/crates/core/machine/src/cpu/air/memory.rs +++ b/crates/core/machine/src/cpu/air/memory.rs @@ -327,8 +327,8 @@ impl CpuChip { let mut recomposed_byte = AB::Expr::zero(); for i in 0..8 { builder.when(is_mem.clone()).assert_bool(memory_columns.most_sig_byte_decomp[i]); - recomposed_byte += - memory_columns.most_sig_byte_decomp[i] * AB::Expr::from_canonical_u8(1 << i); + recomposed_byte = recomposed_byte.clone() + + memory_columns.most_sig_byte_decomp[i] * AB::Expr::from_canonical_u8(1 << i); } builder.when(local.selectors.is_lb).assert_eq(recomposed_byte.clone(), unsigned_mem_val[0]); builder.when(local.selectors.is_lh).assert_eq(recomposed_byte, unsigned_mem_val[1]); diff --git a/crates/core/machine/src/cpu/air/mod.rs b/crates/core/machine/src/cpu/air/mod.rs index 5ab408ce95..35b6dc18af 100644 --- a/crates/core/machine/src/cpu/air/mod.rs +++ b/crates/core/machine/src/cpu/air/mod.rs @@ -36,10 +36,6 @@ where let (local, next) = (main.row_slice(0), main.row_slice(1)); let local: &CpuCols = (*local).borrow(); let next: &CpuCols = (*next).borrow(); - let public_values_slice: [AB::Expr; SP1_PROOF_NUM_PV_ELTS] = - core::array::from_fn(|i| builder.public_values()[i].into()); - let public_values: &PublicValues, AB::Expr> = - public_values_slice.as_slice().borrow(); // Program constraints. builder.send_program( @@ -87,11 +83,15 @@ where self.eval_ecall(builder, local); // COMMIT/COMMIT_DEFERRED_PROOFS ecall instruction. + let public_values_slice: [AB::PublicVar; SP1_PROOF_NUM_PV_ELTS] = + core::array::from_fn(|i| builder.public_values()[i]); + let public_values: &PublicValues, AB::PublicVar> = + public_values_slice.as_slice().borrow(); self.eval_commit( builder, local, - public_values.committed_value_digest.clone(), - public_values.deferred_proofs_digest.clone(), + public_values.committed_value_digest, + public_values.deferred_proofs_digest, ); // HALT ecall and UNIMPL instruction. @@ -335,13 +335,13 @@ impl CpuChip { builder: &mut AB, local: &CpuCols, next: &CpuCols, - public_values: &PublicValues, AB::Expr>, + public_values: &PublicValues, AB::PublicVar>, ) { // Verify the public value's shard. - builder.when(local.is_real).assert_eq(public_values.execution_shard.clone(), local.shard); + builder.when(local.is_real).assert_eq(public_values.execution_shard, local.shard); // Verify the public value's start pc. - builder.when_first_row().assert_eq(public_values.start_pc.clone(), local.pc); + builder.when_first_row().assert_eq(public_values.start_pc, local.pc); // Verify the public value's next pc. We need to handle two cases: // 1. The last real row is a transition row. @@ -351,13 +351,10 @@ impl CpuChip { builder .when_transition() .when(local.is_real - next.is_real) - .assert_eq(public_values.next_pc.clone(), local.next_pc); + .assert_eq(public_values.next_pc, local.next_pc); // If the last real row is the last row, verify the public value's next pc. - builder - .when_last_row() - .when(local.is_real) - .assert_eq(public_values.next_pc.clone(), local.next_pc); + builder.when_last_row().when(local.is_real).assert_eq(public_values.next_pc, local.next_pc); } /// Constraints related to the is_real column. diff --git a/crates/core/machine/src/lib.rs b/crates/core/machine/src/lib.rs index 16fd571c95..168be94eac 100644 --- a/crates/core/machine/src/lib.rs +++ b/crates/core/machine/src/lib.rs @@ -8,6 +8,7 @@ clippy::unnecessary_unwrap, clippy::default_constructed_unit_structs, clippy::box_default, + clippy::assign_op_pattern, deprecated, incomplete_features )] diff --git a/crates/core/machine/src/memory/global.rs b/crates/core/machine/src/memory/global.rs index 2630759b48..db58e9c351 100644 --- a/crates/core/machine/src/memory/global.rs +++ b/crates/core/machine/src/memory/global.rs @@ -208,10 +208,10 @@ where let mut byte3 = AB::Expr::zero(); let mut byte4 = AB::Expr::zero(); for i in 0..8 { - byte1 += local.value[i].into() * AB::F::from_canonical_u8(1 << i); - byte2 += local.value[i + 8].into() * AB::F::from_canonical_u8(1 << i); - byte3 += local.value[i + 16].into() * AB::F::from_canonical_u8(1 << i); - byte4 += local.value[i + 24].into() * AB::F::from_canonical_u8(1 << i); + byte1 = byte1.clone() + local.value[i].into() * AB::F::from_canonical_u8(1 << i); + byte2 = byte2.clone() + local.value[i + 8].into() * AB::F::from_canonical_u8(1 << i); + byte3 = byte3.clone() + local.value[i + 16].into() * AB::F::from_canonical_u8(1 << i); + byte4 = byte4.clone() + local.value[i + 24].into() * AB::F::from_canonical_u8(1 << i); } let value = [byte1, byte2, byte3, byte4]; diff --git a/crates/core/machine/src/operations/add4.rs b/crates/core/machine/src/operations/add4.rs index fc010e9ab1..121acbf767 100644 --- a/crates/core/machine/src/operations/add4.rs +++ b/crates/core/machine/src/operations/add4.rs @@ -141,7 +141,7 @@ impl Add4Operation { for i in 0..WORD_SIZE { let mut overflow = a[i] + b[i] + c[i] + d[i] - cols.value[i]; if i > 0 { - overflow += cols.carry[i - 1].into(); + overflow = overflow.clone() + cols.carry[i - 1].into(); } builder_is_real.assert_eq(cols.carry[i] * base, overflow.clone()); } diff --git a/crates/core/machine/src/operations/add5.rs b/crates/core/machine/src/operations/add5.rs index dcd011f7f8..14d8dae259 100644 --- a/crates/core/machine/src/operations/add5.rs +++ b/crates/core/machine/src/operations/add5.rs @@ -147,12 +147,12 @@ impl Add5Operation { for i in 0..WORD_SIZE { let mut overflow: AB::Expr = AB::F::zero().into(); for word in words { - overflow += word[i].into(); + overflow = overflow.clone() + word[i].into(); } - overflow -= cols.value[i].into(); + overflow = overflow.clone() - cols.value[i].into(); if i > 0 { - overflow += cols.carry[i - 1].into(); + overflow = overflow.clone() + cols.carry[i - 1].into(); } builder_is_real.assert_eq(cols.carry[i] * base, overflow.clone()); } diff --git a/crates/core/machine/src/operations/baby_bear_range.rs b/crates/core/machine/src/operations/baby_bear_range.rs index 17674b6491..e6c8bdde5a 100644 --- a/crates/core/machine/src/operations/baby_bear_range.rs +++ b/crates/core/machine/src/operations/baby_bear_range.rs @@ -41,7 +41,8 @@ impl BabyBearBitDecomposition { let mut reconstructed_value = AB::Expr::zero(); for (i, bit) in cols.bits.iter().enumerate() { builder.when(is_real.clone()).assert_bool(*bit); - reconstructed_value += AB::Expr::from_wrapped_u32(1 << i) * *bit; + reconstructed_value = + reconstructed_value.clone() + AB::Expr::from_wrapped_u32(1 << i) * *bit; } // Assert that bits2num(bits) == value. diff --git a/crates/core/machine/src/operations/field/range.rs b/crates/core/machine/src/operations/field/range.rs index b7490c584b..73a108e775 100644 --- a/crates/core/machine/src/operations/field/range.rs +++ b/crates/core/machine/src/operations/field/range.rs @@ -98,7 +98,7 @@ impl FieldLtCols { // Assert that the flag is boolean. builder.when(is_real.clone()).assert_bool(flag); // Add the flag to the sum. - sum_flags += flag.into(); + sum_flags = sum_flags.clone() + flag.into(); } // Assert that the sum is equal to one. builder.when(is_real.clone()).assert_one(sum_flags); @@ -121,10 +121,10 @@ impl FieldLtCols { ) { // Once the byte flag was set to one, we turn off the quality check flag. // We can do this by calculating the sum of the flags since only `1` is set to `1`. - is_inequality_visited += flag.into(); + is_inequality_visited = is_inequality_visited.clone() + flag.into(); - lhs_comparison_byte += lhs_byte.clone() * flag; - rhs_comparison_byte += flag.into() * rhs_byte.clone(); + lhs_comparison_byte = lhs_comparison_byte.clone() + lhs_byte.clone() * flag; + rhs_comparison_byte = rhs_comparison_byte.clone() + flag.into() * rhs_byte.clone(); builder .when(is_real.clone()) diff --git a/crates/core/machine/src/operations/lt.rs b/crates/core/machine/src/operations/lt.rs index 5d9f000983..ae6c4c2bf4 100644 --- a/crates/core/machine/src/operations/lt.rs +++ b/crates/core/machine/src/operations/lt.rs @@ -81,7 +81,7 @@ impl AssertLtColsBytes { // Assert that the flag is boolean. builder.assert_bool(flag); // Add the flag to the sum. - sum_flags += flag.into(); + sum_flags = sum_flags.clone() + flag.into(); } // Assert that the sum is equal to one. builder.when(is_real.clone()).assert_one(sum_flags); @@ -104,10 +104,10 @@ impl AssertLtColsBytes { { // Once the byte flag was set to one, we turn off the quality check flag. // We can do this by calculating the sum of the flags since only `1` is set to `1`. - is_inequality_visited += flag.into(); + is_inequality_visited = is_inequality_visited.clone() + flag.into(); - first_lt_byte += a_byte.clone() * flag; - b_comparison_byte += b_byte.clone() * flag; + first_lt_byte = first_lt_byte.clone() + a_byte.clone() * flag; + b_comparison_byte = b_comparison_byte.clone() + b_byte.clone() * flag; builder .when_not(is_inequality_visited.clone()) @@ -189,7 +189,7 @@ impl AssertLtColsBits { // Assert that the flag is boolean. builder.assert_bool(flag); // Add the flag to the sum. - sum_flags += flag.into(); + sum_flags = sum_flags.clone() + flag.into(); } // Assert that the sum is equal to one. builder.when(is_real.clone()).assert_one(sum_flags); @@ -212,10 +212,10 @@ impl AssertLtColsBits { { // Once the bit flag was set to one, we turn off the quality check flag. // We can do this by calculating the sum of the flags since only `1` is set to `1`. - is_inequality_visited += flag.into(); + is_inequality_visited = is_inequality_visited.clone() + flag.into(); - a_comparison_bit += a_bit.clone() * flag; - b_comparison_bit += b_bit.clone() * flag; + a_comparison_bit = a_comparison_bit.clone() + a_bit.clone() * flag; + b_comparison_bit = b_comparison_bit.clone() + b_bit.clone() * flag; builder .when(is_real.clone()) diff --git a/crates/core/machine/src/syscall/precompiles/sha256/compress/air.rs b/crates/core/machine/src/syscall/precompiles/sha256/compress/air.rs index 648f9cdd34..2ecb8deb37 100644 --- a/crates/core/machine/src/syscall/precompiles/sha256/compress/air.rs +++ b/crates/core/machine/src/syscall/precompiles/sha256/compress/air.rs @@ -80,7 +80,7 @@ impl ShaCompressChip { // Verify that exactly one of the octet columns is true. let mut octet_sum = AB::Expr::zero(); for i in 0..8 { - octet_sum += local.octet[i].into(); + octet_sum = octet_sum.clone() + local.octet[i].into(); } builder.assert_one(octet_sum); @@ -100,7 +100,7 @@ impl ShaCompressChip { // Verify that exactly one of the octet_num columns is true. let mut octet_num_sum = AB::Expr::zero(); for i in 0..10 { - octet_num_sum += local.octet_num[i].into(); + octet_num_sum = octet_num_sum.clone() + local.octet_num[i].into(); } builder.assert_one(octet_num_sum); @@ -217,13 +217,13 @@ impl ShaCompressChip { // Calculate the current cycle_num. let mut cycle_num = AB::Expr::zero(); for i in 0..10 { - cycle_num += local.octet_num[i] * AB::Expr::from_canonical_usize(i); + cycle_num = cycle_num.clone() + local.octet_num[i] * AB::Expr::from_canonical_usize(i); } // Calculate the current step of the cycle 8. let mut cycle_step = AB::Expr::zero(); for i in 0..8 { - cycle_step += local.octet[i] * AB::Expr::from_canonical_usize(i); + cycle_step = cycle_step.clone() + local.octet[i] * AB::Expr::from_canonical_usize(i); } // Verify correct mem address for initialize phase @@ -490,7 +490,7 @@ impl ShaCompressChip { let mut filtered_operand = Word([zero.clone(), zero.clone(), zero.clone(), zero]); for (i, operand) in local.octet.iter().zip(add_operands.iter()) { for j in 0..4 { - filtered_operand.0[j] += *i * operand.0[j]; + filtered_operand.0[j] = filtered_operand.0[j].clone() + *i * operand.0[j]; } } diff --git a/crates/recursion/core/src/chips/poseidon2_skinny/mod.rs b/crates/recursion/core/src/chips/poseidon2_skinny/mod.rs index 637c00f3f9..ff3c7b32ce 100644 --- a/crates/recursion/core/src/chips/poseidon2_skinny/mod.rs +++ b/crates/recursion/core/src/chips/poseidon2_skinny/mod.rs @@ -52,7 +52,7 @@ pub(crate) fn external_linear_layer(state: &mut [AF; WIDTH]) core::array::from_fn(|k| (0..WIDTH).step_by(4).map(|j| state[j + k].clone()).sum::()); for j in 0..WIDTH { - state[j] += sums[j % 4].clone(); + state[j] = state[j].clone() + sums[j % 4].clone(); } } @@ -66,7 +66,7 @@ pub(crate) fn internal_linear_layer(state: &mut [F; WIDTH]) { .unwrap(); matmul_internal(state, matmul_constants); let monty_inverse = F::from_wrapped_u32(MONTY_INVERSE.as_canonical_u32()); - state.iter_mut().for_each(|i| *i *= monty_inverse.clone()); + state.iter_mut().for_each(|i| *i = i.clone() * monty_inverse.clone()); } #[cfg(test)] diff --git a/crates/recursion/core/src/chips/poseidon2_wide/mod.rs b/crates/recursion/core/src/chips/poseidon2_wide/mod.rs index 637c5afca9..266231b230 100644 --- a/crates/recursion/core/src/chips/poseidon2_wide/mod.rs +++ b/crates/recursion/core/src/chips/poseidon2_wide/mod.rs @@ -67,7 +67,7 @@ pub(crate) fn external_linear_layer(state: &mut [AF; WIDTH]) core::array::from_fn(|k| (0..WIDTH).step_by(4).map(|j| state[j + k].clone()).sum::()); for j in 0..WIDTH { - state[j] += sums[j % 4].clone(); + state[j] = state[j].clone() + sums[j % 4].clone(); } } @@ -89,7 +89,7 @@ pub(crate) fn internal_linear_layer(state: &mut [F; WIDTH]) { .unwrap(); matmul_internal(state, matmul_constants); let monty_inverse = F::from_wrapped_u32(MONTY_INVERSE.as_canonical_u32()); - state.iter_mut().for_each(|i| *i *= monty_inverse.clone()); + state.iter_mut().for_each(|i| *i = i.clone() * monty_inverse.clone()); } #[cfg(test)] diff --git a/crates/stark/src/air/builder.rs b/crates/stark/src/air/builder.rs index c64f1677cd..dc89f80d2e 100644 --- a/crates/stark/src/air/builder.rs +++ b/crates/stark/src/air/builder.rs @@ -97,7 +97,7 @@ pub trait BaseAirBuilder: AirBuilder + MessageBuilder let mut result = Self::Expr::zero(); for (value, i) in array.iter().zip_eq(index_bitmap) { - result += value.clone().into() * i.clone().into(); + result = result.clone() + value.clone().into() * i.clone().into(); } result diff --git a/crates/stark/src/air/extension.rs b/crates/stark/src/air/extension.rs index 0f810a026d..a986f0f06b 100644 --- a/crates/stark/src/air/extension.rs +++ b/crates/stark/src/air/extension.rs @@ -62,9 +62,10 @@ impl + Mul + AbstractField> Mul for BinomialExten for i in 0..D { for j in 0..D { if i + j >= D { - result[i + j - D] += w.clone() * self.0[i].clone() * rhs.0[j].clone(); + result[i + j - D] = result[i + j - D].clone() + + w.clone() * self.0[i].clone() * rhs.0[j].clone(); } else { - result[i + j] += self.0[i].clone() * rhs.0[j].clone(); + result[i + j] = result[i + j].clone() + self.0[i].clone() * rhs.0[j].clone(); } } } diff --git a/crates/stark/src/air/polynomial.rs b/crates/stark/src/air/polynomial.rs index 40f5fdbe84..e89ec78e03 100644 --- a/crates/stark/src/air/polynomial.rs +++ b/crates/stark/src/air/polynomial.rs @@ -126,7 +126,7 @@ impl + Add + AddAssign + Clone> Add for Polyno fn add(self, other: T) -> Polynomial { let mut coefficients = self.coefficients; - coefficients[0] += other; + coefficients[0] = coefficients[0].clone() + other; Self::new(coefficients) } } diff --git a/crates/stark/src/permutation.rs b/crates/stark/src/permutation.rs index 98c1555b93..1d0fa11574 100644 --- a/crates/stark/src/permutation.rs +++ b/crates/stark/src/permutation.rs @@ -335,11 +335,12 @@ pub fn eval_permutation_constraints<'a, F, AB>( let mut rlc = alpha.clone(); let mut betas = beta.powers(); - rlc += betas.next().unwrap() - * AB::ExprEF::from_canonical_usize(interaction.argument_index()); + rlc = rlc.clone() + + betas.next().unwrap() + * AB::ExprEF::from_canonical_usize(interaction.argument_index()); for (field, beta) in interaction.values.iter().zip(betas.clone()) { let elem = field.apply::(&preprocessed_local, main_local); - rlc += beta * elem; + rlc = rlc.clone() + beta * elem; } rlcs.push(rlc); @@ -357,16 +358,16 @@ pub fn eval_permutation_constraints<'a, F, AB>( let mut numerator = AB::ExprEF::zero(); for (i, (m, rlc)) in multiplicities.into_iter().zip(rlcs.iter()).enumerate() { // Calculate the running product of all rlcs. - product *= rlc.clone(); + product = product.clone() * rlc.clone(); // Calculate the product of all but the current rlc. let mut all_but_current = AB::ExprEF::one(); for other_rlc in rlcs.iter().enumerate().filter(|(j, _)| i != *j).map(|(_, rlc)| rlc) { - all_but_current *= other_rlc.clone(); + all_but_current = all_but_current.clone() * other_rlc.clone(); } - numerator += AB::ExprEF::from_base(m) * all_but_current; + numerator = numerator.clone() + AB::ExprEF::from_base(m) * all_but_current; } // Finally, assert that the entry is equal to the numerator divided by the product. From d13675665bff079b6da4f115cb322eadca6bb50e Mon Sep 17 00:00:00 2001 From: Yuwen Zhang Date: Tue, 29 Oct 2024 18:34:34 -0700 Subject: [PATCH 03/17] feat: new crate for no-std groth/plonk verification (#1685) --- .github/actions/setup/action.yml | 2 + .github/workflows/pr.yml | 22 + .gitignore | 4 + Cargo.lock | 76 +- Cargo.toml | 1 + crates/prover/release.sh | 4 + crates/sdk/src/lib.rs | 12 +- crates/sdk/src/proof.rs | 44 +- crates/verifier/Cargo.toml | 26 + crates/verifier/README.md | 37 + crates/verifier/bn254-vk/groth16_vk.bin | Bin 0 -> 396 bytes crates/verifier/bn254-vk/plonk_vk.bin | Bin 0 -> 34368 bytes crates/verifier/src/constants.rs | 33 + crates/verifier/src/converter.rs | 122 + crates/verifier/src/error.rs | 63 + crates/verifier/src/groth16/converter.rs | 53 + crates/verifier/src/groth16/error.rs | 17 + crates/verifier/src/groth16/mod.rs | 66 + crates/verifier/src/groth16/verify.rs | 66 + crates/verifier/src/lib.rs | 32 + crates/verifier/src/plonk/converter.rs | 176 + crates/verifier/src/plonk/error.rs | 49 + crates/verifier/src/plonk/hash_to_field.rs | 118 + crates/verifier/src/plonk/kzg.rs | 193 + crates/verifier/src/plonk/mod.rs | 75 + crates/verifier/src/plonk/proof.rs | 13 + crates/verifier/src/plonk/transcript.rs | 103 + crates/verifier/src/plonk/verify.rs | 404 + crates/verifier/src/tests.rs | 62 + crates/verifier/src/utils.rs | 29 + .../test_binaries/fibonacci-groth16.bin | Bin 0 -> 1449 bytes .../test_binaries/fibonacci-plonk.bin | Bin 0 -> 3825 bytes examples/Cargo.lock | 8381 +++++++++++++++++ examples/Cargo.toml | 2 + examples/fibonacci/script/Cargo.toml | 4 + .../fibonacci/script/bin/groth16_bn254.rs | 10 +- examples/fibonacci/script/bin/plonk_bn254.rs | 40 + examples/groth16/program/Cargo.toml | 9 + examples/groth16/program/src/main.rs | 31 + examples/groth16/script/Cargo.toml | 15 + examples/groth16/script/build.rs | 4 + examples/groth16/script/src/main.rs | 50 + examples/riscv32im-succinct-zkvm-elf | Bin 0 -> 105028 bytes 43 files changed, 10416 insertions(+), 32 deletions(-) create mode 100644 crates/verifier/Cargo.toml create mode 100644 crates/verifier/README.md create mode 100644 crates/verifier/bn254-vk/groth16_vk.bin create mode 100644 crates/verifier/bn254-vk/plonk_vk.bin create mode 100644 crates/verifier/src/constants.rs create mode 100644 crates/verifier/src/converter.rs create mode 100644 crates/verifier/src/error.rs create mode 100644 crates/verifier/src/groth16/converter.rs create mode 100644 crates/verifier/src/groth16/error.rs create mode 100644 crates/verifier/src/groth16/mod.rs create mode 100644 crates/verifier/src/groth16/verify.rs create mode 100644 crates/verifier/src/lib.rs create mode 100644 crates/verifier/src/plonk/converter.rs create mode 100644 crates/verifier/src/plonk/error.rs create mode 100644 crates/verifier/src/plonk/hash_to_field.rs create mode 100644 crates/verifier/src/plonk/kzg.rs create mode 100644 crates/verifier/src/plonk/mod.rs create mode 100644 crates/verifier/src/plonk/proof.rs create mode 100644 crates/verifier/src/plonk/transcript.rs create mode 100644 crates/verifier/src/plonk/verify.rs create mode 100644 crates/verifier/src/tests.rs create mode 100644 crates/verifier/src/utils.rs create mode 100644 crates/verifier/test_binaries/fibonacci-groth16.bin create mode 100644 crates/verifier/test_binaries/fibonacci-plonk.bin create mode 100644 examples/Cargo.lock create mode 100644 examples/fibonacci/script/bin/plonk_bn254.rs create mode 100644 examples/groth16/program/Cargo.toml create mode 100644 examples/groth16/program/src/main.rs create mode 100644 examples/groth16/script/Cargo.toml create mode 100644 examples/groth16/script/build.rs create mode 100644 examples/groth16/script/src/main.rs create mode 100755 examples/riscv32im-succinct-zkvm-elf diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 57d1afc515..d12a1d16aa 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -75,6 +75,8 @@ runs: ~/.cargo/git/db/ target/ ~/.rustup/ + ~/.sp1/circuits/plonk/ + ~/.sp1/circuits/groth16/ key: rust-1.81.0-${{ hashFiles('**/Cargo.toml') }} restore-keys: rust-1.81.0- diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index bacc95b914..41b37ae3db 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -402,3 +402,25 @@ jobs: - uses: getsentry/action-git-diff-suggestions@main with: message: typos + + check-verifier-no-std: + name: Check Verifier `no_std` + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + fail-fast: false + steps: + - name: Checkout Actions Repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: riscv32imac-unknown-none-elf + + - name: Install target support + run: rustup target add riscv32imac-unknown-none-elf + + - name: Check build + run: cargo check --target riscv32imac-unknown-none-elf --no-default-features -p sp1-verifier + \ No newline at end of file diff --git a/.gitignore b/.gitignore index 969693532c..a03b205b74 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,10 @@ pgo-data.profdata **/program.bin **/stdin.bin +# Example fibonacci groth16 / plonk proofs +examples/fibonacci/fibonacci-groth16.bin +examples/fibonacci/fibonacci-plonk.bin + # Benchmark benchmark.csv diff --git a/Cargo.lock b/Cargo.lock index 83bceecc46..22a73f10b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1240,6 +1240,20 @@ name = "bytemuck" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] [[package]] name = "byteorder" @@ -6286,6 +6300,16 @@ dependencies = [ "serde", ] +[[package]] +name = "sp1-lib" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c372b16988e765af85ccf958b18b26d89c05886f2592d313a285415dcc769cb" +dependencies = [ + "bincode", + "serde", +] + [[package]] name = "sp1-perf" version = "3.0.0" @@ -6581,6 +6605,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "sp1-verifier" +version = "3.0.0" +dependencies = [ + "hex", + "lazy_static", + "num-bigint 0.4.6", + "num-traits", + "sha2 0.10.8", + "sp1-sdk", + "substrate-bn", + "thiserror-no-std", +] + [[package]] name = "sp1-zkvm" version = "3.0.1" @@ -6593,7 +6631,7 @@ dependencies = [ "p3-field", "rand 0.8.5", "sha2 0.10.8", - "sp1-lib", + "sp1-lib 3.0.0", "sp1-primitives", ] @@ -6726,6 +6764,22 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "substrate-bn" +version = "0.6.0" +source = "git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2#a1974dba1f3b75c16b48a84037edc12b36bba1cf" +dependencies = [ + "bytemuck", + "byteorder", + "cfg-if", + "crunchy", + "lazy_static", + "num-bigint 0.4.6", + "rand 0.8.5", + "rustc-hex", + "sp1-lib 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "subtle" version = "2.6.1" @@ -6949,6 +7003,26 @@ dependencies = [ "syn 2.0.79", ] +[[package]] +name = "thiserror-impl-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "thiserror-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +dependencies = [ + "thiserror-impl-no-std", +] + [[package]] name = "thread_local" version = "1.1.8" diff --git a/Cargo.toml b/Cargo.toml index cc98876c1e..c557828e67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ members = [ "crates/recursion/gnark-ffi", "crates/sdk", "crates/cuda", + "crates/verifier", "crates/stark", "crates/zkvm/*", ] diff --git a/crates/prover/release.sh b/crates/prover/release.sh index 005a2b6456..41013e1fcf 100644 --- a/crates/prover/release.sh +++ b/crates/prover/release.sh @@ -76,6 +76,10 @@ if [ $? -ne 0 ]; then exit 1 fi +# Copy Groth16 and Plonk vks to verifier crate +cp ./build/groth16/$VERSION/groth16_vk.bin ../verifier/bn254-vk/groth16_vk.bin +cp ./build/plonk/$VERSION/plonk_vk.bin ../verifier/bn254-vk/plonk_vk.bin + echo "Successfully uploaded build artifacts to S3:" echo "- s3://$S3_BUCKET/$GROTH16_ARCHIVE" echo "- s3://$S3_BUCKET/$PLONK_ARCHIVE" diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 68bc0ba459..ac97f2e47c 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -359,8 +359,7 @@ mod tests { fn test_e2e_core() { utils::setup_logger(); let client = ProverClient::local(); - let elf = - include_bytes!("../../../examples/fibonacci/program/elf/riscv32im-succinct-zkvm-elf"); + let elf = include_bytes!("../../../tests/fibonacci/elf/riscv32im-succinct-zkvm-elf"); let (pk, vk) = client.setup(elf); let mut stdin = SP1Stdin::new(); stdin.write(&10usize); @@ -380,8 +379,7 @@ mod tests { fn test_e2e_compressed() { utils::setup_logger(); let client = ProverClient::local(); - let elf = - include_bytes!("../../../examples/fibonacci/program/elf/riscv32im-succinct-zkvm-elf"); + let elf = include_bytes!("../../../tests/fibonacci/elf/riscv32im-succinct-zkvm-elf"); let (pk, vk) = client.setup(elf); let mut stdin = SP1Stdin::new(); stdin.write(&10usize); @@ -401,8 +399,7 @@ mod tests { fn test_e2e_prove_plonk() { utils::setup_logger(); let client = ProverClient::local(); - let elf = - include_bytes!("../../../examples/fibonacci/program/elf/riscv32im-succinct-zkvm-elf"); + let elf = include_bytes!("../../../tests/fibonacci/elf/riscv32im-succinct-zkvm-elf"); let (pk, vk) = client.setup(elf); let mut stdin = SP1Stdin::new(); stdin.write(&10usize); @@ -422,8 +419,7 @@ mod tests { fn test_e2e_prove_plonk_mock() { utils::setup_logger(); let client = ProverClient::mock(); - let elf = - include_bytes!("../../../examples/fibonacci/program/elf/riscv32im-succinct-zkvm-elf"); + let elf = include_bytes!("../../../tests/fibonacci/elf/riscv32im-succinct-zkvm-elf"); let (pk, vk) = client.setup(elf); let mut stdin = SP1Stdin::new(); stdin.write(&10usize); diff --git a/crates/sdk/src/proof.rs b/crates/sdk/src/proof.rs index 9a39f333e8..86bd723e50 100644 --- a/crates/sdk/src/proof.rs +++ b/crates/sdk/src/proof.rs @@ -53,9 +53,27 @@ impl SP1ProofWithPublicValues { } } + /// Returns the *raw* proof as bytes, prepended with the first 4 bytes of the vkey hash. + /// + /// This is the format expected by the `sp1-verifier` crate. The extra 4 bytes are used to + /// ensure that the proof will eventually be verified by the correct vkey. + pub fn raw_with_checksum(&self) -> Vec { + match &self.proof { + SP1Proof::Plonk(plonk) => { + let proof_bytes = hex::decode(&plonk.raw_proof).expect("Invalid Plonk proof"); + [plonk.plonk_vkey_hash[..4].to_vec(), proof_bytes].concat() + } + SP1Proof::Groth16(groth16) => { + let proof_bytes = hex::decode(&groth16.raw_proof).expect("Invalid Groth16 proof"); + [groth16.groth16_vkey_hash[..4].to_vec(), proof_bytes].concat() + } + _ => unimplemented!(), + } + } + /// For Plonk or Groth16 proofs, returns the proof in a byte encoding the onchain verifier /// accepts. The bytes consist of the first four bytes of Plonk vkey hash followed by the - /// encoded proof. + /// *encoded* proof. pub fn bytes(&self) -> Vec { match &self.proof { SP1Proof::Plonk(plonk_proof) => { @@ -65,26 +83,14 @@ impl SP1ProofWithPublicValues { return Vec::new(); } - let mut bytes = Vec::with_capacity(4 + plonk_proof.encoded_proof.len()); - bytes.extend_from_slice(&plonk_proof.plonk_vkey_hash[..4]); - bytes.extend_from_slice( - &hex::decode(&plonk_proof.encoded_proof).expect("Invalid Plonk proof"), - ); - bytes + let proof_bytes = + hex::decode(&plonk_proof.encoded_proof).expect("Invalid Plonk proof"); + [plonk_proof.plonk_vkey_hash[..4].to_vec(), proof_bytes].concat() } SP1Proof::Groth16(groth16_proof) => { - if groth16_proof.encoded_proof.is_empty() { - // If the proof is empty, then this is a mock proof. The mock SP1 verifier - // expects an empty byte array for verification, so return an empty byte array. - return Vec::new(); - } - - let mut bytes = Vec::with_capacity(4 + groth16_proof.encoded_proof.len()); - bytes.extend_from_slice(&groth16_proof.groth16_vkey_hash[..4]); - bytes.extend_from_slice( - &hex::decode(&groth16_proof.encoded_proof).expect("Invalid Groth16 proof"), - ); - bytes + let proof_bytes = + hex::decode(&groth16_proof.encoded_proof).expect("Invalid Groth16 proof"); + [groth16_proof.groth16_vkey_hash[..4].to_vec(), proof_bytes].concat() } _ => unimplemented!("only Plonk and Groth16 proofs are verifiable onchain"), } diff --git a/crates/verifier/Cargo.toml b/crates/verifier/Cargo.toml new file mode 100644 index 0000000000..321fa3c905 --- /dev/null +++ b/crates/verifier/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "sp1-verifier" +description = "Verifier for SP1 Groth16 and Plonk proofs." +readme = "../../README.md" +version = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = { workspace = true } +categories = { workspace = true } + +[dependencies] +bn = { git = "https://github.com/sp1-patches/bn", tag = "substrate_bn-v0.6.0-patch-v2", package = "substrate-bn" } +sha2 = { version = "0.10.8", default-features = false } +thiserror-no-std = "2.0.2" +hex = { version = "0.4.3", default-features = false, features = ["alloc"] } +lazy_static = { version = "1.5.0", default-features = false } + +[dev-dependencies] +sp1-sdk = { workspace = true } +num-bigint = "0.4.6" +num-traits = "0.2.19" + +[features] +default = ["std"] +std = [] diff --git a/crates/verifier/README.md b/crates/verifier/README.md new file mode 100644 index 0000000000..6a4042e04e --- /dev/null +++ b/crates/verifier/README.md @@ -0,0 +1,37 @@ +# SP1 Verifier + +This crate provides verifiers for SP1 Groth16 and Plonk zero-knowledge proofs. These proofs are expected +to be generated using the [SP1 SDK](../sdk). + +## Features + +Groth16 and Plonk proof verification are supported in `no-std` environments. Verification in the +SP1 ZKVM context is patched, in order to make use of the +[bn254 precompiles](https://blog.succinct.xyz/succinctshipsprecompiles/). + +### Pre-generated verification keys + +Verification keys for Groth16 and Plonk are stored in the [`bn254-vk`](./bn254-vk/) directory. These +vkeys are used to verify all SP1 proofs. + +These vkeys are the same as those found locally in +`~/.sp1/circuits///_vk.bin`, and should be automatically +updated after every release. + +## Tests + +Run tests with the following command: + +```sh +cargo test --package sp1-verifier +``` + +These tests verify the proofs in the [`test_binaries`](./test_binaries) directory. These test binaries +were generated from the fibonacci [groth16](../../examples/fibonacci/script/bin/groth16_bn254.rs) and +[plonk](../../examples/fibonacci/script/bin/plonk_bn254.rs) examples. You can reproduce these proofs +from the examples by running `cargo run --bin groth16_bn254` and `cargo run --bin plonk_bn254` from the +[`examples/fibonacci`](../../examples/fibonacci/) directory. + +## Acknowledgements + +Adapted from [@Bisht13's](https://github.com/Bisht13/gnark-bn254-verifier) `gnark-bn254-verifier` crate. diff --git a/crates/verifier/bn254-vk/groth16_vk.bin b/crates/verifier/bn254-vk/groth16_vk.bin new file mode 100644 index 0000000000000000000000000000000000000000..348cc8a0a38da85cc45c4c735187dd9bcea38abb GIT binary patch literal 396 zcmV;70dxMXO`50U0@>d|be&ZPl${0J>NESXY-Bqk^_il+ZSvybp;ufkNli8r>0U#& zA~B7UCCDJ;YRw4f$%nK+Q5jpwX9F+G_jb{*$%XicckzPLgn*_~^4`j+c}%=J^9BqK z7oB6TE-HJ-4fwj+2v;4M;k2V86F9`&}jRs!207 zspk@xY5-!8X>7 zf4*000BRQH7kY{${ln#Z;X) zXwkZq6kvnP1VARM>&cLbk&;N0qGa}^(BqSf>P|#4)EDxY2Xxy|5QWaK(AVc`e-ev> qcX${$k9V{NT8Gdc6dPacF62_tt)odelB}Y{+Fd{Z000000000Vo5gMb literal 0 HcmV?d00001 diff --git a/crates/verifier/bn254-vk/plonk_vk.bin b/crates/verifier/bn254-vk/plonk_vk.bin new file mode 100644 index 0000000000000000000000000000000000000000..c8e98e6fdb54469db488d7ec69c4b7ec115e1c96 GIT binary patch literal 34368 zcmeIv{Z9-47{KvMg|)8Lty8N@R=Ty`=Ey=`)(Z}~yEM(q^FBAJ4U+5H zk4c=X1bM@?y)N#~7CU89kCt44VxU!Jd^DglLi)YEyg71>SzqGuuooj48wxsG;;g#6 z+q@2`KBYKrbu_#Y6n0BfJlMP4`kC%s-IHd&v=VjRBD=s88?8LG%XGJL!E(DuVSaMg zfYN^I=g0Zw;*GN~1}}xl?fofzrtx<_WtEGoGaJiB4J$*EEDKw|W$)1yl=PR~&%Zr1 zF_`qy_(If9Wo2Ph&N9U-nOSjJfU`|=t#{$6{QNwjd`)8bgF4x-5T~(gTUM;RIwU$b zkWp8o7ip~peWN1##TwrOf_t~|h z6*KgFQvXG?RHf{Fcqq5$%vQOJr?T2WJ7U%?^R2Pk;agO5S^QW(e#ggrtybc=@cq*{ zzsmpt1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL WKmY**5I_Kd|3kpw@0r=x!~OtYt@z*o literal 0 HcmV?d00001 diff --git a/crates/verifier/src/constants.rs b/crates/verifier/src/constants.rs new file mode 100644 index 0000000000..7480c5a42f --- /dev/null +++ b/crates/verifier/src/constants.rs @@ -0,0 +1,33 @@ +/// Gnark (and arkworks) use the 2 most significant bits to encode the flag for a compressed +/// G1 point. +/// https://github.com/Consensys/gnark-crypto/blob/a7d721497f2a98b1f292886bb685fd3c5a90f930/ecc/bn254/marshal.go#L32-L42 +pub(crate) const MASK: u8 = 0b11 << 6; + +/// The flags for a positive, negative, or infinity compressed point. +pub(crate) const COMPRESSED_POSITIVE: u8 = 0b10 << 6; +pub(crate) const COMPRESSED_NEGATIVE: u8 = 0b11 << 6; +pub(crate) const COMPRESSED_INFINITY: u8 = 0b01 << 6; + +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum CompressedPointFlag { + Positive = COMPRESSED_POSITIVE as isize, + Negative = COMPRESSED_NEGATIVE as isize, + Infinity = COMPRESSED_INFINITY as isize, +} + +impl From for CompressedPointFlag { + fn from(val: u8) -> Self { + match val { + COMPRESSED_POSITIVE => CompressedPointFlag::Positive, + COMPRESSED_NEGATIVE => CompressedPointFlag::Negative, + COMPRESSED_INFINITY => CompressedPointFlag::Infinity, + _ => panic!("Invalid compressed point flag"), + } + } +} + +impl From for u8 { + fn from(value: CompressedPointFlag) -> Self { + value as u8 + } +} diff --git a/crates/verifier/src/converter.rs b/crates/verifier/src/converter.rs new file mode 100644 index 0000000000..2c747ce5d4 --- /dev/null +++ b/crates/verifier/src/converter.rs @@ -0,0 +1,122 @@ +use core::cmp::Ordering; + +use bn::{AffineG1, AffineG2, Fq, Fq2}; + +use crate::{ + constants::{CompressedPointFlag, MASK}, + error::Error, +}; + +/// Deserializes an Fq element from a buffer. +/// +/// If this Fq element is part of a compressed point, the flag that indicates the sign of the +/// y coordinate is also returned. +pub(crate) fn deserialize_with_flags(buf: &[u8]) -> Result<(Fq, CompressedPointFlag), Error> { + if buf.len() != 32 { + return Err(Error::InvalidXLength); + }; + + let m_data = buf[0] & MASK; + if m_data == u8::from(CompressedPointFlag::Infinity) { + // Checks if the first byte is zero after masking AND the rest of the bytes are zero. + if buf[0] & !MASK == 0 && buf[1..].iter().all(|&b| b == 0) { + return Err(Error::InvalidPoint); + } + Ok((Fq::zero(), CompressedPointFlag::Infinity)) + } else { + let mut x_bytes: [u8; 32] = [0u8; 32]; + x_bytes.copy_from_slice(buf); + x_bytes[0] &= !MASK; + + let x = Fq::from_be_bytes_mod_order(&x_bytes).expect("Failed to convert x bytes to Fq"); + + Ok((x, m_data.into())) + } +} + +/// Converts a compressed G1 point to an AffineG1 point. +/// +/// Asserts that the compressed point is represented as a single fq element: the x coordinate +/// of the point. The y coordinate is then computed from the x coordinate. The final point +/// is not checked to be on the curve for efficiency. +pub(crate) fn unchecked_compressed_x_to_g1_point(buf: &[u8]) -> Result { + let (x, m_data) = deserialize_with_flags(buf)?; + let (y, neg_y) = AffineG1::get_ys_from_x_unchecked(x).ok_or(Error::InvalidPoint)?; + + let mut final_y = y; + if y.cmp(&neg_y) == Ordering::Greater { + if m_data == CompressedPointFlag::Positive { + final_y = -y; + } + } else if m_data == CompressedPointFlag::Negative { + final_y = -y; + } + + Ok(AffineG1::new_unchecked(x, final_y)) +} + +/// Converts an uncompressed G1 point to an AffineG1 point. +/// +/// Asserts that the affine point is represented as two fq elements. +pub(crate) fn uncompressed_bytes_to_g1_point(buf: &[u8]) -> Result { + if buf.len() != 64 { + return Err(Error::InvalidXLength); + }; + + let (x_bytes, y_bytes) = buf.split_at(32); + + let x = Fq::from_slice(x_bytes).map_err(Error::Field)?; + let y = Fq::from_slice(y_bytes).map_err(Error::Field)?; + AffineG1::new(x, y).map_err(Error::Group) +} + +/// Converts a compressed G2 point to an AffineG2 point. +/// +/// Asserts that the compressed point is represented as a single fq2 element: the x coordinate +/// of the point. +/// Then, gets the y coordinate from the x coordinate. +/// For efficiency, this function does not check that the final point is on the curve. +pub(crate) fn unchecked_compressed_x_to_g2_point(buf: &[u8]) -> Result { + if buf.len() != 64 { + return Err(Error::InvalidXLength); + }; + + let (x1, flag) = deserialize_with_flags(&buf[..32])?; + let x0 = Fq::from_be_bytes_mod_order(&buf[32..64]).map_err(Error::Field)?; + let x = Fq2::new(x0, x1); + + if flag == CompressedPointFlag::Infinity { + return Ok(AffineG2::one()); + } + + let (y, neg_y) = AffineG2::get_ys_from_x_unchecked(x).ok_or(Error::InvalidPoint)?; + + match flag { + CompressedPointFlag::Positive => Ok(AffineG2::new_unchecked(x, y)), + CompressedPointFlag::Negative => Ok(AffineG2::new_unchecked(x, neg_y)), + _ => Err(Error::InvalidPoint), + } +} + +/// Converts an uncompressed G2 point to an AffineG2 point. +/// +/// Asserts that the affine point is represented as two fq2 elements. +pub(crate) fn uncompressed_bytes_to_g2_point(buf: &[u8]) -> Result { + if buf.len() != 128 { + return Err(Error::InvalidXLength); + } + + let (x_bytes, y_bytes) = buf.split_at(64); + let (x1_bytes, x0_bytes) = x_bytes.split_at(32); + let (y1_bytes, y0_bytes) = y_bytes.split_at(32); + + let x1 = Fq::from_slice(x1_bytes).map_err(Error::Field)?; + let x0 = Fq::from_slice(x0_bytes).map_err(Error::Field)?; + let y1 = Fq::from_slice(y1_bytes).map_err(Error::Field)?; + let y0 = Fq::from_slice(y0_bytes).map_err(Error::Field)?; + + let x = Fq2::new(x0, x1); + let y = Fq2::new(y0, y1); + + AffineG2::new(x, y).map_err(Error::Group) +} diff --git a/crates/verifier/src/error.rs b/crates/verifier/src/error.rs new file mode 100644 index 0000000000..0facb98902 --- /dev/null +++ b/crates/verifier/src/error.rs @@ -0,0 +1,63 @@ +use bn::{CurveError, FieldError, GroupError}; +use thiserror_no_std::Error; + +#[derive(Error, Debug)] +pub enum Error { + // Cryptographic Errors + #[error("BSB22 Commitment number mismatch")] + Bsb22CommitmentMismatch, + #[error("Challenge already computed")] + ChallengeAlreadyComputed, + #[error("Challenge not found")] + ChallengeNotFound, + #[error("Previous challenge not computed")] + PreviousChallengeNotComputed, + #[error("Pairing check failed")] + PairingCheckFailed, + #[error("Invalid point in subgroup check")] + InvalidPoint, + + // Arithmetic Errors + #[error("Beyond the modulus")] + BeyondTheModulus, + #[error("Ell too large")] + EllTooLarge, + #[error("Inverse not found")] + InverseNotFound, + #[error("Opening linear polynomial mismatch")] + OpeningPolyMismatch, + + // Input Errors + #[error("DST too large")] + DSTTooLarge, + #[error("Invalid number of digests")] + InvalidNumberOfDigests, + #[error("Invalid witness")] + InvalidWitness, + #[error("Invalid x length")] + InvalidXLength, + #[error("Unexpected flag")] + UnexpectedFlag, + #[error("Invalid data")] + InvalidData, + + // Conversion Errors + #[error("Failed to get Fr from random bytes")] + FailedToGetFrFromRandomBytes, + #[error("Failed to get x")] + FailedToGetX, + #[error("Failed to get y")] + FailedToGetY, + + // External Library Errors + #[error("BN254 Field Error")] + Field(FieldError), + #[error("BN254 Group Error")] + Group(GroupError), + #[error("BN254 Curve Error")] + Curve(CurveError), + + // SP1 Errors + #[error("Invalid program vkey hash")] + InvalidProgramVkeyHash, +} diff --git a/crates/verifier/src/groth16/converter.rs b/crates/verifier/src/groth16/converter.rs new file mode 100644 index 0000000000..6c7a5e3b97 --- /dev/null +++ b/crates/verifier/src/groth16/converter.rs @@ -0,0 +1,53 @@ +use alloc::vec::Vec; + +use crate::{ + converter::{ + unchecked_compressed_x_to_g1_point, unchecked_compressed_x_to_g2_point, + uncompressed_bytes_to_g1_point, uncompressed_bytes_to_g2_point, + }, + groth16::{Groth16G1, Groth16G2, Groth16Proof, Groth16VerifyingKey}, +}; + +use super::error::Groth16Error; + +/// Load the Groth16 proof from the given byte slice. +/// +/// The byte slice is represented as 2 uncompressed g1 points, and one uncompressed g2 point, +/// as outputted from gnark. +pub(crate) fn load_groth16_proof_from_bytes(buffer: &[u8]) -> Result { + let ar = uncompressed_bytes_to_g1_point(&buffer[..64])?; + let bs = uncompressed_bytes_to_g2_point(&buffer[64..192])?; + let krs = uncompressed_bytes_to_g1_point(&buffer[192..256])?; + + Ok(Groth16Proof { ar, bs, krs }) +} + +/// Load the Groth16 verification key from the given byte slice. +/// +/// The gnark verification key includes a lot of extraneous information. We only extract the necessary +/// elements to verify a proof. +pub(crate) fn load_groth16_verifying_key_from_bytes( + buffer: &[u8], +) -> Result { + // We don't need to check each compressed point because the Groth16 vkey is a public constant + // that doesn't usually change. The party using the Groth16 vkey will usually clearly know + // how the vkey was generated. + let g1_alpha = unchecked_compressed_x_to_g1_point(&buffer[..32])?; + let g2_beta = unchecked_compressed_x_to_g2_point(&buffer[64..128])?; + let g2_gamma = unchecked_compressed_x_to_g2_point(&buffer[128..192])?; + let g2_delta = unchecked_compressed_x_to_g2_point(&buffer[224..288])?; + + let num_k = u32::from_be_bytes([buffer[288], buffer[289], buffer[290], buffer[291]]); + let mut k = Vec::new(); + let mut offset = 292; + for _ in 0..num_k { + let point = unchecked_compressed_x_to_g1_point(&buffer[offset..offset + 32])?; + k.push(point); + offset += 32; + } + + Ok(Groth16VerifyingKey { + g1: Groth16G1 { alpha: g1_alpha, k }, + g2: Groth16G2 { beta: -g2_beta, gamma: g2_gamma, delta: g2_delta }, + }) +} diff --git a/crates/verifier/src/groth16/error.rs b/crates/verifier/src/groth16/error.rs new file mode 100644 index 0000000000..bc88da868c --- /dev/null +++ b/crates/verifier/src/groth16/error.rs @@ -0,0 +1,17 @@ +use thiserror_no_std::Error; + +#[derive(Debug, Error)] +pub enum Groth16Error { + #[error("Proof verification failed")] + ProofVerificationFailed, + #[error("Process verifying key failed")] + ProcessVerifyingKeyFailed, + #[error("Prepare inputs failed")] + PrepareInputsFailed, + #[error("Unexpected identity")] + UnexpectedIdentity, + #[error("General error")] + GeneralError(#[from] crate::error::Error), + #[error("Groth16 vkey hash mismatch")] + Groth16VkeyHashMismatch, +} diff --git a/crates/verifier/src/groth16/mod.rs b/crates/verifier/src/groth16/mod.rs new file mode 100644 index 0000000000..123d71e4f6 --- /dev/null +++ b/crates/verifier/src/groth16/mod.rs @@ -0,0 +1,66 @@ +mod converter; +pub(crate) mod error; +mod verify; + +pub(crate) use converter::{load_groth16_proof_from_bytes, load_groth16_verifying_key_from_bytes}; +use sha2::{Digest, Sha256}; +pub(crate) use verify::*; + +use error::Groth16Error; + +use crate::{bn254_public_values, decode_sp1_vkey_hash}; + +/// A verifier for Groth16 zero-knowledge proofs. +#[derive(Debug)] +pub struct Groth16Verifier; +impl Groth16Verifier { + /// Verifies a Groth16 proof. + /// + /// # Arguments + /// + /// * `proof` - The proof bytes. + /// * `public_inputs` - The SP1 public inputs. + /// * `sp1_vkey_hash` - The SP1 vkey hash. + /// This is generated in the following manner: + /// + /// ```ignore + /// use sp1_sdk::ProverClient; + /// let client = ProverClient::new(); + /// let (pk, vk) = client.setup(ELF); + /// let sp1_vkey_hash = vk.bytes32(); + /// ``` + /// * `groth16_vk` - The Groth16 verifying key bytes. + /// Usually this will be the [`crate::GROTH16_VK_BYTES`] constant, which is the Groth16 + /// verifying key for the current SP1 version. + /// + /// # Returns + /// + /// A [`Result`] containing a boolean indicating whether the proof is valid, + /// or a [`Groth16Error`] if verification fails. + pub fn verify( + proof: &[u8], + sp1_public_inputs: &[u8], + sp1_vkey_hash: &str, + groth16_vk: &[u8], + ) -> Result { + // Hash the vk and get the first 4 bytes. + let groth16_vk_hash: [u8; 4] = Sha256::digest(groth16_vk)[..4].try_into().unwrap(); + + // Check to make sure that this proof was generated by the groth16 proving key corresponding to + // the given groth16_vk. + // + // SP1 prepends the raw Groth16 proof with the first 4 bytes of the groth16 vkey to + // facilitate this check. + if groth16_vk_hash != proof[..4] { + return Err(Groth16Error::Groth16VkeyHashMismatch); + } + + let sp1_vkey_hash = decode_sp1_vkey_hash(sp1_vkey_hash)?; + let public_inputs = bn254_public_values(&sp1_vkey_hash, sp1_public_inputs); + + let proof = load_groth16_proof_from_bytes(&proof[4..]).unwrap(); + let groth16_vk = load_groth16_verifying_key_from_bytes(groth16_vk).unwrap(); + + verify_groth16_raw(&groth16_vk, &proof, &public_inputs) + } +} diff --git a/crates/verifier/src/groth16/verify.rs b/crates/verifier/src/groth16/verify.rs new file mode 100644 index 0000000000..510815b971 --- /dev/null +++ b/crates/verifier/src/groth16/verify.rs @@ -0,0 +1,66 @@ +use alloc::vec::Vec; +use bn::{pairing_batch, AffineG1, AffineG2, Fr, Gt, G1, G2}; + +use super::error::Groth16Error; + +/// G1 elements of the verification key. +#[derive(Clone, PartialEq)] +pub(crate) struct Groth16G1 { + pub(crate) alpha: AffineG1, + pub(crate) k: Vec, +} + +/// G2 elements of the verification key. +#[derive(Clone, PartialEq)] +pub(crate) struct Groth16G2 { + pub(crate) beta: AffineG2, + pub(crate) delta: AffineG2, + pub(crate) gamma: AffineG2, +} + +/// Verification key for the Groth16 proof. +#[derive(Clone, PartialEq)] +pub(crate) struct Groth16VerifyingKey { + pub(crate) g1: Groth16G1, + pub(crate) g2: Groth16G2, +} + +/// Proof for the Groth16 verification. +pub(crate) struct Groth16Proof { + pub(crate) ar: AffineG1, + pub(crate) krs: AffineG1, + pub(crate) bs: AffineG2, +} + +/// Prepare the inputs for the Groth16 verification by combining the public inputs with the +/// corresponding elements of the verification key. +fn prepare_inputs(vk: Groth16VerifyingKey, public_inputs: &[Fr]) -> Result { + if (public_inputs.len() + 1) != vk.g1.k.len() { + return Err(Groth16Error::PrepareInputsFailed); + } + + Ok(public_inputs + .iter() + .zip(vk.g1.k.iter().skip(1)) + .fold(vk.g1.k[0], |acc, (i, b)| acc + (*b * *i)) + .into()) +} + +/// Verify the Groth16 proof +/// +/// First, prepare the public inputs by folding them with the verification key. +/// Then, verify the proof by checking the pairing equation. +pub(crate) fn verify_groth16_raw( + vk: &Groth16VerifyingKey, + proof: &Groth16Proof, + public_inputs: &[Fr], +) -> Result { + let prepared_inputs = prepare_inputs(vk.clone(), public_inputs)?; + + Ok(pairing_batch(&[ + (-Into::::into(proof.ar), proof.bs.into()), + (prepared_inputs, vk.g2.gamma.into()), + (proof.krs.into(), vk.g2.delta.into()), + (vk.g1.alpha.into(), -Into::::into(vk.g2.beta)), + ]) == Gt::one()) +} diff --git a/crates/verifier/src/lib.rs b/crates/verifier/src/lib.rs new file mode 100644 index 0000000000..6abbd051e2 --- /dev/null +++ b/crates/verifier/src/lib.rs @@ -0,0 +1,32 @@ +//! This crate provides verifiers for SP1 Groth16 and Plonk BN254 proofs in a no-std environment. +//! It is patched for efficient verification within the SP1 ZKVM context. + +#![cfg_attr(not(feature = "std"), no_std)] +extern crate alloc; + +use lazy_static::lazy_static; + +lazy_static! { + /// The PLONK verifying key for this SP1 version. + pub static ref PLONK_VK_BYTES: &'static [u8] = include_bytes!("../bn254-vk/plonk_vk.bin"); +} + +lazy_static! { + /// The Groth16 verifying key for this SP1 version. + pub static ref GROTH16_VK_BYTES: &'static [u8] = include_bytes!("../bn254-vk/groth16_vk.bin"); +} + +mod constants; +mod converter; +mod error; +mod groth16; +mod utils; + +pub use groth16::Groth16Verifier; +pub use utils::*; + +mod plonk; +pub use plonk::PlonkVerifier; + +#[cfg(test)] +mod tests; diff --git a/crates/verifier/src/plonk/converter.rs b/crates/verifier/src/plonk/converter.rs new file mode 100644 index 0000000000..16bd387218 --- /dev/null +++ b/crates/verifier/src/plonk/converter.rs @@ -0,0 +1,176 @@ +use crate::{ + converter::{ + unchecked_compressed_x_to_g1_point, unchecked_compressed_x_to_g2_point, + uncompressed_bytes_to_g1_point, + }, + error::Error, +}; +use alloc::vec::Vec; +use bn::{AffineG1, Fr, G2}; + +use super::{ + error::PlonkError, + kzg::{self, BatchOpeningProof, LineEvaluationAff, OpeningProof, E2}, + verify::PlonkVerifyingKey, + PlonkProof, +}; + +pub(crate) fn load_plonk_verifying_key_from_bytes( + buffer: &[u8], +) -> Result { + let size = u64::from_be_bytes([ + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], + ]) as usize; + let size_inv = + Fr::from_slice(&buffer[8..40]).map_err(|e| PlonkError::GeneralError(Error::Field(e)))?; + let generator = + Fr::from_slice(&buffer[40..72]).map_err(|e| PlonkError::GeneralError(Error::Field(e)))?; + + let nb_public_variables = u64::from_be_bytes([ + buffer[72], buffer[73], buffer[74], buffer[75], buffer[76], buffer[77], buffer[78], + buffer[79], + ]) as usize; + + let coset_shift = + Fr::from_slice(&buffer[80..112]).map_err(|e| PlonkError::GeneralError(Error::Field(e)))?; + let s0 = unchecked_compressed_x_to_g1_point(&buffer[112..144])?; + let s1 = unchecked_compressed_x_to_g1_point(&buffer[144..176])?; + let s2 = unchecked_compressed_x_to_g1_point(&buffer[176..208])?; + let ql = unchecked_compressed_x_to_g1_point(&buffer[208..240])?; + let qr = unchecked_compressed_x_to_g1_point(&buffer[240..272])?; + let qm = unchecked_compressed_x_to_g1_point(&buffer[272..304])?; + let qo = unchecked_compressed_x_to_g1_point(&buffer[304..336])?; + let qk = unchecked_compressed_x_to_g1_point(&buffer[336..368])?; + let num_qcp = u32::from_be_bytes([buffer[368], buffer[369], buffer[370], buffer[371]]); + let mut qcp = Vec::new(); + let mut offset = 372; + + for _ in 0..num_qcp { + let point = unchecked_compressed_x_to_g1_point(&buffer[offset..offset + 32])?; + qcp.push(point); + offset += 32; + } + + let g1 = unchecked_compressed_x_to_g1_point(&buffer[offset..offset + 32])?; + let g2_0 = unchecked_compressed_x_to_g2_point(&buffer[offset + 32..offset + 96])?; + let g2_1 = unchecked_compressed_x_to_g2_point(&buffer[offset + 96..offset + 160])?; + + offset += 160 + 33788; + + let num_commitment_constraint_indexes = u64::from_be_bytes([ + buffer[offset], + buffer[offset + 1], + buffer[offset + 2], + buffer[offset + 3], + buffer[offset + 4], + buffer[offset + 5], + buffer[offset + 6], + buffer[offset + 7], + ]) as usize; + + let mut commitment_constraint_indexes = Vec::new(); + offset += 8; + for _ in 0..num_commitment_constraint_indexes { + let index = u64::from_be_bytes([ + buffer[offset], + buffer[offset + 1], + buffer[offset + 2], + buffer[offset + 3], + buffer[offset + 4], + buffer[offset + 5], + buffer[offset + 6], + buffer[offset + 7], + ]) as usize; + commitment_constraint_indexes.push(index); + offset += 8; + } + + let result = PlonkVerifyingKey { + size, + size_inv, + generator, + nb_public_variables, + kzg: kzg::KZGVerifyingKey { + g2: [G2::from(g2_0), G2::from(g2_1)], + g1: g1.into(), + lines: [[[LineEvaluationAff { + r0: E2 { a0: Fr::zero(), a1: Fr::zero() }, + r1: E2 { a0: Fr::zero(), a1: Fr::zero() }, + }; 66]; 2]; 2], + }, + coset_shift, + s: [s0, s1, s2], + ql, + qr, + qm, + qo, + qk, + qcp, + commitment_constraint_indexes, + }; + + Ok(result) +} + +pub(crate) fn load_plonk_proof_from_bytes(buffer: &[u8]) -> Result { + let lro0 = uncompressed_bytes_to_g1_point(&buffer[..64])?; + let lro1 = uncompressed_bytes_to_g1_point(&buffer[64..128])?; + let lro2 = uncompressed_bytes_to_g1_point(&buffer[128..192])?; + let z = uncompressed_bytes_to_g1_point(&buffer[192..256])?; + let h0 = uncompressed_bytes_to_g1_point(&buffer[256..320])?; + let h1 = uncompressed_bytes_to_g1_point(&buffer[320..384])?; + let h2 = uncompressed_bytes_to_g1_point(&buffer[384..448])?; + let batched_proof_h = uncompressed_bytes_to_g1_point(&buffer[448..512])?; + + let num_claimed_values = + u32::from_be_bytes([buffer[512], buffer[513], buffer[514], buffer[515]]) as usize; + + let mut claimed_values = Vec::new(); + let mut offset = 516; + for _ in 0..num_claimed_values { + let value = Fr::from_slice(&buffer[offset..offset + 32]) + .map_err(|e| PlonkError::GeneralError(Error::Field(e)))?; + claimed_values.push(value); + offset += 32; + } + + let z_shifted_opening_h = uncompressed_bytes_to_g1_point(&buffer[offset..offset + 64])?; + let z_shifted_opening_value = Fr::from_slice(&buffer[offset + 64..offset + 96]) + .map_err(|e| PlonkError::GeneralError(Error::Field(e)))?; + + let num_bsb22_commitments = u32::from_be_bytes([ + buffer[offset + 96], + buffer[offset + 97], + buffer[offset + 98], + buffer[offset + 99], + ]) as usize; + + let mut bsb22_commitments = Vec::new(); + offset += 100; + for _ in 0..num_bsb22_commitments { + let commitment = uncompressed_bytes_to_g1_point(&buffer[offset..offset + 64])?; + bsb22_commitments.push(commitment); + offset += 64; + } + + let result = PlonkProof { + lro: [lro0, lro1, lro2], + z, + h: [h0, h1, h2], + bsb22_commitments, + batched_proof: BatchOpeningProof { h: batched_proof_h, claimed_values }, + z_shifted_opening: OpeningProof { + h: z_shifted_opening_h, + claimed_value: z_shifted_opening_value, + }, + }; + + Ok(result) +} + +pub(crate) fn g1_to_bytes(g1: &AffineG1) -> Result, PlonkError> { + let mut bytes: [u8; 64] = unsafe { core::mem::transmute(*g1) }; + bytes[..32].reverse(); + bytes[32..].reverse(); + Ok(bytes.to_vec()) +} diff --git a/crates/verifier/src/plonk/error.rs b/crates/verifier/src/plonk/error.rs new file mode 100644 index 0000000000..cc166638dd --- /dev/null +++ b/crates/verifier/src/plonk/error.rs @@ -0,0 +1,49 @@ +use thiserror_no_std::Error; + +#[derive(Error, Debug)] +pub enum PlonkError { + #[error("Beyond the modulus")] + BeyondTheModulus, + #[error("BSB22 Commitment number mismatch")] + Bsb22CommitmentMismatch, + #[error("Challenge already computed")] + ChallengeAlreadyComputed, + #[error("Challenge not found")] + ChallengeNotFound, + #[error("DST too large")] + DSTTooLarge, + #[error("Ell too large")] + EllTooLarge, + #[error("Failed to get Fr from random bytes")] + FailedToGetFrFromRandomBytes, + #[error("Failed to get x")] + FailedToGetX, + #[error("Failed to get y")] + FailedToGetY, + #[error("Inverse not found")] + InverseNotFound, + #[error("Invalid number of digests")] + InvalidNumberOfDigests, + #[error("Invalid point in subgroup check")] + InvalidPoint, + #[error("Invalid witness")] + InvalidWitness, + #[error("Invalid x length")] + InvalidXLength, + #[error("Opening linear polynomial mismatch")] + OpeningPolyMismatch, + #[error("Pairing check failed")] + PairingCheckFailed, + #[error("Previous challenge not computed")] + PreviousChallengeNotComputed, + #[error("Unexpected flag")] + UnexpectedFlag, + #[error("Transcript error")] + TranscriptError, + #[error("Hash to field initialization failed")] + HashToFieldInitializationFailed, + #[error("Plonk vkey hash mismatch")] + PlonkVkeyHashMismatch, + #[error("General error")] + GeneralError(#[from] crate::error::Error), +} diff --git a/crates/verifier/src/plonk/hash_to_field.rs b/crates/verifier/src/plonk/hash_to_field.rs new file mode 100644 index 0000000000..d473abc4fe --- /dev/null +++ b/crates/verifier/src/plonk/hash_to_field.rs @@ -0,0 +1,118 @@ +use alloc::vec; +use alloc::vec::Vec; +use core::hash::Hasher; +use sha2::Digest; + +use crate::error::Error; + +pub(crate) struct WrappedHashToField { + domain: Vec, + to_hash: Vec, +} + +impl WrappedHashToField { + // Creates a new instance with a domain separator + pub(crate) fn new(domain_separator: &[u8]) -> Result { + Ok(Self { domain: domain_separator.to_vec(), to_hash: Vec::new() }) + } + + // Hashes the bytes to a field element and returns the byte representation + pub(crate) fn sum(&self) -> Result, Error> { + let res = Self::hash(self.to_hash.clone(), self.domain.clone(), 1)?; + + Ok(res[0].clone()) + } + + pub(crate) fn hash(msg: Vec, dst: Vec, count: usize) -> Result>, Error> { + let bytes = 32; + let l = 16 + bytes; + + let len_in_bytes = count * l; + let pseudo_random_bytes = Self::expand_msg_xmd(msg, dst, len_in_bytes).unwrap(); + + let mut res = Vec::new(); + for i in 0..count { + res.push(pseudo_random_bytes[i * l..(i + 1) * l].to_vec()); + } + + Ok(res) + } + + fn expand_msg_xmd(msg: Vec, dst: Vec, len: usize) -> Result, Error> { + let mut h = sha2::Sha256::new(); + + let ell = (len + 32 - 1) / 32; + + if ell > 255 { + Err(Error::EllTooLarge)?; + } + if dst.len() > 255 { + Err(Error::DSTTooLarge)?; + } + + let size_domain = dst.len(); + + h.reset(); + + // b_0 = H(msg_prime) + h.update([0u8; 64]); // Assuming the block size is 64 bytes for SHA-256 + h.update(&msg); + h.update([(len >> 8) as u8, len as u8, 0]); + h.update(&dst); + h.update([size_domain as u8]); + let b0 = h.finalize_reset(); + + // b_1 = H(b_0 || I2OSP(1, 1) || DST_prime) + h.update(b0); + h.update([1]); // I2OSP(1, 1) + h.update(&dst); + h.update([size_domain as u8]); + let mut b1 = h.finalize_reset(); + + let mut res = vec![0u8; len]; + res[..32].copy_from_slice(&b1); + + for i in 2..=ell { + h.reset(); + let mut strxor = vec![0u8; 32]; + for (j, (b0_byte, b1_byte)) in b0.iter().zip(b1.iter()).enumerate() { + strxor[j] = b0_byte ^ b1_byte; + } + h.update(&strxor); + h.update([i as u8]); + h.update(&dst); + h.update([size_domain as u8]); + b1 = h.finalize_reset(); + + let start = 32 * (i - 1); + let end = core::cmp::min(start + 32, res.len()); + res[start..end].copy_from_slice(&b1[..end - start]); + } + + Ok(res) + } +} + +impl Hasher for WrappedHashToField { + fn finish(&self) -> u64 { + // This method is not directly applicable to field elements, so it's a stub + unimplemented!(); + } + + fn write(&mut self, bytes: &[u8]) { + self.to_hash.extend_from_slice(bytes); + } +} + +impl Default for WrappedHashToField { + fn default() -> Self { + Self::new(&[]).unwrap() + } +} + +impl WrappedHashToField { + // Resets the state of the hasher + pub(crate) fn reset(&mut self) { + self.to_hash.clear(); + } +} diff --git a/crates/verifier/src/plonk/kzg.rs b/crates/verifier/src/plonk/kzg.rs new file mode 100644 index 0000000000..549e048f9c --- /dev/null +++ b/crates/verifier/src/plonk/kzg.rs @@ -0,0 +1,193 @@ +use alloc::{string::ToString, vec, vec::Vec}; +use bn::{pairing_batch, AffineG1, Fr, G1, G2}; + +use crate::{error::Error, plonk::transcript::Transcript}; + +use super::{converter::g1_to_bytes, error::PlonkError, GAMMA, U}; + +pub(crate) type Digest = AffineG1; + +#[derive(Clone, Copy, Debug)] +#[allow(dead_code)] +pub(crate) struct E2 { + pub(crate) a0: Fr, + pub(crate) a1: Fr, +} + +#[derive(Clone, Copy, Debug)] +#[allow(dead_code)] +pub(crate) struct LineEvaluationAff { + pub(crate) r0: E2, + pub(crate) r1: E2, +} + +#[derive(Clone, Copy, Debug)] +#[allow(dead_code)] +pub(crate) struct KZGVerifyingKey { + pub(crate) g2: [G2; 2], // [G₂, [α]G₂] + pub(crate) g1: G1, + // Precomputed pairing lines corresponding to G₂, [α]G₂ + pub(crate) lines: [[[LineEvaluationAff; 66]; 2]; 2], +} + +#[derive(Clone, Debug)] +pub(crate) struct BatchOpeningProof { + pub(crate) h: AffineG1, + pub(crate) claimed_values: Vec, +} + +#[derive(Clone, Copy, Debug)] +pub(crate) struct OpeningProof { + pub(crate) h: AffineG1, + pub(crate) claimed_value: Fr, +} + +/// Derives the folding factor for the batched opening proof. +/// +/// Uses a separate transcript than the main transcript used for the other fiat shamir randomness. +fn derive_gamma( + point: &Fr, + digests: Vec, + claimed_values: Vec, + data_transcript: Option>, +) -> Result { + let mut transcript = Transcript::new(Some([GAMMA.to_string()].to_vec()))?; + transcript.bind(GAMMA, &point.into_u256().to_bytes_be())?; + + for digest in digests.iter() { + transcript.bind(GAMMA, &g1_to_bytes(digest)?)?; + } + + for claimed_value in claimed_values.iter() { + transcript.bind(GAMMA, &claimed_value.into_u256().to_bytes_be())?; + } + + if let Some(data_transcript) = data_transcript { + transcript.bind(GAMMA, &data_transcript)?; + } + + let gamma_byte = transcript.compute_challenge(GAMMA)?; + + let x = Fr::from_bytes_be_mod_order(gamma_byte.as_slice()) + .map_err(|e| PlonkError::GeneralError(Error::Field(e)))?; + + Ok(x) +} + +fn fold(di: Vec, fai: Vec, ci: Vec) -> Result<(AffineG1, Fr), PlonkError> { + let nb_digests = di.len(); + let mut folded_evaluations = Fr::zero(); + + for i in 0..nb_digests { + folded_evaluations += fai[i] * ci[i]; + } + + let folded_digests = AffineG1::msm(&di, &ci); + + Ok((folded_digests, folded_evaluations)) +} + +pub(crate) fn fold_proof( + digests: Vec, + batch_opening_proof: &BatchOpeningProof, + point: &Fr, + data_transcript: Option>, + global_transcript: &mut Transcript, +) -> Result<(OpeningProof, AffineG1), PlonkError> { + let nb_digests = digests.len(); + + if nb_digests != batch_opening_proof.claimed_values.len() { + return Err(Error::InvalidNumberOfDigests.into()); + } + + let gamma = derive_gamma( + point, + digests.clone(), + batch_opening_proof.claimed_values.clone(), + data_transcript, + )?; + + // Bind gamma to the transcript to challenge U. + global_transcript.bind(U, &gamma.into_u256().to_bytes_be())?; + + let mut gammai = vec![Fr::zero(); nb_digests]; + gammai[0] = Fr::one(); + + if nb_digests > 1 { + gammai[1] = gamma; + } + + for i in 2..nb_digests { + gammai[i] = gammai[i - 1] * gamma; + } + + let (folded_digests, folded_evaluations) = + fold(digests, batch_opening_proof.claimed_values.clone(), gammai)?; + + let open_proof = OpeningProof { h: batch_opening_proof.h, claimed_value: folded_evaluations }; + + Ok((open_proof, folded_digests)) +} + +pub(crate) fn batch_verify_multi_points( + digests: Vec, + proofs: Vec, + points: Vec, + u: Fr, + vk: &KZGVerifyingKey, +) -> Result<(), PlonkError> { + let nb_digests = digests.len(); + let nb_proofs = proofs.len(); + let nb_points = points.len(); + + if nb_digests != nb_proofs { + return Err(Error::InvalidNumberOfDigests.into()); + } + + if nb_digests != nb_points { + return Err(Error::InvalidNumberOfDigests.into()); + } + + if nb_digests == 1 { + todo!(); + } + + let mut random_numbers = Vec::with_capacity(nb_digests); + random_numbers.push(Fr::one()); + for i in 1..nb_digests { + random_numbers.push(u * random_numbers[i - 1]); + } + + let mut quotients = Vec::with_capacity(nb_proofs); + for item in proofs.iter().take(nb_digests) { + quotients.push(item.h); + } + + let mut folded_quotients = AffineG1::msm("ients, &random_numbers); + let mut evals = Vec::with_capacity(nb_digests); + + for item in proofs.iter().take(nb_digests) { + evals.push(item.claimed_value); + } + + let (mut folded_digests, folded_evals) = fold(digests, evals, random_numbers.clone())?; + let folded_evals_commit = vk.g1 * folded_evals; + folded_digests = folded_digests - folded_evals_commit.into(); + + for i in 0..random_numbers.len() { + random_numbers[i] *= points[i]; + } + let folded_points_quotients = AffineG1::msm("ients, &random_numbers); + + folded_digests = folded_digests + folded_points_quotients; + folded_quotients = -folded_quotients; + + let pairing_result = + pairing_batch(&[(folded_digests.into(), vk.g2[0]), (folded_quotients.into(), vk.g2[1])]); + + if !pairing_result.is_one() { + return Err(Error::PairingCheckFailed.into()); + } + + Ok(()) +} diff --git a/crates/verifier/src/plonk/mod.rs b/crates/verifier/src/plonk/mod.rs new file mode 100644 index 0000000000..4ee223b71e --- /dev/null +++ b/crates/verifier/src/plonk/mod.rs @@ -0,0 +1,75 @@ +pub(crate) const GAMMA: &str = "gamma"; +pub(crate) const BETA: &str = "beta"; +pub(crate) const ALPHA: &str = "alpha"; +pub(crate) const ZETA: &str = "zeta"; +pub(crate) const U: &str = "u"; + +mod converter; +mod hash_to_field; +mod kzg; +mod proof; +mod transcript; +mod verify; + +pub(crate) mod error; + +pub(crate) use converter::{load_plonk_proof_from_bytes, load_plonk_verifying_key_from_bytes}; +pub(crate) use proof::PlonkProof; +pub(crate) use verify::verify_plonk_raw; + +use error::PlonkError; +use sha2::{Digest, Sha256}; + +use crate::{bn254_public_values, decode_sp1_vkey_hash}; +/// A verifier for Plonk zero-knowledge proofs. +#[derive(Debug)] +pub struct PlonkVerifier; + +impl PlonkVerifier { + /// # Arguments + /// + /// * `proof` - The proof bytes. + /// * `public_inputs` - The SP1 public inputs. + /// * `sp1_vkey_hash` - The SP1 vkey hash. + /// This is generated in the following manner: + /// + /// ```ignore + /// use sp1_sdk::ProverClient; + /// let client = ProverClient::new(); + /// let (pk, vk) = client.setup(ELF); + /// let sp1_vkey_hash = vk.bytes32(); + /// ``` + /// * `plonk_vk` - The Plonk verifying key bytes. + /// Usually this will be the [`crate::PLONK_VK_BYTES`] constant. + /// + /// # Returns + /// + /// A `Result` containing a boolean indicating whether the proof is valid, + /// or a [`PlonkError`] if verification fails. + pub fn verify( + proof: &[u8], + sp1_public_inputs: &[u8], + sp1_vkey_hash: &str, + plonk_vk: &[u8], + ) -> Result { + // Hash the vk and get the first 4 bytes. + let plonk_vk_hash: [u8; 4] = Sha256::digest(plonk_vk)[..4].try_into().unwrap(); + + // Check to make sure that this proof was generated by the plonk proving key corresponding to + // the given plonk vk. + // + // SP1 prepends the raw Plonk proof with the first 4 bytes of the plonk vkey to + // facilitate this check. + if plonk_vk_hash != proof[..4] { + return Err(PlonkError::PlonkVkeyHashMismatch); + } + + let sp1_vkey_hash = decode_sp1_vkey_hash(sp1_vkey_hash)?; + let public_inputs = bn254_public_values(&sp1_vkey_hash, sp1_public_inputs); + + let proof = load_plonk_proof_from_bytes(&proof[4..]).unwrap(); + let plonk_vk = load_plonk_verifying_key_from_bytes(plonk_vk).unwrap(); + + verify_plonk_raw(&plonk_vk, &proof, &public_inputs) + } +} diff --git a/crates/verifier/src/plonk/proof.rs b/crates/verifier/src/plonk/proof.rs new file mode 100644 index 0000000000..850ecf00f4 --- /dev/null +++ b/crates/verifier/src/plonk/proof.rs @@ -0,0 +1,13 @@ +use alloc::vec::Vec; + +use super::kzg::{BatchOpeningProof, Digest, OpeningProof}; + +#[derive(Debug)] +pub(crate) struct PlonkProof { + pub(crate) lro: [Digest; 3], + pub(crate) z: Digest, + pub(crate) h: [Digest; 3], + pub(crate) bsb22_commitments: Vec, + pub(crate) batched_proof: BatchOpeningProof, + pub(crate) z_shifted_opening: OpeningProof, +} diff --git a/crates/verifier/src/plonk/transcript.rs b/crates/verifier/src/plonk/transcript.rs new file mode 100644 index 0000000000..5d1c2db8db --- /dev/null +++ b/crates/verifier/src/plonk/transcript.rs @@ -0,0 +1,103 @@ +use alloc::{collections::btree_map::BTreeMap, string::String, vec::Vec}; +use sha2::{Digest, Sha256}; + +use crate::error::Error; + +/// A challenge in the transcript, derived with randomness from `bindings` and the previous +/// challenge. +#[derive(Clone, Debug)] +pub(crate) struct Challenge { + position: usize, + bindings: Vec>, + value: Vec, + is_computed: bool, +} + +/// A Fiat-Shamir transcript. +#[derive(Clone, Debug)] +pub(crate) struct Transcript { + pub(crate) h: Sha256, + + pub(crate) challenges: BTreeMap, + previous_challenge: Option, +} + +impl Transcript { + /// Creates a new transcript. + pub(crate) fn new(challenges_id: Option>) -> Result { + let h = Sha256::new(); + + if let Some(challenges_id) = challenges_id { + let mut challenges = BTreeMap::new(); + for (position, id) in challenges_id.iter().enumerate() { + challenges.insert( + id.clone(), + Challenge { + position, + bindings: Vec::new(), + value: Vec::new(), + is_computed: false, + }, + ); + } + + Ok(Transcript { h, challenges, previous_challenge: None }) + } else { + Ok(Transcript { h, challenges: BTreeMap::new(), previous_challenge: None }) + } + } + + /// Binds some data to a challenge. + pub(crate) fn bind(&mut self, id: &str, binding: &[u8]) -> Result<(), Error> { + let current_challenge = self.challenges.get_mut(id).ok_or(Error::ChallengeNotFound)?; + if current_challenge.is_computed { + return Err(Error::ChallengeAlreadyComputed); + } + + current_challenge.bindings.push(binding.to_vec()); + + Ok(()) + } + + /// Computes a challenge and returns its value. + /// + /// Challenges must be computed in order. The previous challenge is automatically fed into the + /// challenge currently being computed. + pub(crate) fn compute_challenge(&mut self, challenge_id: &str) -> Result, Error> { + let challenge = self.challenges.get_mut(challenge_id).ok_or(Error::ChallengeNotFound)?; + + if challenge.is_computed { + return Ok(challenge.value.clone()); + } + + // Reset the hash function before and after computing the challenge + self.h.reset(); + + self.h.update(challenge_id.as_bytes()); + + if challenge.position != 0 { + if let Some(previous_challenge) = &self.previous_challenge { + if previous_challenge.position != challenge.position - 1 { + return Err(Error::PreviousChallengeNotComputed); + } + self.h.update(&previous_challenge.value) + } else { + return Err(Error::PreviousChallengeNotComputed); + } + } + + for binding in challenge.bindings.iter() { + self.h.update(binding) + } + + let res = self.h.finalize_reset(); + + challenge.value = res.to_vec(); + challenge.is_computed = true; + + // Update the previous challenge reference + self.previous_challenge = Some(challenge.clone()); + + Ok(res.to_vec()) + } +} diff --git a/crates/verifier/src/plonk/verify.rs b/crates/verifier/src/plonk/verify.rs new file mode 100644 index 0000000000..d00f35094b --- /dev/null +++ b/crates/verifier/src/plonk/verify.rs @@ -0,0 +1,404 @@ +use alloc::{string::ToString, vec, vec::Vec}; +use bn::{arith::U256, AffineG1, Fr}; +use core::hash::Hasher; + +use crate::{error::Error, plonk::transcript::Transcript}; + +use super::{ + converter::g1_to_bytes, error::PlonkError, kzg, PlonkProof, ALPHA, BETA, GAMMA, U, ZETA, +}; +#[derive(Debug)] +pub(crate) struct PlonkVerifyingKey { + pub(crate) size: usize, + pub(crate) size_inv: Fr, + pub(crate) generator: Fr, + pub(crate) nb_public_variables: usize, + + pub(crate) kzg: kzg::KZGVerifyingKey, + + pub(crate) coset_shift: Fr, + + pub(crate) s: [kzg::Digest; 3], + + pub(crate) ql: kzg::Digest, + pub(crate) qr: kzg::Digest, + pub(crate) qm: kzg::Digest, + pub(crate) qo: kzg::Digest, + pub(crate) qk: kzg::Digest, + pub(crate) qcp: Vec, + + pub(crate) commitment_constraint_indexes: Vec, +} + +/// Verifies a PLONK proof +/// +/// # Arguments +/// +/// * `vk` - The verifying key +/// * `proof` - The PLONK proof +/// * `public_inputs` - The public inputs to the circuit +/// +/// # Returns +/// +/// * `Result` - Returns true if the proof is valid, or an error if verification fails +pub(crate) fn verify_plonk_raw( + vk: &PlonkVerifyingKey, + proof: &PlonkProof, + public_inputs: &[Fr], +) -> Result { + // Check if the number of BSB22 commitments matches the number of Qcp in the verifying key + if proof.bsb22_commitments.len() != vk.qcp.len() { + return Err(PlonkError::GeneralError(Error::Bsb22CommitmentMismatch)); + } + + // Check if the number of public inputs matches the number of public variables in the verifying key + if public_inputs.len() != vk.nb_public_variables { + return Err(PlonkError::GeneralError(Error::InvalidWitness)); + } + + // Initialize the Fiat-Shamir transcript + let mut fs = Transcript::new(Some( + [GAMMA.to_string(), BETA.to_string(), ALPHA.to_string(), ZETA.to_string(), U.to_string()] + .to_vec(), + ))?; + + // Bind public data to the transcript + bind_public_data(&mut fs, GAMMA, vk, public_inputs)?; + + // Derive gamma challenge: γ + let gamma = derive_randomness( + &mut fs, + GAMMA, + Some([proof.lro[0], proof.lro[1], proof.lro[2]].to_vec()), + )?; + + // Derive beta challenge: β + let beta = derive_randomness(&mut fs, BETA, None)?; + + // Derive alpha challenge: α + let mut alpha_deps: Vec = proof.bsb22_commitments.to_vec(); + alpha_deps.push(proof.z); + let alpha = derive_randomness(&mut fs, ALPHA, Some(alpha_deps))?; + + // Derive zeta challenge (point of evaluation): ζ + let zeta = + derive_randomness(&mut fs, ZETA, Some([proof.h[0], proof.h[1], proof.h[2]].to_vec()))?; + + // Compute zh_zeta = ζⁿ - 1 + let one = Fr::one(); + let n = U256::from(vk.size as u64); + let n = + Fr::from_slice(&n.to_bytes_be()).map_err(|e| PlonkError::GeneralError(Error::Field(e)))?; + let zeta_power_n = zeta.pow(n); + let zh_zeta = zeta_power_n - one; + + // Compute Lagrange polynomial at ζ: L₁(ζ) = (ζⁿ - 1) / (n * (ζ - 1)) + let mut lagrange_one = (zeta - one).inverse().ok_or(Error::InverseNotFound)?; + lagrange_one *= zh_zeta; + lagrange_one *= vk.size_inv; + + // Compute PI = ∑_{i Result<(), PlonkError> { + transcript.bind(challenge, &g1_to_bytes(&vk.s[0])?)?; + transcript.bind(challenge, &g1_to_bytes(&vk.s[1])?)?; + transcript.bind(challenge, &g1_to_bytes(&vk.s[2])?)?; + + transcript.bind(challenge, &g1_to_bytes(&vk.ql)?)?; + transcript.bind(challenge, &g1_to_bytes(&vk.qr)?)?; + transcript.bind(challenge, &g1_to_bytes(&vk.qm)?)?; + transcript.bind(challenge, &g1_to_bytes(&vk.qo)?)?; + transcript.bind(challenge, &g1_to_bytes(&vk.qk)?)?; + + for qcp in vk.qcp.iter() { + transcript.bind(challenge, &g1_to_bytes(qcp)?)?; + } + + for public_input in public_inputs.iter() { + transcript.bind(challenge, &public_input.into_u256().to_bytes_be())?; + } + + Ok(()) +} + +/// Derives the randomness from the transcript. +/// +/// If you want to include some data for a challenge that isn't an affine g1 point, use +/// [`Transcript::bind`] to bind the data to the transcript before deriving the randomness. +fn derive_randomness( + transcript: &mut Transcript, + challenge: &str, + points: Option>, +) -> Result { + if let Some(points) = points { + for point in points { + let buf = g1_to_bytes(&point)?; + transcript.bind(challenge, &buf)?; + } + } + + let b = transcript.compute_challenge(challenge)?; + let x = Fr::from_bytes_be_mod_order(b.as_slice()) + .map_err(|e| PlonkError::GeneralError(Error::Field(e)))?; + Ok(x) +} + +/// Wrapper for [`batch_inversion`]. +fn batch_invert(elements: &[Fr]) -> Result, PlonkError> { + let mut elements = elements.to_vec(); + batch_inversion(&mut elements); + Ok(elements) +} + +/// Inverts a batch of Fr elements. +fn batch_inversion(v: &mut [Fr]) { + batch_inversion_and_mul(v, &Fr::one()); +} + +/// Inverts a batch of Fr elements and multiplies them by a given coefficient. +fn batch_inversion_and_mul(v: &mut [Fr], coeff: &Fr) { + let mut prod = Vec::with_capacity(v.len()); + let mut tmp = Fr::one(); + for f in v.iter().filter(|f| !f.is_zero()) { + tmp *= *f; + prod.push(tmp); + } + + tmp = tmp.inverse().unwrap(); + + tmp *= *coeff; + + for (f, s) in v + .iter_mut() + .rev() + .filter(|f| !f.is_zero()) + .zip(prod.into_iter().rev().skip(1).chain(Some(Fr::one()))) + { + let new_tmp = tmp * *f; + *f = tmp * s; + tmp = new_tmp; + } +} diff --git a/crates/verifier/src/tests.rs b/crates/verifier/src/tests.rs new file mode 100644 index 0000000000..7048c3c8e8 --- /dev/null +++ b/crates/verifier/src/tests.rs @@ -0,0 +1,62 @@ +use sp1_sdk::{install::try_install_circuit_artifacts, SP1ProofWithPublicValues}; + +extern crate std; + +#[test] +fn test_verify_groth16() { + // Location of the serialized SP1ProofWithPublicValues. See README.md for more information. + let proof_file = "test_binaries/fibonacci-groth16.bin"; + + // Load the saved proof and extract the proof and public inputs. + let sp1_proof_with_public_values = SP1ProofWithPublicValues::load(proof_file).unwrap(); + + let proof = sp1_proof_with_public_values.bytes(); + let public_inputs = sp1_proof_with_public_values.public_values.to_vec(); + + // This vkey hash was derived by calling `vk.bytes32()` on the verifying key. + let vkey_hash = "0x00e60860c07bfc6e4c480286c0ddbb879674eb47f84b4ef041cf858b17aa0ed1"; + + let is_valid = + crate::Groth16Verifier::verify(&proof, &public_inputs, vkey_hash, &crate::GROTH16_VK_BYTES) + .expect("Groth16 proof is invalid"); + + if !is_valid { + panic!("Groth16 proof is invalid"); + } +} + +#[test] +fn test_verify_plonk() { + // Location of the serialized SP1ProofWithPublicValues. See README.md for more information. + let proof_file = "test_binaries/fibonacci-plonk.bin"; + + // Load the saved proof and extract the proof and public inputs. + let sp1_proof_with_public_values = SP1ProofWithPublicValues::load(proof_file).unwrap(); + + let proof = sp1_proof_with_public_values.raw_with_checksum(); + let public_inputs = sp1_proof_with_public_values.public_values.to_vec(); + + // This vkey hash was derived by calling `vk.bytes32()` on the verifying key. + let vkey_hash = "0x00e60860c07bfc6e4c480286c0ddbb879674eb47f84b4ef041cf858b17aa0ed1"; + + let is_valid = + crate::PlonkVerifier::verify(&proof, &public_inputs, vkey_hash, &crate::PLONK_VK_BYTES) + .expect("Plonk proof is invalid"); + + if !is_valid { + panic!("Plonk proof is invalid"); + } +} + +#[test] +fn test_vkeys() { + let groth16_path = try_install_circuit_artifacts("groth16"); + let s3_vkey_path = groth16_path.join("groth16_vk.bin"); + let s3_vkey_bytes = std::fs::read(s3_vkey_path).unwrap(); + assert_eq!(s3_vkey_bytes, *crate::GROTH16_VK_BYTES); + + let plonk_path = try_install_circuit_artifacts("plonk"); + let s3_vkey_path = plonk_path.join("plonk_vk.bin"); + let s3_vkey_bytes = std::fs::read(s3_vkey_path).unwrap(); + assert_eq!(s3_vkey_bytes, *crate::PLONK_VK_BYTES); +} diff --git a/crates/verifier/src/utils.rs b/crates/verifier/src/utils.rs new file mode 100644 index 0000000000..7c2472374f --- /dev/null +++ b/crates/verifier/src/utils.rs @@ -0,0 +1,29 @@ +use bn::Fr; +use sha2::{Digest, Sha256}; + +use crate::error::Error; + +/// Hashes the public inputs in the same format as the Plonk and Groth16 verifiers. +pub fn hash_public_inputs(public_inputs: &[u8]) -> [u8; 32] { + let mut result = Sha256::digest(public_inputs); + + // The Plonk and Groth16 verifiers operate over a 254 bit field, so we need to zero + // out the first 3 bits. The same logic happens in the SP1 Ethereum verifier contract. + result[0] &= 0x1F; + + result.into() +} + +/// Formats the sp1 vkey hash and public inputs for use in either the Plonk or Groth16 verifier. +pub fn bn254_public_values(sp1_vkey_hash: &[u8; 32], sp1_public_inputs: &[u8]) -> [Fr; 2] { + let committed_values_digest = hash_public_inputs(sp1_public_inputs); + let vkey_hash = Fr::from_slice(&sp1_vkey_hash[1..]).unwrap(); + let committed_values_digest = Fr::from_slice(&committed_values_digest).unwrap(); + [vkey_hash, committed_values_digest] +} + +/// Decodes the sp1 vkey hash from the string from a call to `vk.bytes32`. +pub fn decode_sp1_vkey_hash(sp1_vkey_hash: &str) -> Result<[u8; 32], Error> { + let bytes = hex::decode(&sp1_vkey_hash[2..]).map_err(|_| Error::InvalidProgramVkeyHash)?; + bytes.try_into().map_err(|_| Error::InvalidProgramVkeyHash) +} diff --git a/crates/verifier/test_binaries/fibonacci-groth16.bin b/crates/verifier/test_binaries/fibonacci-groth16.bin new file mode 100644 index 0000000000000000000000000000000000000000..72c58644c3c5fcf1c88b4d24c2ced7efd366b910 GIT binary patch literal 1449 zcmeHHJC0Q`41IhwBP1H8rKTC7k$-XGH9$c_jhw`m*uX3SQBDaZEfO0*Vh^wc7C<)( zz)$m#SONu+auYkg_Q~;49vlvb7d4MVK!r)AlePM4XTU~+z-$J9h&-$@F%Ri14937i zkp@9C(~d^M^^@_-yNm}VZKB<*kqy$CqS#akgv+Qh+{JoFXo@gUYKs*PtlWkvSD_A7 zk_Zp??~;NDYxmKRe97Y22B|iaNELif#zoza@aGH)lSwp%Dlcwzg1RQABS*O$2X1f} zo9nxPqWs+I+hB4*4!w`R4gKw6t*+@`QM<`lrF z9?mEXt1TLBv@M#_iIkVDb%4biH7ZBxrPHW>^(Eq^zR_TB!}tGn@Lva|1NcYAqqCcv%Znf1pPzsF^6c~V zw_k7e$Dfx^zFu6vef9LUeYkge3m=}=+dqzzeOw;@b#_~U@6Hd0vy<Mg-cRP>Q=xAa6%Omkh;}o1TK%j83C!M;36O+p^BIpKnRfo z67T?6`@ZKY=P$Sf@6`G1v-dvT($ZQ>IzN1QdHFS7&qK*|i0hOvy!#x)CdxEM1Q9cj z6*gpyrE}<@7&Ml%EFp{V$ss!MqZpsQTk*xkO?^g~#1h9#oy}cH2fkpNF*W97GG|(> zIAq*T!-uW#fsH0%OA-F-Pu?v`IqjZED_(I}L&m~A&i9<~lZkj`Uaxs0eb5R%$=7kl zr*n$6U%J)id-Cah3|pqG-iafGV;fl^SIKpXz0+prOkv#X%rSK%snYDIYOhr+hG0ne zaBgf`_u8?-QHZS^>&~mgSE>j5q^q{$49;ZHye5YVur4>=(|6tFJ5;g#mAjjerVUjW zS%WG??6`H7uD#}5h8(6IUPo-AICh_yQo`4+>4C6i?Q=CunYV4Ao~ObS;ILKMwRs9# zGXaf8DHi#_Ro(ZX2;mkKM**Qo2$dOmMbn&vDJ`9_0~UAWiuzzL3+&^l4rf&$IoDo{ z-~beAKk_D(R@ZDILNF`Sn`e(ebUb$h4Kh`kp>BJUM{i%iKT29AxVYT)oCIeWf!5us zi6i`cA%U7ev}D)brx8iVaLM2Sya{z4M@mFSJ3#CtT9pCPv?*DQE>yR2&X`*+$aZd} zjY7VSU^p~@dN+tNp2Pxl+gx(ogZ3etPt9!&@PI(giX-0VFvT)S=A3tq8n|c%g zY(>3y&%HBafbtOIBW%Q#o(GX}xFhccio*exKk$I+{U|>7Yr}p5 zA(;kCproiJ=MgFU*Z>nL9q>3yqPvch(%uS%HtO0o1^!WZMztJx1P);qC=5ys0z<~t z31E^0v^fubP^mjhAZ$a4FA46PATOIj1pwNMz}z$i0ULaXgPKs>vq7J}Y)8+;id%Hu zabY5t6sNa?Hrb#qBxY-##$uqcg}`cTL6C;RB83TH2nMr&I_KR9W{&g=FPyMA)#hv) zYb;8{DeE?0_I*&#A+#S`Rc=F^BQD{t5;&%)NN+e2{3T;k0>IIF?A6}xCMVwEd(`q9 zynCQzHtyY50-hxs#skC!ZgCW5acSR2f-Pb!uN`ADB@~O1mOS_+R6j_#u9q;A?WD#3F@Kh=B+ULD0p409Run=8@MzUf@9H@ ziR*JeI&ng92}1Flpq<2AJ_d|iz?cid98$f|ZV%K3(6>Dv?w}zgi;M;+=-}Uybbt#e z1mf%gtY6g$pEf#sC5mhJ>17v6g$wb5TW&;!e&p-Y0>;L}l zH|LxG{Qis2e)i)Zy#G)6qxYZRes|*i_vhp1-@EoLZu}Cx_Wj?+m(Ry1^a=eB3!U-D literal 0 HcmV?d00001 diff --git a/examples/Cargo.lock b/examples/Cargo.lock new file mode 100644 index 0000000000..6e0fdb5471 --- /dev/null +++ b/examples/Cargo.lock @@ -0,0 +1,8381 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addchain" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" +dependencies = [ + "num-bigint 0.3.3", + "num-integer", + "num-traits", +] + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aggregation-program" +version = "1.1.0" +dependencies = [ + "sha2 0.10.8", + "sp1-zkvm", +] + +[[package]] +name = "aggregation-script" +version = "1.1.0" +dependencies = [ + "sp1-build", + "sp1-sdk", + "tracing", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "alloy-chains" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca4a1469a3e572e9ba362920ff145f5d0a00a3e71a64ddcb4a3659cf64c76a7" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "num_enum 0.7.3", + "serde", + "strum", +] + +[[package]] +name = "alloy-consensus" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629b62e38d471cc15fea534eb7283d2f8a4e8bdb1811bcc5d66dda6cfce6fae1" +dependencies = [ + "alloy-eips", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "serde", +] + +[[package]] +name = "alloy-eip2930" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "serde", +] + +[[package]] +name = "alloy-eip7702" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "k256", + "serde", +] + +[[package]] +name = "alloy-eips" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "alloy-genesis" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a7a18afb0b318616b6b2b0e2e7ac5529d32a966c673b48091c9919e284e6aca" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-json-abi" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b5671117c38b1c2306891f97ad3828d85487087f54ebe2c7591a055ea5bcea7" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-network-primitives" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ad40869867ed2d9cd3842b1e800889e5b49e6b92da346e93862b4a741bedf3" +dependencies = [ + "alloy-eips", + "alloy-primitives 0.8.9", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-primitives" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "600d34d8de81e23b6d909c094e23b3d357e01ca36b78a8c5424c501eedbe86f0" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more 0.99.18", + "hex-literal", + "itoa", + "k256", + "keccak-asm", + "proptest", + "rand 0.8.5", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-primitives" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more 0.99.18", + "hex-literal", + "itoa", + "k256", + "keccak-asm", + "proptest", + "rand 0.8.5", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-primitives" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71738eb20c42c5fb149571e76536a0f309d142f3957c28791662b96baf77a3d" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more 1.0.0", + "foldhash", + "getrandom", + "hashbrown 0.15.0", + "hex-literal", + "indexmap 2.6.0", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand 0.8.5", + "ruint", + "rustc-hash 2.0.0", + "serde", + "sha3", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0822426598f95e45dd1ea32a738dac057529a709ee645fcc516ffa4cbde08f" +dependencies = [ + "alloy-rlp-derive", + "arrayvec 0.7.6", + "bytes", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "alloy-rpc-types" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64333d639f2a0cf73491813c629a405744e16343a4bc5640931be707c345ecc5" +dependencies = [ + "alloy-rpc-types-eth", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-rpc-types-eth" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83aa984386deda02482660aa31cb8ca1e63d533f1c31a52d7d181ac5ec68e9b8" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types 0.8.9", + "cfg-if", + "derive_more 1.0.0", + "hashbrown 0.14.5", + "itertools 0.13.0", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "731f75ec5d383107fd745d781619bd9cedf145836c51ecb991623d41278e71fa" +dependencies = [ + "alloy-primitives 0.8.9", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" +dependencies = [ + "alloy-sol-macro-expander 0.7.7", + "alloy-sol-macro-input 0.7.7", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0900b83f4ee1f45c640ceee596afbc118051921b9438fdb5a3175c1a7e05f8b" +dependencies = [ + "alloy-sol-macro-expander 0.8.9", + "alloy-sol-macro-input 0.8.9", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" +dependencies = [ + "alloy-sol-macro-input 0.7.7", + "const-hex", + "heck", + "indexmap 2.6.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.85", + "syn-solidity 0.7.7", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41b1e78dde06b5e12e6702fa8c1d30621bf07728ba75b801fb801c9c6a0ba10" +dependencies = [ + "alloy-sol-macro-input 0.8.9", + "const-hex", + "heck", + "indexmap 2.6.0", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.85", + "syn-solidity 0.8.9", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro2", + "quote", + "syn 2.0.85", + "syn-solidity 0.7.7", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91dc311a561a306664393407b88d3e53ae58581624128afd8a15faa5de3627dc" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro2", + "quote", + "syn 2.0.85", + "syn-solidity 0.8.9", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45d1fbee9e698f3ba176b6e7a145f4aefe6d2b746b611e8bb246fe11a0e9f6c4" +dependencies = [ + "serde", + "winnow 0.6.20", +] + +[[package]] +name = "alloy-sol-types" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" +dependencies = [ + "alloy-primitives 0.7.7", + "alloy-sol-macro 0.7.7", + "const-hex", + "serde", +] + +[[package]] +name = "alloy-sol-types" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "086f41bc6ebcd8cb15f38ba20e47be38dd03692149681ce8061c35d960dbf850" +dependencies = [ + "alloy-json-abi", + "alloy-primitives 0.8.9", + "alloy-sol-macro 0.8.9", + "const-hex", + "serde", +] + +[[package]] +name = "alloy-trie" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a46c9c4fdccda7982e7928904bd85fe235a0404ee3d7e197fff13d61eac8b4f" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "derive_more 1.0.0", + "hashbrown 0.14.5", + "nybbles", + "serde", + "smallvec", + "tracing", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anstream" +version = "0.6.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint 0.4.6", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version 0.4.1", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "aurora-engine-modexp" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aef7712851e524f35fbbb74fa6599c5cd8692056a1c36f9ca0d2001b670e7e5" +dependencies = [ + "hex", + "num", +] + +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "axum" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.5.0", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.1", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "serde", + "windows-targets 0.52.6", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.85", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "serde", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +dependencies = [ + "arrayref", + "arrayvec 0.7.6", + "constant_time_eq", +] + +[[package]] +name = "blake3" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" +dependencies = [ + "arrayref", + "arrayvec 0.7.6", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "bls12381-program" +version = "1.1.0" +dependencies = [ + "bls12_381 0.8.0", + "ff 0.13.0", + "group 0.13.0", + "rand 0.8.5", + "sp1-zkvm", +] + +[[package]] +name = "bls12381-script" +version = "0.1.0" +dependencies = [ + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "bls12_381" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" +dependencies = [ + "ff 0.12.1", + "group 0.12.1", + "pairing 0.22.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "bls12_381" +version = "0.8.0" +source = "git+https://github.com/sp1-patches/bls12_381?branch=patch-v0.8.0#12f049691dc9165ccb1a0930327d2316976450a3" +dependencies = [ + "cfg-if", + "ff 0.13.0", + "group 0.13.0", + "pairing 0.23.0", + "rand_core 0.6.4", + "sp1-lib 1.2.0", + "subtle", +] + +[[package]] +name = "blst" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "bn254-program" +version = "1.1.0" +dependencies = [ + "rand 0.8.5", + "sp1-zkvm", + "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?rev=43d854d45b5727b1ff2b9f346d728e785bb8395c)", +] + +[[package]] +name = "bn254-script" +version = "0.1.0" +dependencies = [ + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "sha2 0.10.8", + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "bytemuck" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +dependencies = [ + "serde", +] + +[[package]] +name = "c-kzg" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" +dependencies = [ + "blst", + "cc", + "glob", + "hex", + "libc", + "once_cell", + "serde", +] + +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.23", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chess" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ed299b171ec34f372945ad6726f7bc1d2afd5f59fb8380f64f48e2bab2f0ec8" +dependencies = [ + "arrayvec 0.5.2", + "failure", + "nodrop", + "rand 0.7.3", +] + +[[package]] +name = "chess-program" +version = "1.1.0" +dependencies = [ + "chess", + "sp1-zkvm", +] + +[[package]] +name = "chess-script" +version = "1.1.0" +dependencies = [ + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets 0.52.6", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "coins-bip32" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" +dependencies = [ + "bs58", + "coins-core", + "digest 0.10.7", + "hmac", + "k256", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" +dependencies = [ + "bitvec", + "coins-bip32", + "hmac", + "once_cell", + "pbkdf2 0.12.2", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" +dependencies = [ + "base64 0.21.7", + "bech32", + "bs58", + "digest 0.10.7", + "generic-array 0.14.7", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2 0.10.8", + "sha3", + "thiserror", +] + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + +[[package]] +name = "const-hex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +dependencies = [ + "generic-array 0.14.7", + "subtle", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "git+https://github.com/sp1-patches/curve25519-dalek?branch=patch-curve25519-v4.1.3#1d73fd95f1a76bee8f46643cf78bbccc1fb06ede" +dependencies = [ + "anyhow", + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version 0.4.1", + "sp1-lib 1.2.0", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "git+https://github.com/sp1-patches/curve25519-dalek?branch=patch-curve25519-v4.1.3#1d73fd95f1a76bee8f46643cf78bbccc1fb06ede" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "git+https://github.com/sp1-patches/curve25519-dalek-ng?branch=patch-v4.1.1#8dd77b20f3e78965a0cc57070a04465b9d52c49e" +dependencies = [ + "anyhow", + "byteorder", + "cfg-if", + "digest 0.9.0", + "rand_core 0.6.4", + "sp1-lib 1.2.0", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "cycle-tracking-program" +version = "1.1.0" +dependencies = [ + "sp1-derive", + "sp1-zkvm", +] + +[[package]] +name = "cycle-tracking-script" +version = "1.1.0" +dependencies = [ + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.85", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "dashu" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b3e5ac1e23ff1995ef05b912e2b012a8784506987a2651552db2c73fb3d7e0" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-macros", + "dashu-ratio", + "rustversion", +] + +[[package]] +name = "dashu-base" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b80bf6b85aa68c58ffea2ddb040109943049ce3fbdf4385d0380aef08ef289" + +[[package]] +name = "dashu-float" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85078445a8dbd2e1bd21f04a816f352db8d333643f0c9b78ca7c3d1df71063e7" +dependencies = [ + "dashu-base", + "dashu-int", + "num-modular", + "num-order", + "rustversion", + "static_assertions", +] + +[[package]] +name = "dashu-int" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee99d08031ca34a4d044efbbb21dff9b8c54bb9d8c82a189187c0651ffdb9fbf" +dependencies = [ + "cfg-if", + "dashu-base", + "num-modular", + "num-order", + "rustversion", + "static_assertions", +] + +[[package]] +name = "dashu-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93381c3ef6366766f6e9ed9cf09e4ef9dec69499baf04f0c60e70d653cf0ab10" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "dashu-ratio", + "paste", + "proc-macro2", + "quote", + "rustversion", +] + +[[package]] +name = "dashu-ratio" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e33b04dd7ce1ccf8a02a69d3419e354f2bbfdf4eb911a0b7465487248764c9" +dependencies = [ + "dashu-base", + "dashu-float", + "dashu-int", + "num-modular", + "num-order", + "rustversion", +] + +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +dependencies = [ + "const-oid 0.7.1", + "crypto-bigint 0.3.2", + "pem-rfc7468 0.3.1", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid 0.9.6", + "pem-rfc7468 0.7.0", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version 0.4.1", + "syn 2.0.85", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.85", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid 0.9.6", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.9", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki 0.7.3", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "git+https://github.com/sp1-patches/signatures?branch=patch-ecdsa-v0.16.9#475daa8834035cc170a567e7656329ab8de8cc44" +dependencies = [ + "anyhow", + "cfg-if", + "digest 0.10.7", + "elliptic-curve", + "hex-literal", + "signature", + "sp1-lib 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "spki 0.7.3", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8 0.10.2", + "signature", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "git+https://github.com/sp1-patches/ed25519-consensus?branch=patch-v2.1.0#2b2c4b43344bc4daf5b1326f367f2d9d661eeabb" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "elf" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enr" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" +dependencies = [ + "base64 0.21.7", + "bytes", + "hex", + "k256", + "log", + "rand 0.8.5", + "rlp", + "serde", + "sha3", + "zeroize", +] + +[[package]] +name = "enr" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "972070166c68827e64bd1ebc8159dd8e32d9bc2da7ebe8f20b61308f7974ad30" +dependencies = [ + "alloy-rlp", + "base64 0.21.7", + "bytes", + "hex", + "log", + "rand 0.8.5", + "sha3", + "zeroize", +] + +[[package]] +name = "enum-map" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" +dependencies = [ + "enum-map-derive", + "serde", +] + +[[package]] +name = "enum-map-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "enumn" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest 0.10.7", + "hex", + "hmac", + "pbkdf2 0.11.0", + "rand 0.8.5", + "scrypt", + "serde", + "serde_json", + "sha2 0.10.8", + "sha3", + "thiserror", + "uuid", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" +dependencies = [ + "ethers-addressbook", + "ethers-contract", + "ethers-core", + "ethers-middleware", + "ethers-providers", + "ethers-signers", +] + +[[package]] +name = "ethers-addressbook" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" +dependencies = [ + "ethers-core", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "ethers-contract" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" +dependencies = [ + "const-hex", + "ethers-contract-abigen", + "ethers-contract-derive", + "ethers-core", + "ethers-providers", + "futures-util", + "once_cell", + "pin-project", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ethers-contract-abigen" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" +dependencies = [ + "Inflector", + "const-hex", + "dunce", + "ethers-core", + "eyre", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "serde", + "serde_json", + "syn 2.0.85", + "toml", + "walkdir", +] + +[[package]] +name = "ethers-contract-derive" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" +dependencies = [ + "Inflector", + "const-hex", + "ethers-contract-abigen", + "ethers-core", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.85", +] + +[[package]] +name = "ethers-core" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" +dependencies = [ + "arrayvec 0.7.6", + "bytes", + "cargo_metadata", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array 0.14.7", + "k256", + "num_enum 0.7.3", + "once_cell", + "open-fastrlp", + "rand 0.8.5", + "rlp", + "serde", + "serde_json", + "strum", + "syn 2.0.85", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "ethers-middleware" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" +dependencies = [ + "async-trait", + "auto_impl", + "ethers-contract", + "ethers-core", + "ethers-providers", + "ethers-signers", + "futures-channel", + "futures-locks", + "futures-util", + "instant", + "reqwest 0.11.27", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", +] + +[[package]] +name = "ethers-providers" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" +dependencies = [ + "async-trait", + "auto_impl", + "base64 0.21.7", + "bytes", + "const-hex", + "enr 0.10.0", + "ethers-core", + "futures-core", + "futures-timer", + "futures-util", + "hashers", + "http 0.2.12", + "instant", + "jsonwebtoken", + "once_cell", + "pin-project", + "reqwest 0.11.27", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "ws_stream_wasm", +] + +[[package]] +name = "ethers-signers" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" +dependencies = [ + "async-trait", + "coins-bip32", + "coins-bip39", + "const-hex", + "elliptic-curve", + "eth-keystore", + "ethers-core", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", + "tracing", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure", +] + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec 0.7.6", + "auto_impl", + "bytes", +] + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "bitvec", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "byteorder", + "ff_derive", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff_derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f54704be45ed286151c5e11531316eaef5b8f5af7d597b806fdb8af108d84a" +dependencies = [ + "addchain", + "cfg-if", + "num-bigint 0.3.3", + "num-integer", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "fibonacci-program" +version = "1.1.0" +dependencies = [ + "sp1-zkvm", +] + +[[package]] +name = "fibonacci-script" +version = "1.1.0" +dependencies = [ + "hex", + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "flex-error" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" +dependencies = [ + "paste", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-locks" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" +dependencies = [ + "futures-channel", + "futures-task", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers", + "send_wrapper 0.4.0", +] + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "generic-array" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96512db27971c2c3eece70a1e106fbe6c87760234e31e8f7e5634912fe52794a" +dependencies = [ + "serde", + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libgit2-sys", + "log", + "url", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "groth16-verifier-program" +version = "1.1.0" +dependencies = [ + "sp1-verifier", + "sp1-zkvm", +] + +[[package]] +name = "groth16-verifier-script" +version = "1.1.0" +dependencies = [ + "hex", + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "memuse", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + +[[package]] +name = "halo2" +version = "0.1.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a23c779b38253fe1538102da44ad5bd5378495a61d2c4ee18d64eaa61ae5995" +dependencies = [ + "halo2_proofs", +] + +[[package]] +name = "halo2_proofs" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e925780549adee8364c7f2b685c753f6f3df23bde520c67416e93bf615933760" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "pasta_curves 0.4.1", + "rand_core 0.6.4", + "rayon", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", + "serde", +] + +[[package]] +name = "hashers" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.5.0", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.31", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.5.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.5.0", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.0", + "serde", +] + +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-program" +version = "1.1.0" +dependencies = [ + "serde", + "sp1-zkvm", +] + +[[package]] +name = "io-script" +version = "1.1.0" +dependencies = [ + "serde", + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "ipnet" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" + +[[package]] +name = "is-prime-program" +version = "1.1.0" +dependencies = [ + "sp1-zkvm", +] + +[[package]] +name = "is-prime-script" +version = "1.1.0" +dependencies = [ + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json-lib" +version = "1.1.0" +dependencies = [ + "serde", +] + +[[package]] +name = "json-program" +version = "1.1.0" +dependencies = [ + "json-lib", + "serde_json", + "sp1-zkvm", +] + +[[package]] +name = "json-script" +version = "1.1.0" +dependencies = [ + "json-lib", + "serde_json", + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.7", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "jubjub" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" +dependencies = [ + "bitvec", + "bls12_381 0.7.1", + "ff 0.12.1", + "group 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve", + "once_cell", + "sha2 0.10.8", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + +[[package]] +name = "kzg-rs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850eb19206463a61bede4f7b7e6b21731807137619044b1f3c287ebcfe2b3b0" +dependencies = [ + "ff 0.13.0", + "hex", + "sha2 0.10.8", + "sp1_bls12_381", + "spin 0.9.8", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", +] + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] + +[[package]] +name = "libm" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bda4c6077b0b08da2c48b172195795498381a7c8988c9e6212a6c55c5b9bd70" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.0", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memuse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "modular-bitfield" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" +dependencies = [ + "modular-bitfield-impl", + "static_assertions", +] + +[[package]] +name = "modular-bitfield-impl" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint 0.4.6", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17bb261bf36fa7d83f4c294f834e91256769097b3cb505d44831e0a179ac647f" + +[[package]] +name = "num-order" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b596b97c40fcf8056d153049eb22f481c17ebce72a513ec9286e4986d1bb6" +dependencies = [ + "num-modular", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint 0.4.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive 0.7.3", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "nybbles" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95f06be0417d97f81fe4e5c86d7d01b392655a9cac9c19a848aa033e18937b23" +dependencies = [ + "alloy-rlp", + "const-hex", + "proptest", + "serde", + "smallvec", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "op-alloy-consensus" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21aad1fbf80d2bcd7406880efc7ba109365f44bbb72896758ddcbfa46bf1592c" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-serde", + "derive_more 1.0.0", + "serde", + "spin 0.9.8", +] + +[[package]] +name = "op-alloy-rpc-types" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e281fbfc2198b7c0c16457d6524f83d192662bc9f3df70f24c3038d4521616df" +dependencies = [ + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives 0.8.9", + "alloy-rpc-types-eth", + "alloy-serde", + "cfg-if", + "hashbrown 0.14.5", + "op-alloy-consensus", + "serde", + "serde_json", +] + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec 0.7.6", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "openssl" +version = "0.10.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "elliptic-curve", + "primeorder", + "sha2 0.10.8", +] + +[[package]] +name = "p3-air" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "066f571b2e645505ed5972dd0e1e252ba03352150830c9566769ca711c0f1e9b" +dependencies = [ + "p3-field", + "p3-matrix", +] + +[[package]] +name = "p3-baby-bear" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff00f571044d299310d9659c6e51c98422de3bf94b8577f7f30cf59cf2043e40" +dependencies = [ + "num-bigint 0.4.6", + "p3-field", + "p3-mds", + "p3-poseidon2", + "p3-symmetric", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-blake3" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4cb69ae54a279bbbd477566d1bdb71aa879b528fd658d0fcfc36f54b00217c" +dependencies = [ + "blake3", + "p3-symmetric", +] + +[[package]] +name = "p3-bn254-fr" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf19917f986d45e9abb6d177e875824ced6eed096480d574fce16f2c45c721ea" +dependencies = [ + "ff 0.13.0", + "num-bigint 0.4.6", + "p3-field", + "p3-poseidon2", + "p3-symmetric", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-challenger" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be7e4fbce4566a93091107eadfafa0b5374bd1ffd3e0f6b850da3ff72eb183f" +dependencies = [ + "p3-field", + "p3-maybe-rayon", + "p3-symmetric", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-commit" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a03eb0f99d68a712c41e658e9a7782a0705d4ffcfb6232a43bd3f1ef9591002" +dependencies = [ + "itertools 0.12.1", + "p3-challenger", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-util", + "serde", +] + +[[package]] +name = "p3-dft" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1556de968523fbe5d804ab50600ea306fcceea3500cfd7601e40882480524664" +dependencies = [ + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "tracing", +] + +[[package]] +name = "p3-field" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cec2af6e1ac47a2035af5165e668d64612c4b9ccabd06df37fc1fd381fdf8a71" +dependencies = [ + "itertools 0.12.1", + "num-bigint 0.4.6", + "num-traits", + "p3-util", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-fri" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f351ee9f9d4256455164565cd91e3e6d2487cc2a5355515fa2b6d479269188dd" +dependencies = [ + "itertools 0.12.1", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-interpolation", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-interpolation" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24d0f2907a374ebe4545fcff3120d6376d9630cf0bef30feedcfc5908ea2c37" +dependencies = [ + "p3-field", + "p3-matrix", + "p3-util", +] + +[[package]] +name = "p3-keccak-air" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e66badd47cedf6570e91a0cabc389b80dfd53ba1a6e9a45a3923fd54b86122ff" +dependencies = [ + "p3-air", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "tracing", +] + +[[package]] +name = "p3-matrix" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa272f3ae77ed8d73478aa7c89e712efb15bda3ff4aff10fadfe11a012cd5389" +dependencies = [ + "itertools 0.12.1", + "p3-field", + "p3-maybe-rayon", + "p3-util", + "rand 0.8.5", + "serde", + "tracing", +] + +[[package]] +name = "p3-maybe-rayon" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eecad6292021858f282d643d9d1284ab112a200494d589863a9c4080e578ef0" +dependencies = [ + "rayon", +] + +[[package]] +name = "p3-mds" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "716c4dbe68a02f1541eb09149d07b8663a3a5951b1864a31cd67ff3bb0826e57" +dependencies = [ + "itertools 0.12.1", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-symmetric", + "p3-util", + "rand 0.8.5", +] + +[[package]] +name = "p3-merkle-tree" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad7ebab52a03c26025988663a135aed62f5084a2e2ea262176dc8748efb593e5" +dependencies = [ + "itertools 0.12.1", + "p3-commit", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-symmetric", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-poseidon2" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c042efa15beab7a8c4d0ca9b9e4cbda7582be0c08e121e830fec45f082935b" +dependencies = [ + "gcd", + "p3-field", + "p3-mds", + "p3-symmetric", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "p3-symmetric" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9896a831f5b688adc13f6fbe1dcf66ecfaa4622a500f81aa745610e777acb72" +dependencies = [ + "itertools 0.12.1", + "p3-field", + "serde", +] + +[[package]] +name = "p3-uni-stark" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437ebcd060c8a5479898030b114a93da8a86eb4c2e5f313d9eeaaf40c6e6f61" +dependencies = [ + "itertools 0.12.1", + "p3-air", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-matrix", + "p3-maybe-rayon", + "p3-util", + "serde", + "tracing", +] + +[[package]] +name = "p3-util" +version = "0.1.4-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dedb9d27ba47ac314c6fac4ca54e55c3e486c864d51ec5ba55dbe47b75121157" +dependencies = [ + "serde", +] + +[[package]] +name = "pairing" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" +dependencies = [ + "group 0.12.1", +] + +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group 0.13.0", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec 0.7.6", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "pasta_curves" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc65faf8e7313b4b1fbaa9f7ca917a0eed499a9663be71477f87993604341d8" +dependencies = [ + "blake2b_simd", + "ff 0.12.1", + "group 0.12.1", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + +[[package]] +name = "pasta_curves" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" +dependencies = [ + "blake2b_simd", + "ff 0.13.0", + "group 0.13.0", + "lazy_static", + "rand 0.8.5", + "static_assertions", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "patch-testing-program" +version = "1.1.0" +dependencies = [ + "alloy-primitives 0.8.9", + "curve25519-dalek", + "curve25519-dalek-ng", + "ed25519-consensus", + "ed25519-dalek", + "revm-precompile", + "secp256k1", + "sha2 0.10.8", + "sha2 0.9.9", + "sp1-zkvm", + "tiny-keccak", +] + +[[package]] +name = "patch-testing-script" +version = "1.1.0" +dependencies = [ + "sp1-build", + "sp1-core-executor", + "sp1-sdk", +] + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac", +] + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "pem-rfc7468" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version 0.4.1", +] + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78f66c04ccc83dd4486fd46c33896f4e17b24a7a3a6400dedc48ed0ddd72320" +dependencies = [ + "der 0.5.1", + "pkcs8 0.8.0", + "zeroize", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.9", + "pkcs8 0.10.2", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der 0.5.1", + "spki 0.5.4", + "zeroize", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.9", + "spki 0.7.3", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.85", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit 0.22.22", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.6.0", + "lazy_static", + "num-traits", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax 0.8.5", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "prost" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +dependencies = [ + "bytes", + "prost-derive 0.12.6", +] + +[[package]] +name = "prost" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" +dependencies = [ + "bytes", + "prost-derive 0.13.3", +] + +[[package]] +name = "prost-derive" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +dependencies = [ + "anyhow", + "itertools 0.12.1", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "prost-derive" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" +dependencies = [ + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "prost-types" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +dependencies = [ + "prost 0.12.6", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quinn" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.0.0", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring 0.17.8", + "rustc-hash 2.0.0", + "rustls", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +dependencies = [ + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rayon-scan" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f87cc11a0140b4b0da0ffc889885760c61b13672d80a908920b2c0df078fa14" +dependencies = [ + "rayon", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-program" +version = "1.1.0" +dependencies = [ + "regex", + "sp1-zkvm", +] + +[[package]] +name = "regex-script" +version = "1.1.0" +dependencies = [ + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.31", + "hyper-tls 0.5.0", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration 0.5.1", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "reqwest" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.5.0", + "hyper-rustls", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pemfile 2.2.0", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "system-configuration 0.6.1", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "windows-registry", +] + +[[package]] +name = "reqwest-middleware" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04" +dependencies = [ + "anyhow", + "async-trait", + "http 1.1.0", + "reqwest 0.12.8", + "serde", + "thiserror", + "tower-service", +] + +[[package]] +name = "reth-blockchain-tree-api" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "reth-consensus", + "reth-execution-errors", + "reth-primitives", + "reth-storage-errors", + "thiserror", +] + +[[package]] +name = "reth-chainspec" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-chains", + "alloy-eips", + "alloy-genesis", + "alloy-primitives 0.8.9", + "alloy-trie", + "auto_impl", + "derive_more 1.0.0", + "once_cell", + "op-alloy-rpc-types", + "reth-ethereum-forks", + "reth-network-peers", + "reth-primitives-traits", + "reth-trie-common", + "serde", + "serde_json", +] + +[[package]] +name = "reth-codecs" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-genesis", + "alloy-primitives 0.8.9", + "alloy-trie", + "bytes", + "modular-bitfield", + "reth-codecs-derive", + "serde", +] + +[[package]] +name = "reth-codecs-derive" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "reth-consensus" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "auto_impl", + "derive_more 1.0.0", + "reth-primitives", +] + +[[package]] +name = "reth-consensus-common" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "reth-chainspec", + "reth-consensus", + "reth-primitives", +] + +[[package]] +name = "reth-db-models" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "bytes", + "modular-bitfield", + "reth-codecs", + "reth-primitives", + "serde", +] + +[[package]] +name = "reth-errors" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "reth-blockchain-tree-api", + "reth-consensus", + "reth-execution-errors", + "reth-fs-util", + "reth-storage-errors", + "thiserror", +] + +[[package]] +name = "reth-ethereum-consensus" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "reth-chainspec", + "reth-consensus", + "reth-consensus-common", + "reth-primitives", + "tracing", +] + +[[package]] +name = "reth-ethereum-forks" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-chains", + "alloy-primitives 0.8.9", + "alloy-rlp", + "auto_impl", + "crc", + "dyn-clone", + "once_cell", + "rustc-hash 2.0.0", + "serde", + "thiserror-no-std", +] + +[[package]] +name = "reth-evm" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-eips", + "auto_impl", + "futures-util", + "reth-chainspec", + "reth-execution-errors", + "reth-execution-types", + "reth-primitives", + "reth-prune-types", + "reth-storage-errors", + "revm", + "revm-primitives", +] + +[[package]] +name = "reth-evm-ethereum" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-eips", + "alloy-sol-types 0.8.9", + "reth-chainspec", + "reth-ethereum-consensus", + "reth-ethereum-forks", + "reth-evm", + "reth-execution-types", + "reth-primitives", + "reth-prune-types", + "reth-revm", + "revm-primitives", +] + +[[package]] +name = "reth-evm-optimism" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "reth-chainspec", + "reth-ethereum-forks", + "reth-evm", + "reth-execution-errors", + "reth-execution-types", + "reth-optimism-consensus", + "reth-primitives", + "reth-prune-types", + "reth-revm", + "revm", + "revm-primitives", + "thiserror", + "tracing", +] + +[[package]] +name = "reth-execution-errors" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-eips", + "alloy-primitives 0.8.9", + "alloy-rlp", + "derive_more 1.0.0", + "nybbles", + "reth-consensus", + "reth-prune-types", + "reth-storage-errors", + "revm-primitives", +] + +[[package]] +name = "reth-execution-types" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "reth-chainspec", + "reth-execution-errors", + "reth-primitives", + "reth-trie", + "revm", +] + +[[package]] +name = "reth-fs-util" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "reth-network-peers" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "enr 0.12.1", + "serde_with", + "thiserror", + "url", +] + +[[package]] +name = "reth-optimism-chainspec" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-chains", + "alloy-primitives 0.8.9", + "derive_more 1.0.0", + "once_cell", + "reth-chainspec", + "reth-ethereum-forks", + "reth-primitives-traits", + "serde_json", +] + +[[package]] +name = "reth-optimism-consensus" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "reth-chainspec", + "reth-consensus", + "reth-consensus-common", + "reth-primitives", + "tracing", +] + +[[package]] +name = "reth-primitives" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-genesis", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-rpc-types", + "alloy-serde", + "bytes", + "derive_more 1.0.0", + "k256", + "once_cell", + "op-alloy-rpc-types", + "rayon", + "reth-chainspec", + "reth-ethereum-forks", + "reth-optimism-chainspec", + "reth-primitives-traits", + "reth-static-file-types", + "reth-trie-common", + "revm-primitives", + "serde", + "thiserror", +] + +[[package]] +name = "reth-primitives-traits" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-genesis", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-rpc-types-eth", + "byteorder", + "bytes", + "derive_more 1.0.0", + "modular-bitfield", + "reth-codecs", + "revm-primitives", + "roaring", + "serde", +] + +[[package]] +name = "reth-prune-types" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-primitives 0.8.9", + "bytes", + "derive_more 1.0.0", + "modular-bitfield", + "reth-codecs", + "serde", + "thiserror", +] + +[[package]] +name = "reth-revm" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "reth-chainspec", + "reth-consensus-common", + "reth-execution-errors", + "reth-primitives", + "reth-prune-types", + "reth-storage-api", + "reth-storage-errors", + "revm", +] + +[[package]] +name = "reth-stages-types" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-primitives 0.8.9", + "bytes", + "modular-bitfield", + "reth-codecs", + "reth-trie-common", + "serde", +] + +[[package]] +name = "reth-static-file-types" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-primitives 0.8.9", + "derive_more 1.0.0", + "serde", + "strum", +] + +[[package]] +name = "reth-storage-api" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "auto_impl", + "reth-chainspec", + "reth-db-models", + "reth-execution-types", + "reth-primitives", + "reth-prune-types", + "reth-stages-types", + "reth-storage-errors", + "reth-trie", +] + +[[package]] +name = "reth-storage-errors" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-rlp", + "derive_more 1.0.0", + "reth-fs-util", + "reth-primitives", +] + +[[package]] +name = "reth-trie" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-rlp", + "auto_impl", + "derive_more 1.0.0", + "itertools 0.13.0", + "rayon", + "reth-execution-errors", + "reth-primitives", + "reth-stages-types", + "reth-storage-errors", + "reth-trie-common", + "revm", + "tracing", +] + +[[package]] +name = "reth-trie-common" +version = "1.0.6" +source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" +dependencies = [ + "alloy-consensus", + "alloy-genesis", + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-trie", + "bytes", + "derive_more 1.0.0", + "itertools 0.13.0", + "nybbles", + "reth-codecs", + "reth-primitives-traits", + "revm-primitives", + "serde", +] + +[[package]] +name = "revm" +version = "14.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f719e28cc6fdd086f8bc481429e587740d20ad89729cec3f5f5dd7b655474df" +dependencies = [ + "auto_impl", + "cfg-if", + "dyn-clone", + "revm-interpreter", + "revm-precompile", + "serde", + "serde_json", +] + +[[package]] +name = "revm-interpreter" +version = "10.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "959ecbc36802de6126852479844737f20194cf8e6718e0c30697d306a2cca916" +dependencies = [ + "revm-primitives", + "serde", +] + +[[package]] +name = "revm-precompile" +version = "11.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e25f604cb9db593ca3013be8c00f310d6790ccb1b7d8fbbdd4660ec8888043a" +dependencies = [ + "aurora-engine-modexp", + "c-kzg", + "cfg-if", + "k256", + "kzg-rs", + "once_cell", + "p256", + "revm-primitives", + "ripemd", + "secp256k1", + "sha2 0.10.8", + "substrate-bn 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "revm-primitives" +version = "9.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a6bff9dbde3370a5ac9555104117f7e6039b3cc76e8d5d9d01899088beca2a" +dependencies = [ + "alloy-eips", + "alloy-primitives 0.8.9", + "auto_impl", + "bitflags 2.6.0", + "bitvec", + "c-kzg", + "cfg-if", + "dyn-clone", + "enumn", + "hashbrown 0.14.5", + "hex", + "kzg-rs", + "serde", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "roaring" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4b84ba6e838ceb47b41de5194a60244fac43d9fe03b71dbe8c5a201081d6d1" +dependencies = [ + "bytemuck", + "byteorder", +] + +[[package]] +name = "rrs-succinct" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3372685893a9f67d18e98e792d690017287fd17379a83d798d958e517d380fa9" +dependencies = [ + "downcast-rs", + "num_enum 0.5.11", + "paste", +] + +[[package]] +name = "rsa" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf22754c49613d2b3b119f0e5d46e34a2c628a937e3024b8762de4e7d8c710b" +dependencies = [ + "byteorder", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1 0.3.3", + "pkcs8 0.8.0", + "rand_core 0.6.4", + "smallvec", + "subtle", + "zeroize", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid 0.9.6", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1 0.7.5", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "signature", + "spki 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "rsa-program" +version = "1.1.0" +dependencies = [ + "rsa 0.9.6", + "sha2 0.10.8", + "sp1-zkvm", +] + +[[package]] +name = "rsa-script" +version = "1.1.0" +dependencies = [ + "rsa 0.6.1", + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "rsp-client-executor" +version = "0.1.0" +source = "git+https://github.com/succinctlabs/rsp/?rev=3647076#3647076da6580e30384dd911a3fc50d4bcdb5bc1" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "eyre", + "futures", + "itertools 0.13.0", + "reth-chainspec", + "reth-errors", + "reth-ethereum-consensus", + "reth-evm", + "reth-evm-ethereum", + "reth-evm-optimism", + "reth-execution-types", + "reth-optimism-consensus", + "reth-primitives", + "reth-revm", + "reth-storage-errors", + "reth-trie", + "revm", + "revm-primitives", + "rsp-mpt", + "rsp-primitives", + "rsp-witness-db", + "serde", + "serde_json", + "tokio", + "url", +] + +[[package]] +name = "rsp-mpt" +version = "0.1.0" +source = "git+https://github.com/succinctlabs/rsp/?rev=3647076#3647076da6580e30384dd911a3fc50d4bcdb5bc1" +dependencies = [ + "alloy-primitives 0.8.9", + "alloy-rlp", + "alloy-rpc-types", + "anyhow", + "eyre", + "itertools 0.13.0", + "reth-execution-types", + "reth-primitives", + "reth-trie", + "revm", + "revm-primitives", + "rlp", + "rsp-primitives", + "serde", + "thiserror", +] + +[[package]] +name = "rsp-primitives" +version = "0.1.0" +source = "git+https://github.com/succinctlabs/rsp/?rev=3647076#3647076da6580e30384dd911a3fc50d4bcdb5bc1" +dependencies = [ + "alloy-rpc-types", + "eyre", + "reth-chainspec", + "reth-optimism-chainspec", + "reth-primitives", + "reth-revm", + "reth-trie", + "revm-interpreter", + "revm-precompile", + "revm-primitives", + "serde", + "serde_json", + "tracing", +] + +[[package]] +name = "rsp-program" +version = "1.1.0" +dependencies = [ + "bincode", + "rsp-client-executor", + "sp1-zkvm", +] + +[[package]] +name = "rsp-script" +version = "0.1.0" +dependencies = [ + "alloy-primitives 0.8.9", + "bincode", + "clap", + "rsp-client-executor", + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "rsp-witness-db" +version = "0.1.0" +source = "git+https://github.com/succinctlabs/rsp/?rev=3647076#3647076da6580e30384dd911a3fc50d4bcdb5bc1" +dependencies = [ + "reth-primitives", + "reth-storage-errors", + "revm-primitives", + "rsp-primitives", + "serde", +] + +[[package]] +name = "ruint" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint 0.4.6", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand 0.8.5", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustix" +version = "0.38.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.23.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" +dependencies = [ + "once_cell", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" +dependencies = [ + "cfg-if", + "derive_more 1.0.0", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" +dependencies = [ + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "scc" +version = "2.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d25269dd3a12467afe2e510f69fb0b46b698e5afb296b59f2145259deaf8e8" +dependencies = [ + "sdd", +] + +[[package]] +name = "schannel" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac", + "pbkdf2 0.11.0", + "salsa20", + "sha2 0.10.8", +] + +[[package]] +name = "sdd" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der 0.7.9", + "generic-array 0.14.7", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.29.0" +source = "git+https://github.com/sp1-patches/rust-secp256k1?branch=patch-secp256k1-v0.29.0#13910d476dbdaf436312a9f096ee312593028557" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9 (git+https://github.com/sp1-patches/signatures?branch=patch-ecdsa-v0.16.9)", + "elliptic-curve", + "k256", + "rand 0.8.5", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.0" +source = "git+https://github.com/sp1-patches/rust-secp256k1?branch=patch-secp256k1-v0.29.0#13910d476dbdaf436312a9f096ee312593028557" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +dependencies = [ + "serde", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "indexmap 2.6.0", + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +dependencies = [ + "itoa", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.6.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "serial_test" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b4b487fe2acf240a021cf57c6b2b4903b1e78ca0ecd862a71b71d2a51fed77d" +dependencies = [ + "futures", + "log", + "once_cell", + "parking_lot", + "scc", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "sha2" +version = "0.9.8" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes.git?branch=patch-v0.9.8#afdbfb09c325f8a69c01d540ec9a261e3637725d" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-sha2-v0.9.9#db82a4848f8d033eab544255e1efa036cc06f054" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-v0.10.8#1f224388fdede7cef649bce0d63876d1a9e3f515" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" +dependencies = [ + "cc", + "cfg-if", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "size" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fed904c7fb2856d868b92464fc8fa597fce366edea1a9cbfaa8cb5fe080bd6d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] + +[[package]] +name = "snowbridge-amcl" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460a9ed63cdf03c1b9847e8a12a5f5ba19c4efd5869e4a737e05be25d7c427e5" +dependencies = [ + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "sp1-build" +version = "3.0.0" +dependencies = [ + "anyhow", + "cargo_metadata", + "chrono", + "clap", + "dirs", +] + +[[package]] +name = "sp1-core-executor" +version = "3.0.0" +dependencies = [ + "bincode", + "bytemuck", + "elf", + "enum-map", + "eyre", + "hashbrown 0.14.5", + "hex", + "itertools 0.13.0", + "log", + "nohash-hasher", + "num", + "p3-field", + "p3-maybe-rayon", + "rand 0.8.5", + "rrs-succinct", + "serde", + "sp1-curves", + "sp1-primitives", + "sp1-stark", + "strum", + "strum_macros", + "thiserror", + "tiny-keccak", + "tracing", + "typenum", + "vec_map", +] + +[[package]] +name = "sp1-core-machine" +version = "3.0.0" +dependencies = [ + "bincode", + "cfg-if", + "elliptic-curve", + "generic-array 1.1.0", + "hashbrown 0.14.5", + "hex", + "itertools 0.13.0", + "k256", + "log", + "num", + "num_cpus", + "p3-air", + "p3-baby-bear", + "p3-blake3", + "p3-challenger", + "p3-field", + "p3-keccak-air", + "p3-matrix", + "p3-maybe-rayon", + "p3-uni-stark", + "p3-util", + "rand 0.8.5", + "serde", + "size", + "snowbridge-amcl", + "sp1-core-executor", + "sp1-curves", + "sp1-derive", + "sp1-primitives", + "sp1-stark", + "static_assertions", + "strum", + "strum_macros", + "tempfile", + "thiserror", + "tracing", + "tracing-forest", + "tracing-subscriber", + "typenum", + "web-time", +] + +[[package]] +name = "sp1-cuda" +version = "3.0.0" +dependencies = [ + "bincode", + "ctrlc", + "prost 0.13.3", + "serde", + "sp1-core-machine", + "sp1-prover", + "tokio", + "tracing", + "twirp-rs", +] + +[[package]] +name = "sp1-curves" +version = "3.0.0" +dependencies = [ + "cfg-if", + "curve25519-dalek", + "dashu", + "elliptic-curve", + "generic-array 1.1.0", + "itertools 0.13.0", + "k256", + "num", + "p3-field", + "serde", + "snowbridge-amcl", + "sp1-primitives", + "sp1-stark", + "typenum", +] + +[[package]] +name = "sp1-derive" +version = "3.0.0" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sp1-lib" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea7811abd2d3a991007fcb284f41152840b8388c171288d0c52c6793956609c" +dependencies = [ + "anyhow", + "bincode", + "cfg-if", + "hex", + "serde", + "snowbridge-amcl", +] + +[[package]] +name = "sp1-lib" +version = "3.0.0" +dependencies = [ + "bincode", + "serde", +] + +[[package]] +name = "sp1-lib" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c372b16988e765af85ccf958b18b26d89c05886f2592d313a285415dcc769cb" +dependencies = [ + "bincode", + "serde", +] + +[[package]] +name = "sp1-lib" +version = "3.0.0" +source = "git+https://github.com/succinctlabs/sp1.git?branch=dev#b5c6a41816db138a84371178a84538356cd9addd" +dependencies = [ + "bincode", + "serde", +] + +[[package]] +name = "sp1-primitives" +version = "3.0.0" +dependencies = [ + "bincode", + "hex", + "lazy_static", + "num-bigint 0.4.6", + "p3-baby-bear", + "p3-field", + "p3-poseidon2", + "p3-symmetric", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "sp1-prover" +version = "3.0.0" +dependencies = [ + "anyhow", + "bincode", + "clap", + "dirs", + "eyre", + "itertools 0.13.0", + "lazy_static", + "lru", + "num-bigint 0.4.6", + "p3-baby-bear", + "p3-bn254-fr", + "p3-challenger", + "p3-commit", + "p3-field", + "p3-matrix", + "p3-symmetric", + "rayon", + "reqwest 0.11.27", + "serde", + "serde_json", + "serial_test", + "sp1-core-executor", + "sp1-core-machine", + "sp1-primitives", + "sp1-recursion-circuit", + "sp1-recursion-compiler", + "sp1-recursion-core", + "sp1-recursion-gnark-ffi", + "sp1-stark", + "subtle-encoding", + "tempfile", + "thiserror", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "sp1-recursion-circuit" +version = "3.0.0" +dependencies = [ + "hashbrown 0.14.5", + "itertools 0.13.0", + "num-traits", + "p3-air", + "p3-baby-bear", + "p3-bn254-fr", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-fri", + "p3-matrix", + "p3-symmetric", + "p3-util", + "rand 0.8.5", + "rayon", + "serde", + "sp1-core-executor", + "sp1-core-machine", + "sp1-derive", + "sp1-primitives", + "sp1-recursion-compiler", + "sp1-recursion-core", + "sp1-recursion-gnark-ffi", + "sp1-stark", + "tracing", +] + +[[package]] +name = "sp1-recursion-compiler" +version = "3.0.0" +dependencies = [ + "backtrace", + "itertools 0.13.0", + "p3-baby-bear", + "p3-bn254-fr", + "p3-field", + "p3-symmetric", + "serde", + "sp1-core-machine", + "sp1-primitives", + "sp1-recursion-core", + "sp1-recursion-derive", + "sp1-stark", + "tracing", + "vec_map", +] + +[[package]] +name = "sp1-recursion-core" +version = "3.0.0" +dependencies = [ + "backtrace", + "ff 0.13.0", + "hashbrown 0.14.5", + "itertools 0.13.0", + "p3-air", + "p3-baby-bear", + "p3-bn254-fr", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-fri", + "p3-matrix", + "p3-maybe-rayon", + "p3-merkle-tree", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "serde", + "sp1-core-machine", + "sp1-derive", + "sp1-primitives", + "sp1-stark", + "static_assertions", + "thiserror", + "tracing", + "vec_map", + "zkhash", +] + +[[package]] +name = "sp1-recursion-derive" +version = "3.0.0" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "sp1-recursion-gnark-ffi" +version = "3.0.0" +dependencies = [ + "anyhow", + "bincode", + "bindgen", + "cc", + "cfg-if", + "hex", + "log", + "num-bigint 0.4.6", + "p3-baby-bear", + "p3-field", + "p3-symmetric", + "serde", + "serde_json", + "sha2 0.10.8", + "sp1-core-machine", + "sp1-recursion-compiler", + "sp1-stark", + "tempfile", +] + +[[package]] +name = "sp1-sdk" +version = "3.0.0" +dependencies = [ + "alloy-sol-types 0.7.7", + "anyhow", + "async-trait", + "bincode", + "cfg-if", + "dirs", + "ethers", + "futures", + "hashbrown 0.14.5", + "hex", + "indicatif", + "itertools 0.13.0", + "log", + "p3-baby-bear", + "p3-field", + "p3-fri", + "prost 0.13.3", + "reqwest 0.12.8", + "reqwest-middleware", + "serde", + "sp1-core-executor", + "sp1-core-machine", + "sp1-cuda", + "sp1-primitives", + "sp1-prover", + "sp1-stark", + "strum", + "strum_macros", + "tempfile", + "thiserror", + "tokio", + "tracing", + "twirp-rs", + "vergen", +] + +[[package]] +name = "sp1-stark" +version = "3.0.0" +dependencies = [ + "arrayref", + "getrandom", + "hashbrown 0.14.5", + "itertools 0.13.0", + "num-traits", + "p3-air", + "p3-baby-bear", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-fri", + "p3-matrix", + "p3-maybe-rayon", + "p3-merkle-tree", + "p3-poseidon2", + "p3-symmetric", + "p3-uni-stark", + "p3-util", + "rayon-scan", + "serde", + "sp1-derive", + "sp1-primitives", + "strum", + "strum_macros", + "sysinfo", + "thiserror", + "tracing", +] + +[[package]] +name = "sp1-verifier" +version = "3.0.0" +dependencies = [ + "hex", + "lazy_static", + "sha2 0.10.8", + "substrate-bn 0.6.0 (git+https://github.com/yuwen01/bn?branch=yuwen/sp1-flag)", + "thiserror-no-std", +] + +[[package]] +name = "sp1-zkvm" +version = "3.0.0" +dependencies = [ + "cfg-if", + "getrandom", + "lazy_static", + "libm", + "p3-baby-bear", + "p3-field", + "rand 0.8.5", + "sha2 0.10.8", + "sp1-lib 3.0.0", + "sp1-primitives", +] + +[[package]] +name = "sp1_bls12_381" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a27c4b8901334dc09099dd82f80a72ddfc76b0046f4b342584c808f1931bed5a" +dependencies = [ + "cfg-if", + "ff 0.13.0", + "group 0.13.0", + "pairing 0.23.0", + "rand_core 0.6.4", + "sp1-lib 1.2.0", + "subtle", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +dependencies = [ + "base64ct", + "der 0.5.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.9", +] + +[[package]] +name = "ssz-withdrawals-program" +version = "1.1.0" +dependencies = [ + "alloy-primitives 0.6.4", + "hex", + "hex-literal", + "serde", + "serde_with", + "sha2 0.9.8", + "sp1-zkvm", + "ssz_rs", +] + +[[package]] +name = "ssz-withdrawals-script" +version = "1.1.0" +dependencies = [ + "sp1-build", + "sp1-sdk", +] + +[[package]] +name = "ssz_rs" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057291e5631f280978fa9c8009390663ca4613359fc1318e36a8c24c392f6d1f" +dependencies = [ + "bitvec", + "hex", + "num-bigint 0.4.6", + "serde", + "sha2 0.9.9", + "ssz_rs_derive", +] + +[[package]] +name = "ssz_rs_derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f07d54c4d01a1713eb363b55ba51595da15f6f1211435b71466460da022aa140" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.85", +] + +[[package]] +name = "substrate-bn" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b5bbfa79abbae15dd642ea8176a21a635ff3c00059961d1ea27ad04e5b441c" +dependencies = [ + "byteorder", + "crunchy", + "lazy_static", + "rand 0.8.5", + "rustc-hex", +] + +[[package]] +name = "substrate-bn" +version = "0.6.0" +source = "git+https://github.com/yuwen01/bn?branch=yuwen/sp1-flag#d5c1270f612fcaa7107e5b3a5686df8fed78cc3b" +dependencies = [ + "bytemuck", + "byteorder", + "cfg-if", + "crunchy", + "lazy_static", + "num-bigint 0.4.6", + "rand 0.8.5", + "rustc-hex", + "sp1-lib 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "substrate-bn" +version = "0.6.0" +source = "git+https://github.com/sp1-patches/bn?rev=43d854d45b5727b1ff2b9f346d728e785bb8395c#43d854d45b5727b1ff2b9f346d728e785bb8395c" +dependencies = [ + "bytemuck", + "byteorder", + "cfg-if", + "crunchy", + "lazy_static", + "rand 0.8.5", + "rustc-hex", + "sp1-lib 3.0.0 (git+https://github.com/succinctlabs/sp1.git?branch=dev)", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-solidity" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "syn-solidity" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5e0c2ea8db64b2898b62ea2fbd60204ca95e0b2c6bdf53ff768bbe916fbe4d" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "sysinfo" +version = "0.30.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "tendermint" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f8a10105d0a7c4af0a242e23ed5a12519afe5cc0e68419da441bb5981a6802" +dependencies = [ + "bytes", + "digest 0.10.7", + "ed25519", + "ed25519-consensus", + "flex-error", + "futures", + "num-traits", + "once_cell", + "prost 0.12.6", + "prost-types", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "signature", + "subtle", + "subtle-encoding", + "tendermint-proto", + "time", + "zeroize", +] + +[[package]] +name = "tendermint-light-client-verifier" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35678b66e819659617c2e83f9662b8544425694441990c07137904a07872d871" +dependencies = [ + "derive_more 0.99.18", + "flex-error", + "serde", + "tendermint", + "time", +] + +[[package]] +name = "tendermint-program" +version = "1.1.0" +dependencies = [ + "serde_cbor", + "sp1-zkvm", + "tendermint-light-client-verifier", +] + +[[package]] +name = "tendermint-proto" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff525d5540a9fc535c38dc0d92a98da3ee36fcdfbda99cecb9f3cce5cd4d41d7" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost 0.12.6", + "prost-types", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-script" +version = "1.1.0" +dependencies = [ + "serde", + "serde_cbor", + "serde_json", + "sp1-build", + "sp1-sdk", + "tendermint-light-client-verifier", +] + +[[package]] +name = "thiserror" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "thiserror-impl-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "thiserror-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +dependencies = [ + "thiserror-impl-no-std", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "git+https://github.com/sp1-patches/tiny-keccak?branch=patch-v2.0.2#bf0b28f63510a90c7b6c21ac6ff461c93ecd2331" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.22", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.6.0", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap 2.6.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.20", +] + +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-forest" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" +dependencies = [ + "ansi_term", + "smallvec", + "thiserror", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "twirp-rs" +version = "0.13.0-succinct" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27dfcc06b8d9262bc2d4b8d1847c56af9971a52dd8a0076876de9db763227d0d" +dependencies = [ + "async-trait", + "axum", + "futures", + "http 1.1.0", + "http-body-util", + "hyper 1.5.0", + "prost 0.13.3", + "reqwest 0.12.8", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "url", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-bidi" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +dependencies = [ + "serde", +] + +[[package]] +name = "vergen" +version = "8.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" +dependencies = [ + "anyhow", + "cfg-if", + "git2", + "rustversion", + "time", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.85", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version 0.4.1", + "send_wrapper 0.6.0", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "zkhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4352d1081da6922701401cdd4cbf29a2723feb4cfabb5771f6fee8e9276da1c7" +dependencies = [ + "ark-ff 0.4.2", + "ark-std 0.4.0", + "bitvec", + "blake2", + "bls12_381 0.7.1", + "byteorder", + "cfg-if", + "group 0.12.1", + "group 0.13.0", + "halo2", + "hex", + "jubjub", + "lazy_static", + "pasta_curves 0.5.1", + "rand 0.8.5", + "serde", + "sha2 0.10.8", + "sha3", + "subtle", +] + +[[patch.unused]] +name = "ecdsa" +version = "0.16.8" +source = "git+https://github.com/sp1-patches/signatures?branch=ratan/secp256k1-add-fixes-v0.16.8#cdeab4f0ed0d715ceae3fc6d09d16ec3ae41ead7" + +[[patch.unused]] +name = "sha2" +version = "0.10.6" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-sha2-v0.10.6#e5f8b7eaaa9801503bd998932a52b65848eee234" + +[[patch.unused]] +name = "sha2" +version = "0.9.8" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-sha2-v0.9.8#afdbfb09c325f8a69c01d540ec9a261e3637725d" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 48301d93be..4022f079b2 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -12,6 +12,8 @@ members = [ "cycle-tracking/script", "fibonacci/program", "fibonacci/script", + "groth16/program", + "groth16/script", "io/program", "io/script", "is-prime/program", diff --git a/examples/fibonacci/script/Cargo.toml b/examples/fibonacci/script/Cargo.toml index 021aaf5fcc..308d3eeede 100644 --- a/examples/fibonacci/script/Cargo.toml +++ b/examples/fibonacci/script/Cargo.toml @@ -12,6 +12,10 @@ sp1-sdk = { workspace = true } [build-dependencies] sp1-build = { workspace = true } +[[bin]] +name = "plonk_bn254" +path = "bin/plonk_bn254.rs" + [[bin]] name = "groth16_bn254" path = "bin/groth16_bn254.rs" diff --git a/examples/fibonacci/script/bin/groth16_bn254.rs b/examples/fibonacci/script/bin/groth16_bn254.rs index ac873f9760..3b4aae3cbd 100644 --- a/examples/fibonacci/script/bin/groth16_bn254.rs +++ b/examples/fibonacci/script/bin/groth16_bn254.rs @@ -1,4 +1,4 @@ -use sp1_sdk::{utils, ProverClient, SP1Stdin}; +use sp1_sdk::{utils, HashableKey, ProverClient, SP1Stdin}; /// The ELF we want to execute inside the zkVM. const ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf"); @@ -13,11 +13,13 @@ fn main() { let mut stdin = SP1Stdin::new(); stdin.write(&n); - // Generate the proof for the given program and input. + // Set up the pk and vk. let client = ProverClient::new(); let (pk, vk) = client.setup(ELF); - let proof = client.prove(&pk, stdin).groth16().run().unwrap(); + println!("vk: {:?}", vk.bytes32()); + // Generate the Groth16 proof. + let proof = client.prove(&pk, stdin).groth16().run().unwrap(); println!("generated proof"); // Get the public values as bytes. @@ -32,7 +34,7 @@ fn main() { client.verify(&proof, &vk).expect("verification failed"); // Save the proof. - proof.save("proof-with-pis.bin").expect("saving proof failed"); + proof.save("fibonacci-groth16.bin").expect("saving proof failed"); println!("successfully generated and verified proof for the program!") } diff --git a/examples/fibonacci/script/bin/plonk_bn254.rs b/examples/fibonacci/script/bin/plonk_bn254.rs new file mode 100644 index 0000000000..f9dd90569f --- /dev/null +++ b/examples/fibonacci/script/bin/plonk_bn254.rs @@ -0,0 +1,40 @@ +use sp1_sdk::{utils, HashableKey, ProverClient, SP1Stdin}; + +/// The ELF we want to execute inside the zkVM. +const ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf"); + +fn main() { + // Setup logging. + utils::setup_logger(); + + // Create an input stream and write '500' to it. + let n = 500u32; + + let mut stdin = SP1Stdin::new(); + stdin.write(&n); + + // Set up the pk and vk. + let client = ProverClient::new(); + let (pk, vk) = client.setup(ELF); + println!("vk: {:?}", vk.bytes32()); + + // Generate the Plonk proof. + let proof = client.prove(&pk, stdin).plonk().run().unwrap(); + println!("generated proof"); + + // Get the public values as bytes. + let public_values = proof.public_values.as_slice(); + println!("public values: 0x{}", hex::encode(public_values)); + + // Get the proof as bytes. + let solidity_proof = proof.bytes(); + println!("proof: 0x{}", hex::encode(solidity_proof)); + + // Verify proof and public values + client.verify(&proof, &vk).expect("verification failed"); + + // Save the proof. + proof.save("fibonacci-plonk.bin").expect("saving proof failed"); + + println!("successfully generated and verified proof for the program!") +} diff --git a/examples/groth16/program/Cargo.toml b/examples/groth16/program/Cargo.toml new file mode 100644 index 0000000000..164feb7373 --- /dev/null +++ b/examples/groth16/program/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "groth16-verifier-program" +version = "1.1.0" +edition = "2021" +publish = false + +[dependencies] +sp1-zkvm = { path = "../../../crates/zkvm/entrypoint" } +sp1-verifier = { path = "../../../crates/verifier" } diff --git a/examples/groth16/program/src/main.rs b/examples/groth16/program/src/main.rs new file mode 100644 index 0000000000..f7dd8178f4 --- /dev/null +++ b/examples/groth16/program/src/main.rs @@ -0,0 +1,31 @@ +//! A program that verifies a Groth16 proof in SP1. + +#![no_main] +sp1_zkvm::entrypoint!(main); + +use sp1_verifier::Groth16Verifier; + +pub fn main() { + // Read the proof, public values, and vkey hash from the input stream. + let proof = sp1_zkvm::io::read_vec(); + let sp1_public_values = sp1_zkvm::io::read_vec(); + let sp1_vkey_hash: String = sp1_zkvm::io::read(); + + // Verify the groth16 proof. + let groth16_vk = *sp1_verifier::GROTH16_VK_BYTES; + println!("cycle-tracker-start: verify"); + let result = Groth16Verifier::verify(&proof, &sp1_public_values, &sp1_vkey_hash, groth16_vk); + println!("cycle-tracker-end: verify"); + + match result { + Ok(true) => { + println!("Proof is valid"); + } + Ok(false) => { + println!("Proof is invalid"); + } + Err(e) => { + println!("Error verifying proof: {:?}", e); + } + } +} diff --git a/examples/groth16/script/Cargo.toml b/examples/groth16/script/Cargo.toml new file mode 100644 index 0000000000..a9768a95ba --- /dev/null +++ b/examples/groth16/script/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "groth16-verifier-script" +version = { workspace = true } +edition = { workspace = true } +publish = false + +[dependencies] +hex = "0.4.3" +sp1-sdk = { workspace = true } + +[build-dependencies] +sp1-build = { workspace = true } + +[features] +cuda = ["sp1-sdk/cuda"] diff --git a/examples/groth16/script/build.rs b/examples/groth16/script/build.rs new file mode 100644 index 0000000000..7e10aecc5a --- /dev/null +++ b/examples/groth16/script/build.rs @@ -0,0 +1,4 @@ +fn main() { + sp1_build::build_program("../program"); + sp1_build::build_program("../../fibonacci/program"); +} diff --git a/examples/groth16/script/src/main.rs b/examples/groth16/script/src/main.rs new file mode 100644 index 0000000000..1a55484de1 --- /dev/null +++ b/examples/groth16/script/src/main.rs @@ -0,0 +1,50 @@ +//! A script that generates a Groth16 proof for the Fibonacci program, and verifies the +//! Groth16 proof in SP1. + +use sp1_sdk::{include_elf, utils, HashableKey, ProverClient, SP1ProofWithPublicValues, SP1Stdin}; + +/// The ELF for the Groth16 verifier program. +const GROTH16_ELF: &[u8] = include_elf!("groth16-verifier-program"); + +/// The ELF for the Fibonacci program. +const FIBONACCI_ELF: &[u8] = include_elf!("fibonacci-program"); + +fn generate_fibonacci_proof() -> (SP1ProofWithPublicValues, String) { + // Create an input stream and write '20' to it. + let n = 20u32; + + // The input stream that the program will read from using `sp1_zkvm::io::read`. Note that the + // types of the elements in the input stream must match the types being read in the program. + let mut stdin = SP1Stdin::new(); + stdin.write(&n); + + // Create a `ProverClient`. + let client = ProverClient::new(); + + // Generate the proof for the fibonacci program.. + let (pk, vk) = client.setup(FIBONACCI_ELF); + println!("vk: {:?}", vk.bytes32()); + (client.prove(&pk, stdin).groth16().run().unwrap(), vk.bytes32()) +} + +fn main() { + // Setup logging. + utils::setup_logger(); + + // Generate the Fibonacci proof. + let (fibonacci_proof, vk) = generate_fibonacci_proof(); + + // Write the proof, public values, and vkey hash to the input stream. + let mut stdin = SP1Stdin::new(); + stdin.write_vec(fibonacci_proof.bytes()); + stdin.write_vec(fibonacci_proof.public_values.to_vec()); + stdin.write(&vk); + + // Create a `ProverClient`. + let client = ProverClient::new(); + + // Execute the program using the `ProverClient.execute` method, without generating a proof. + let (_, report) = client.execute(GROTH16_ELF, stdin.clone()).run().unwrap(); + println!("executed groth16 program with {} cycles", report.total_instruction_count()); + println!("{}", report); +} diff --git a/examples/riscv32im-succinct-zkvm-elf b/examples/riscv32im-succinct-zkvm-elf new file mode 100755 index 0000000000000000000000000000000000000000..b100efdd3f51d7951109d6e837f99423fb37dabd GIT binary patch literal 105028 zcmeFa33ycHy+8h*b(VxAa3BeYFfd7oh!B`8fZIee0W4Kqg4S9go(vF$B+Y`*&4I}T zP-?MZR0f)wC%O_R{`5vwGE5c`lG2eAwtOfKi~J9NhTqvy}kGO zKhN(eKF66k@AiGa`}g}UdC<3{SP%pj`zNx$Gy2t*=3=?{+_uLo%VjQRW7#Z$Ihcy~ zRF;dH^t_Aj^vKpT*c*Kl*jRkfL**=m-r%2|9v6S+ZeWZah2C4`b2sAMqb~jgW->-k zeEa8r#Mtw{cJYUry@iM1qV~6(tSzIj!~gMeyp$NLn)mEr=@fjWhx+HR4Ho_D+rKdI zFAV$(1OLLnzcBFsBnG4`g-MykOv-9tMuWl(MP*up%F=FQY!!RCLdsNFnumX{rnXz=tl(8rOGKdYjCHD@KZbGEsiHmsu+-4_(toBc;Gc8M&zG-8U;XZx zqgim8!eKH(3z>Vyb5`G>8SaedFrSTrdn!J~?XmY)5qyT4I+Md`Z@7~Gws*|b)a`)# zS>|@#V!_O=0?Y!&5eeo`hA;RF6RzMj7M#UYf8@Eme8if=Jo9tG0-ARaPl3t;;Yb8H z4KV#g1n>tykM5|URx!Qy7$Z13pHTXPJ|F7ju+BY^ekn7Awmv2`Dy)-9_^lAW2-loG zCXH3rN_`g}#T?OR2sAu#3U~-GV^>xTH(EG!m<5~BJ^-Am#c_1?O)}|Pe7UB&SS4#q z8djcZm1m$_KzZWO^2ijkocJP#%AF>^bWf$$IqC0zvwTf{_r@pYYps*B zQT2)gPLJb&H(cMuD!ablNA2`uKM^~()Sah3r4IBtcBLdWgHIsGouYb90-aC8YexN# z^<5=G&^KD>Z18_fe5mzwCmWDWJ>{6F!7;A{`)i65eC8Y|>y(dy*L=*K{Ty>o-^XZ7 z6TW~0c#@=yjZzS}kggD<;1w^4()5jDaC)IAT`7pcE4f_Bgh!%@*5I3HD45?0KEG># z+Y8VwqB{e)o%$$Xc*&Z3pqJ*ODLG7Ee<&rGDPV5nSg-?n>_{dHM)H`J+Q2+3k1;LH zCKx+ILiprK=7B7^vk1nQAX75i&G|&nXEuzPEoEdkV6|_5!cs;hW%wszuYVt?XaQ!JS>CVmxav%5_{hNJhat_Aa z$j7wC`=g$&h_QFnxB0&95BfyNzY93Re1S6&^Op!W1T*Is#W$DpZbM`?$Jgf2JVWsc znhLyB(OlRgn&M^dnW#^&E8~{BXV82%S~T%?(QmV_$ef{l`3ekW1^Pl=-j{bPmnpSj zzM+B_Vm3kJ`uDpQ?{nP(`Y_N3I&+GkZH3ORhyDh?o8yG$$Lxv4x4U&w5%sbR$b z^ji|#*`*1sM_tg@ir{`4viB5p9qfoT_v=g^3uq*lMo1BiPzZCxI4ZMQbh=T>1dnDG ziiW&VlooGPwPkgJv1=#uobF&o+D@jW&tsnVY=Sm!9BZ`;%-CY@^3;tJjN_YyaCtZL z)TN^=gt{*Xp7-}NW9K;L=|=gn1|fXkQIx0ga`39)xxa;ZLK%>AX4lj%$;}QiJ@Hkh z6@Ltw8^`&{f@^lTe7>Ohwn~Ol#XRL-6!iC-RTK6Uj!R4aevEfE*bvlX7LNt4(vEHw z8g2WW+EIt#=AT!)UqI7xIwJ_sYNFaF(_cX)SG%#seA@C7`TpnfNlM$vZ+st^qWt+`< z>wquR3r^bz83sOA9%r6Y!27Yy=%a;cgyU1EnCI+%DrZtQWO_H+o<7Z}u6D;3=6L{p z+_6RQtUAlW4?IQXESN0_TKX0tys8&;Jk5;bTUeO-coXkV+XPSVQ=sb>7Mxlr7<Nw>Jsl_r~zL#+^YHMjytlLA<+@g{vDG z%3072U8mvQy|*!{Yy2P7`|wGo{TA>3d@uN-k#Sxzf`aE{BlGAb@K+dg9Aj{OtnZ*N zrOR^WF@SECu}*a@mq)c z^%bX*8u898;K6UrR>c}0!TYjPiH&$?*tRn_{a(}K46A#++Sz=xhkZ~_d9`&NQKP#% zxxfZKv8APiLnlS|-ownZxdVE&wO_xt$L@aeFmpHIncmuuz6AFSykFU)x?Aw>DLhZ( z`8PaMTl?J^c(PFMY%w!VgFn?CuV!cP6VPUjDuo+*0C$%_V+`~=yq{+dLoccQMuRGL zt~t_2y4UE*W5(fBrWK?zk^}v5HObgKj%jw-kS);H_-?4_%*~*K)E>;KfQ9p(WuCch z;7{ng&1t~3jcHp{_>cBJqdTAJo0LSu#zeiMXQ}~Q>J8mv44Vt@yC)d76sCW>duni+ zjkyCo%s9H4H3k6Jo3O8;eCFP$Vw_{}QK1iQOpu-`j*=cUNS2;#h=x!1GWXtYE|1zC z$iq_|QIbLTlilcJ6J!YW_N&mRqTp^)1d>N%4|D?L&kY?;IvO~L0tZ6py+_VzoAaaa zN5*s8v>7@a@OOS&`3U?Y=xYv(hSCMyVS`>+2$_f6Pd$S1doZ4g{!`KCGTnFxQ3#)ZNUCx?;jnDwR{2(NK){3&}4UM`IbGRE`^tZ;l67 z3=a%=5QgD_0T043JU~~V-cUS1&wy_(iHB6+Az+WuMSBx)hO$^=far0`qDP7a2WXXU z9|nhA(DsPK;1EF%)Efea9rS>Hyd)f1pbh9yhq&$Aik;(fkCMW1wnY(x3UF#mW0HLu zaC8{(^{}8)VDb%cXlyQKjT;H4z++t&)AvwcsZ8Ic@VG11p4w`*Y1SNxHfFufN0dIQ zL**nNvHBy87sPmy{SH1}P+7&?n|fH|CRGU99$@YuVjl(e#J-y~1_7gOKXcau-g=ZP zt;`*wcSlfuoHbIMq?~4M$Z#Y0GH5%?+?xqLk_lC4+#G|ifpucC&jo+2Pt65JVu@C8-a zI2YIVh~b!?9!cS_XZeI+mLibt*OSx~_!EM(Sb^WcWRIFzsMofO=A2MR$%Ktkq(NVj zJrkCjzTiL-6^2fmj2&G=CiMgP0-X zY540u5j7RD8hq11pWQpr2*HP~llzR?k0fnb8S~UPGuR{!6Lgax?Qal+`#VGpwDZ`H zFi*jIuqEJ`CRK8`oDwbHKh2th9EF5kCcCYLL@p18n8JS(4GUEGa^lJqDyQGAh@*^6B`Go6Ytfne_I&*5 zkTIfj_94t)5n4|=?lVGlE8Q7~SnHuxKSjRhJ$DwqcUN3vgfa`LUTgQw%|@vCHurRV zFG;$^2z5_$&%pOO<-0~Gvc)|U-%kc78=*swxm}0E)}!x!(FpDQjeF`L;64OgZwD@7 zekP>bPjOjv^rDXxt6tl+)P~Q=`b?83h6ooIRQOR2Lh+*`yh`6P8wSs za_88sz2Je-;DOQLfzjZB(cpm;@IZu zN2`a-(fmS$KNY@}YQfMJaX(oPm>|!ArXjHy`r)}de2yr~6i-=k%A34z1$f&Ki54g< zped24eqW|SJSBN|o;T1x$&-o4z<9%o1+Df+-L4Ge?Q)?Xb`T5~@jqaQ=lxsBKQtPA zx6r4y+4m*z4{YFbv3$bg!*L*G_z+*3I+5Vfls4eO8-phWITaClFaZ99FSiqVAT%;A z(8fU9-8r0ozl|S9lOe0frRV`gq&x}f5X^})mOu> zC4DGIOdh@@-Vv)FKwhT>yjTw&Jb*D(&=mNk{7$fWG1DKy`esrv5&tUoM*8mHIY*mzR1x$ER4+pHl6bwHK0zyK zCjD>Lwc5EAYL`P}$l6YfS8|lk1JYAg0^y#hWa>J=f_ zb_KZ1E7Tk+)9;PQF__}ux%SiGiMJyJlLkH+3Kz>YDDTH%n@q5sMefD!&e&*2?!}H= zfCIS~n|nr~4gBsP*d*Uk@Sg%+Biu95oFBW9=M|xw^_7RLIkW!8gr;7CJJ?*$f=x2= zJ+Qem4)!Ac>m@yS8v6~T%p&Cc+9C3KD}Q+mvB@!B?^H9FahfOWH1a0$*|;&zVvMr|sg+Nm{wUtIWy4&= z2y(2gWoIi$ZuAsYma^K<2D9qV7Thtn4nEqCJ;kS3!Df%B*>*REJ5KSOg+38-7%IZJ z0Zy-Q=pfIpx4r>ActDQ2XEyb^T?fzU%;AzU$(D>mF6{-TFH-0?bYRALohgWEfVT;U zFvqRXDT~2h@aY~`fZu>v&v+5Gck_w=T7q@RO6rB74aKX%V(Kc}g+AG>F^pF@AnR?^)qzCHtb z%*~GWX(3-9^h_$*vfvd8;HC%ukX+OU-F-oS$YGZv$RjCDeHwDz?)t?7@|zZ`rP-^?lvD;D%*m=S~@5glj`8V)! zW>KG!2S4y+o`Bd-L|@QHMdvJi_Uw@I?TB*#AAFrC*$j$dh|etEZ-p+f!+zU?8HIM( zZ#(R_4YFs0JUO_|56Mw8ch`0^@kKl@bl$DJU6aDvh?Zu5-WMyoCjXZ;$DcxHoFN{7 zjokv8_PMi*fH&Ch>G(cF#u^3YP35X@EC00lwiya=sJ3IBAl7GK3}872e@KQuB*Pz) z;SVYBhp;YEs9-%q!Fq-Q8CP3D8|g>`)-ym4@dS8?Xxjq*v}G9ZJU}`Ry6pgT5#*KI>VU#=cCoGYZjHCqrmbOH zVApKYl{Z2z5?FA$)9feY1WwRT=I2bCpY<^K&>6E&^#lDtr(3>PFdko>ziRSZw1a`{Q~^0Y59?X9fJMfS+aXvmBgWC}Vwx)`nH$YZG6-`-b2P zYh5I}?rfq-5p)dXYye+H=Ykpa=Q{fid{Ei-&i`!%-}0Ej!Z+t@&f_x2{l$C@zCeG2 ze9cY*mVvb-@UMimQUPmVh%F<4;~?^M?fvelZ}bNLVnKj;DS9rdw?>{4?(c$Vm&LVfdi);%4(LUNgnakFUL z2+Bej*9V;gnaaSpQ&Hx61LK==VJMONNUuRJUod@5@6%GId;#|Ef|ONsf$G6-nz95w zbT=JDz6)dTZGtSqw!+3rEi&edvJBLl+TQ2h3wsZ^+)p+kCY5yJg8@ic)Sfps*Z z3+O>SL4I-zXtZAuOx+*@SHMNqiGHl9qb$Uv{h(7b;mV|)+Xec}gkItD8M%+>FbrS2 zNgu<;17GzQFbCj_=+F+Fy@CGmy$Sew@(th&HhS1voW;j$XkOqQzLu`19#b)o0lye? zfPE%fnskVDACv4YcR+8uI?; zo{R+(F#eF(4*nSODFX5Y3gR1I98Ckzhlp=DO#?T;KZ9M&6s&ozr5Fce^4KIeY~77y zj{FzP_9*dV(pX$xz`HTnV*Q|=VC@|tS@{@#qYA%K1-(_kX@lRWz;9HrW~X4yj%ZtOgl_|l%>O3 zLU!)6i114nsS^w*cq0_Dn=u*kwoMT`{KpB>mC!xpTY*nVhjRVS^?KO_w=?%bqm%4v zeV^s)-wfY&BIz&KF3YCCp3Q86y@K!Lg51K!A>PO!+fu-7TcnEmq?p8=m2rV|0Qx&` z+70+Su-B$vBE!C695XI>M)Jw$gBe9UX4X$MJ9RNLf&76We8Cv3l&|tA5!m=1|~S3c8&mF{W%U_9>E8jJOH0>-G2kVreW~0&M}#1KeK(~{OG-Gz%BvzCXccSG)J!A zmB=QO7LZepGx_Yl*0i#M!FV00MXHaPdP|8W{t{HUs=Fn>1#xnSIxjpVMDZM|6qYgTAeNYvdayZ-7VOC%LD}utU%r(D__{yT~rJ z!^YG`VM}B7>0z$xeC-y$vh&vX1Nwqwx3y$$9oD~p%yW1lkBB^6BhT%Pt9;4`9UX<7 z9BXafFc&_LO!5>j+g!)T=^yH^poM5q9OQXwE3Xva#$3Y>UU!iWfo-^Co}`oVB+|$6 z{a9lU=wA4%pv4q{a>{_?({mDhA5Gx4|EF^jrmp|g8~|v+b7`FKL*W0xeMY(eqd5r^ zp4@*bC&B5~Hhox5VhB%@4;9ZVmaTkiIM0zCC%dX`hCKkU(t5h4Vy!AZN9Um&>Vmib ziMHd>_B?E#4BIEe_Cb!OD6oAJ_|(jY`ao(ZzznIPmp}XPv__7F#doY zg6cn{7&SrQfS|#VEF{Q zb*D0c_KjJ*@jJ9fE)2Gs>z1}NZdY#9Jv9UNJU43A@$IqT+O4VBV*($W^qdt#O}G5* zn_(;ak>eVJxB&8lF=>401G8W6qtphufzdQ?eZny(_pLcT4()-@)^DgwWBAaGhI(ra z6!WAyHs3C)Lvyw8F|`%%u@1Dy#Dn@B4qHPEt~Qrhj}^nuaY{b;vQEo~RCmrY$3tJ- zKV%Q^F;sI51GKT`w8R=~74ifs(a^Ak;1kF6iSn2`V;^uVBi5wPrHo)PMD@FrD>T$& zCXMXHyZC$i%I|9G3d{vQj|=rf;1R4ZT0ZJs;LU;f5Bh}f_XLkwaUk#sTADhEEgH`I zl&j%*P>X+}jmyM3bPHlA>{lju8XDR?p%(Bp(SycRhsdhwPrSSseO}TRKt7YlLf|K+ zm(dy{bYP&FR~;vyv_Adp1156)xmlm zwK<93gKgsba3fY47@POu#X3_6YZhC1&fi?q+bK(#i)lU0T+<_6Z2GHP!}Z?*9=`(} z`6+99utUUuv{&EMb>0AtVXf&6!8Q7_BW?uVnxWgtXS48zwa_8!pia;)k~~{ zQd!&@W@B7CcLKGu@D{%g%G&^Mv31a4eeia%v3Va};DF?&C~D#6FBVP){GgHi5>vN# zoW5jCsBs_rOT+omvI+n7$?abL!YA?P|Gw@IB**K*PuBe})1H$NWyx)=?FKWzmvL*& zBd+b5`gX-X6-RL$Z*)gJJx8HCF+ZF|K|e$Ig!DZ5Kv=tgZ;EzUH-Mjj{mo?G zPD1CyE^Sgp-gh%_Ot{?JjJ$Tb)3-#%a(`_{GuD|&_p!0u-Z>(FHPm-8H{go$6{fDPQ5S1oX1(u||3K}D|Kr+!Pv0i1`mbbj{~_O}gnfT>P75@*c=k0tNl79< zZ9vzX@;HtAmw_gg)~59*awW+}cArUl`XRo4PkhH?6|?@Y2u^cOUX|uS?J#d8R?iq1 z)BCE4lQzkWwZ`ReK7_q7ZMnDG$i<#-*!x&p3)Tq1ZEPKD?&EwYFABLDpnc5e#kw8w z8|MSdmw3Om*#$cmIYV)qIR@LVIe}~7i^FC5G7k^u_fLwcA%8>GONRRrw05j7QSIc{ z1)GaWUgcnO1M!9o-;J*~Q%q0vGRVeqJhrt`9)Nr-=oXn|hj`PSu@kuTV%-{Lz`NUJ z?xE5HvN{lBf`%MFgh!Jm&&B%cd|Wx_o|-9`{RGgb+0RJ$BizOMCqJ)qlA{NEbNlfA zBA*s=EO{Crs}+a&o+-*zY2(K+eO;CfxMq59rp@qu95s%13y5{$vle0OcKC3x;pE%F zpF=Ew_`3);9dL6!-uAwPbwK2h;KLv%MC*BbGX%go#5V;zreBKvLNr$A2a#UQ5n!?L zIwvT-FHU6Ci$B4R>+Xx@v&Ol$#1^+v-ZXocP{GFF6 z)_wWw!{<%BHNt%U(Rdhk8|!0cF8GE2U*qAni{t;@{2i-^i-*sBdW@&Q7mDR>+C0G9 zC21_RgoNN?(7DNnyhTSW7e?#m=6WFZ%$fV|xIGc|2HMv|HnmM4{SFz$J_6Vo*aq5P z*EtdACq}RffMG=6z|uJvtpgMPlg}^$eTT@GWce|q%SWg?FmK{#vM01Jz<_M%&SOkZ zRb}j9gP!N{63#%I`>t@-6E?$#eH#(z?Dl>s3pgr1B1j95V@>Fwm2-$-|5km!=>vGv z&@c8EH1)UISb*2>hzQb=qiFw;RX?P})gKFdjHvr)t(fn5Y5|EPG1!ehBSB zBf;dKz+Xnn%Ok&x`6-wybf+mth4HdLJV88+b!+TBwQS-g^Bve{0$N!4(Ej1D(3u#^ zuAQ@BIy<}$mlrjHI|rUM;R+4q*)$%zzAPB37y4VloeC|0%?o~A$2@AA*VEI1@38AD zkBMRBFw_4W5lQbO$LYmcH5OJ5nZCce*BkC0*ylY2XV!d2artTpCDNz1IWpQ%o&}w1 zqgJl?8NfcUHy3zvP+nC-yk*!JV5^TB%3kt`M5AGyqS<<)ICCm!B@v-9`B*=l38b|z z@;Quk-K?|!a39XwNyuGXFp#V8gu1=@d(9^9)zCNtzKEd`9qd-FgKYsn@I8)zgYRkN za5jX-QhPH`+(zrZpA|;we-uX3Px|_&!x+fD2uASp#du_ccr5W@zu*Ws>^e;6Hi5%; zJ{^Z9d^Mi|zUlt}d?pV6=in><4Dh)C-+&Ik$j4W!`2KbM#9>j}nQ7(ti>G>&quhU7 z#o!m^fnSw~f>_9-DQ$|rr4tOzLTZc1(vYJl%g7mK`2i_3*;JRH& z)s7;!3q7YT!RiD%t0oWVF5#eN!ZLB7YM zsrjDpIk+&!?6)aMO~zS`9-RHhcNIRNnwo-kqP8o9IvqmmF4)9|;xBj_ zI&ek^vCD4sbH@?Ev-uRx3c-Kejk9RSj|gF$7YrV;u|~1IpYm~T=|q2{^pTYd?GUKF zwmU?3Pw=+LXTk>HyrJV{)Gf;W)OWBLYu6Elxkt~x06{bUC2d+{Q!N8DC2o`wA{;EsSy^X&gIpY<8C zJ{8;x5Mf3HG&weuCPw$kXgCx{lOEJNihjByCN8M2&>&6deT*h}FKVex18q4?(y#~1YOB?KZ1Tp|p)?^qJd`G6w_-GD>es91IW(e)nmI@l zvJ1*mTVwJe(C=9rotGiHY3g2X|4rN2Hrb6cjE$jO!f%XLnY1?H-XSx$f#=(_$CJ6- zJDbQ}UljX8RtMvLHIhpEL?=;0vWoS=dKi{7d+d55wnt7<=%4iM8bRKDU$hho0y|Tr292K?cX= zfzAg|$H&iE81SvpHp=0|UO+u%odkMFW;{&eQrSVi4^K~8hw~esi|Q#2lD0Fhp9bI) zxeLe{`lat^hdtZ_W5Exm{@gf=fqlt+$ibhdy$$+UB~f!e#EgfW{g|uR`Gm6zW7~pH zBj35rsY*}R13%yaj-Nc>2M_RLY+Y>OXg+cb(3kOeX?}GOFJl#z@FoFQd`yNhk!LWr zZpD}nMQQBL?an^R-|F`rApIcInMwZpD|=TXQ9sAz179;;@;hysn zk5!0QiBB)un}QsbguUew_LfVyJ4lpp=Ms2~?^nU+i1DL41H2Y@4-?KcfR`S{Uch|< z?qi~TVzN<>J){okVZNUfbK8XZUKtUzuU*Dkougr25}DzAR`eu3jx*`lQ@;&!r+Wsv zUQmhd`X-0yQRhQ$fg|Jsv}v|JZ6WSgXrS}eCvnEJqu;X)u?T3VKc>jgnb@xJH*o4Kh3#`|kd;5pOa4Dev}{#!BPng2O+qMru8h)M8Z1fC*J1-nh3!eg@SYy)&Q=0iFANWducE)#8kwyOp-p2 zwQCC&IxEcm$Wh>H>`A&bY;9?Xd(`mOZH30x@u1bmQQ&=y)B@Q?pVW?Gtxj3#2mdJ= z{8H>Ohi#b1jBR+{n#kqK2!WP~;7x0MX@(+b--NChbs?%JjzW$x!NiY}IM5&Ao7{l6LYiOh58acbWM`iVO?M|@0tHBl9HyF-*3U&ZeMzPiXJ4dkQ2J0xS|SAYhW zu19ztAvUM|1F$!c`CB0KrI2~Liw*iC3rsUD#KNaf0e-+pu-DthV(mYX_UwDq@9=T; zB%6%bDG7JBBpY@I@sMC_N{3uOZ{C{_`mxv8B7zn+QLlf+9^7PSov(}i#)ls!>+gNY z^!IU>#->GB|DAln*pyA{zy!_#hwLJ+s|Qq^E%Oolf`0CxO!(6` z$>;}jLcL4rDE*^61?ShHJAg~9DTN<;!K>eRT*aD_o$CtdC(>O+Tkgjp2Vv#k>P$X$ zvd(w&kaGy(PCB0;HA4OdX*?tkO?xCjV*&bHfIf#_;<`d2U12DY-97MYk4=Dm!SnkG zSf@vS&|T7W1-2Y(We=Z^>VX90h9IvY%pLp{lYf#|&`AkqL7sS-$!GEML^&gmV`-t0 z5GPNpP8!}{Or9`r;MWPcxc#D>`X%RL^5hWTDTthuiJK1M=fT`E<_-QGs7vdX*#APj zD)95%`(ZzjH<6}+{tn){6gj>i80ZS3%^?4SkYKN0qG8^I!BU2;dC+uqdIXqT~96?@X5 zb2Sxuw*fZCmJs6^+)qYj=GvP<`AHkr=6F7rJtz6bUI_Z+3v}*?=t*`H`LVvBFCrM- zuy;Es=V#(F*n)FN$cJFx`W({xkRj27yN+N7MyL})ofNK@fTz!F&wxAm)AH^Y(TQ~8 z2(&Wt#v>jAz3Q=FYp(-$%e*k6Zo`!N~#q#%vd-)kXEX2kMb*dGg@%4$CFRS83|f0r`k4r@J9O_1r7&@s!{{ zB6fKcvCBThF3(Zi0$;HK`yGnm_dpjt1i1vwp~G!Z zlv#8>94Zm?M-bPYyHSw94}kr=Ud+dztUrF^WPJ;Kj;>myOcvotXcPxa;T(eBRg>aUN%)iLVlf7s=<)cior(zd_VLEJnTGF~Se8_xonM z_7Lue1^p;KAz9V87dyzddeplL!|2oGbIgCjaK6W!VE-YH3gQMOc!_huu>BI^1_^P4 zgt$RM+(2<1KRX;&4-J`5=ecEnFMzJsY`$4ByHCD}m0R9Va|a%JtvWM_=6rw0K%GD{ z`W~W3%)Mm1oI(*5ZO!H~}x=p~{kf@=d63@b4}~4Q4`~ zpnGA1QZz^V1?&9v4{=6==ZEz%IG2I7A`_?Z4{@hOd|$x781$7P*H_yg%=!graM&AG zkW1sb2Jw#*_cmZG%wa@-3-cIRms+`n&vFie`_8D(eUQ+w+>eQ`g&5~E=YHVp;GSgY z)0sRTN8AfKYy}RHLm)lbszm#Zhr0jTI?n0T9&X+XyU!?=q*$5Gl*1o^eWNolA4j?V zR2I`YO6y#I$!s^B#~ihn6@&r-_^x*FJA8?H=z^WlUql;!RKpz)JPryp!@rUHf?1IN zhTOuiG7tV*Q6Kq^VgF9S*g6XPdX!YX=V8S_KFRnd`Q3=aAK5StefCj*d@b7QLsPxz zuL!WVo4J}v%9ze?=YFigCr1qMap#$bp}!t3^eD(7s#Und<*=wf@-XgQhJ8?x52v^w zu_b|W37vb6Qf!Mmw~@cWJ(c>T7MXl?qahTPra`yaHVa`}1otS~_+4XCww;AvStW$G z+$k7GaL3!(UKU=on*Y`o^+r9tc7C^M`0PU5wQhso-@rP%I$$FLqB(wx*JA?=3u#Sg zzr+J35H4u~N_QUc3oc0!B5YB)UR^DRTwsBZTs{0$y?E^QR>CJzm_}dr- ze-L?<7|uG=6`b||{uyl>V&yozcJA81_m`61vH1Ek<%OV2MCcL`x`g&($8toU7|YUr zV5u1TDg*u$;wRm%%F=$^Q$oIlTEg$CCpk0k$1(kG(k-O-E!aLeJ`I_C=4J<&)QA`v zeL+qy-NuXwKC@p!zDRJP5B3Cm%<$+tY?HVzSPvP!0&{A46>H%ojP4@UkXzEX+e9ND zYks&dhGb4>wlSnP4W)ZFZ1-q=tW6HKY=wWfSdjL2SnD+Tb2KO96S-OAVYGw%Q~aU9 zPvQAs8XNfzoXJWh`_9MY?ZMwDYjhOh9Cs7)xF=xKa-k!da0j^qYwix*lZV*!DdYs7 z+KM|vUqvn$IoGL8$i1Gx`Pz?=JC$*cZ0vcr>vqU`5zhs4J+Jt3&<}rSt>HcoJDz0D zWgOOuig3RK_OLR_p|u@`-AJX)kPZ`zj4$Keyp3e>rOg|*!%?Y`XABR?hEdWvAAcTo$h7old{bHJ-8Pq2YtauZU^6* zJOG~*K1I<5*sKeKc#r2>^Nfk19GW9#nRAjj-=>;;3m)L|3i?Sczu-79{VKD6zLy1a zb;~=!Zxlzu$N3aKi}4peN7T2V7knJ>9%zPG)1(>k9martbA)r-$j`(bN$@cctLwWW za?rPv^78n6)r|iir}%#>))N*(H^t)rlRTy*8kli+Oh;pmz!%T4Uev~nL&;~Ovwoz@ z%>6qKz=QK1m(bCeTP!vo;!9fR6>=_lUV)!ufB7b~AJWbkqX;@vRfFOH%6I;Dlc1%h z!Uu^kMW- z!KSbLE$j?(lG`JFx@=cHTW~k+Q4u+AtSxn5uDE+%!@dvw7my8`jn+=R`Y|5I$hzI8 z;I8^YsRL^no2TK<=^h*1$xe5%@_K+t^TED9Zo^#+h!4o8vFx-~2Y)I)zlB_wrK{&! zdib(d*cz?DH;?WhxAgXOUPtxKBbe!aYV*B!>P7g%IRJefVop9L##Xzq&lJ4!wFvi1 zhmUQP0Kdrj(U`#DYNC^&X07F)wyX!S7Y=u};arvd^)c~nt-C@`8YSc6+WY34?K`eF z+p9}7wGHjPiJILtafJ4NYCYK(H9|_nqhc@pN!ZE;*3VQl*XT!2z(%riT z@)Mma@J_vecUkwC?_BqEt~~Z(K`MVYfxlaZb8EJg&v(9ms!LOkO*7Ok)>(F}t0151 zoEm4gdzbn@qpdp`ZS4>-=BbUHBK=nSTU+S2TG8n|_CdiiYO`{i*=7Ze|3RzrSFAAr zR^$B#-yco~%Iy~%0v(m^M`MOHFGTQzJGG8?|k;L0+0Q3WBDHc z>|?bVBjMVhTucw{PTz#RV}CA5^=vNj8h1{^nxuVfSX_qn$pWrF^hY{yPc>wEzpc+W z0v}I>E>WCPpA>O6$xvR_C#$n@gC&c&JyYVdHqBx_EED$V@x(Puy>&IRL?o1SG+!K$KS`0 zY)qPoHG!M@qsH6cVA?$uOq#WTdCt5hc)sx(qyDv&a z7vqOw8p2P!ypz8~_|?|GlB}g?GY{P{|Gb*$v9rQ(k17~F`N)%H!T!T%rhCs3hZ%3K zXWE^s`Ca#(^{)Uops%eLf8$B*^YpahZ&Yl?{+3qKxlG%o2n36PJ5XuQ&hW9pGXr@F z$elznns$c|Fr`e>u6y)v3Yl0K{nvE+rQkJ4%oLmzt9l9YC$7p zT525E+S#ob!M`VKNeXhb-6HN!W#J@63Mai?sC_?4(3Z~ld(q*acI(Sh2XCzvEXY-;IodXJNb09k)0LX z>^S~*z>#R@`!9d2*>Y6<8~bG~O~KxpX+monVB6ff5Px$=)b2Zgf#|EGk0J=%FXtMtxCjuFZnFw zOHd4Loi*wKop?S5^cgw-;!|J?71%SLyBSy)GVPDlIb0V=SijUtdJ4nHbHe_6wPMU; zSr6iG>H{=yfDapIe=R$9@f{}c!!A8;@DCVwh#uF}5at!3d`o|UAGlGJ8xW)M`|}3w z_kd34_nl#1wW-fT-y{7`F{2y%Kj_}1*xhGz7Xy#;rnjRU`}z6VthN^cJ71f@__7s) z41ojV!%v3KOlRD)-azapn|37z6F)0c54#eB(|0|5XA2%5?wq7}(Z%oE8ri-K_#X5( z=7#!elyez(2r`o*790i+)Q%?DV#@sro-N0{+GgZSKJ1aTJJXSec@uyCC!2+B*xUD% z4S&nwdHAu~dQH}msId!cr^lfqI=Z7_75nAuRT;c_ z74e3C0{R5)NJn{;li<~!XhAFSxb25}J#snrRwgY%-e|K;&{ub3O!#+Wv4@p-s{3M} zPD4MjaiFhocIcf8oaSnz5qZn2NDfRNt}VxU|0H-ExzX5r?=0ZA$2}AG3D3ZN!qah| za5nA}&YJCj{&G^B8ElRSS`XwKK05aPi(0oLQru(Sk4nBi_d)8mr{Veqx zcyV~Yq*t(?4|Qb9IYXDA4c%?Q*Gs)zKO&CjeQ;lu^Jaj~CJ)tP1AcM)2!3(>FuyqR zhfmjAF}Z5{E5;hQZxOO&gOA;dGitraIrP$+8uAUjbj}*`h;@cTs;R3_zJ=VM< z(3BjC6P@Ne<&WkVRRd#m1{CB37h=DIO`zO8{C@mCg7VGSr??O~HNb+L3guT|Pml+E z12B#RQ@xoZEP;Mgl&NNp5O6~G55URuDS(siO{F`kIGm9`nQ(%R*0~ac+ZV(r+^$eO z5{p^AzXP6!*auS&1t^a-4FB!D@Wb$TCf?}P-|bd|cHC)g?>cYTa+rQox)8KuozsT3 zz(x3OJDD8w-Hpx1lf(9I{9Py5jJwiDgWr0whTGdpdV9-}PQ$ho{D$1<)Q`^TA4ceo zY8%O@S?^#k?37h5pVQxssQQ_svfkg3$Z1Bns3ZK~u0f8Aq5)ih|LG3PA$A^k08ULj zSoAxIae#jw4=DPH2=_g3uPxDp-)kA)KkpOrGT=J^=e$q4XBW7(_~eY)XAa2}#-nv% zKf@E6ZwE#wG3ah9OpCU6+k$lvH(3;q2x>#k3iM^%Kdts6O+Bi^ujl=L9ohYY&F zHo}e?4L#A$S9<$Bsw#xxBhlX*)W_hA1HsDmQy@`acUTP49#O#5c|$MdXv83FA@27` z*4q@EwQo8{@(BCo>=fzzP3(LU`+e|8D&o6t#7bSGjI(DYz4|FxdL;|z2Ua28=#>yp zCDY%q)7OlXq)7hYx;&NBy8OxgIP*X;{b<&y9_oP%3L4huJ^pTt*T%G+5uBCS4<8LM z(BE?)y->df()UrQ{#IjXfW9zw{8f3l<|sb_BHDa|(A@lK&2$ z82PZyu`0%3L;PXxQ{o+cdP1kX@xC%I8{YRtzVw3LiCDKki05uRU&C_^o;UDx;n{;H zF~P-FmX@#am$_;yT@O^3*ZN%#tgc++cimgJa;3le?nhm0BJ4sM9ud!a{GL@(Gsl9u{uS5%&Z&(e#Ku{vEio5+S}@?sw%5%{bje|)sphH z<+Zo@zg*|9(EXpsj2D%z^DpsNtg2l-1SSTU7NEFt?a(pr#+dXkHoqCD$0t@@U0Kbi zxxB7wd2OYielK5xQ7X&)pDV8@yC2WWx;1NVt6b}MU30Cgwz|%LQ)PwUg@5R83;K=q z`4+yH4a}mnw!E^!WzyH8+J?FZ{1snWU0ShfR!!CHS$cJ8t-og0SMFc8b{0ryk&Kgz z-C%&$=zkd=8YhOE_+DdmXsR>teEKN)4HQc0 zT7Mbg8sipM)>V|7Oh6-VI<_SCPN8Y)z$pf9-1UK$&aWG*?w=MY(=I z2vS<>n(xFmAeO$%#q87upGo+fiBHmDIryahDk^LJ^IcG5t_R9%SG!i+T5{X%%Wo)L z@VVP>EnMKccJ>P3W?gx8WyM->oNHYvGy}03^ki9iP1Tyx4X#qxy`_Mmx>WaLz}wO9 zP3U*&<bb7;UZ@?S zQdu1zktC)bulBpv*46sg zui4{b1ScDA>!8bK)oiHHXYp#YDk_(osH-vc+D^119XS>c$+IcxE@;0>-PEao$7S-j zi6$p|18v5k?tkHvcz8%Le#gq~-*GW)wY&%<-Z_TPMmbWatPG4#W8VyWO#fnbBi-ZT zzez6Wsm*t>^>`P<-;4OZ7MxSM%0HldNVcf`2f!`;i}m&1oS6ON3VT5%`~;o!(5?QJ z#6s~eYW%f}Dr;&>237e@{#tS=;@%9_FC?k(mq9sL?@T4NxB?!D)vl=Wfr=ZdEARJL zEG@6{7p@`ou)(*!yr#D1j>@_I&2O$) zv!NK$1M=4T*A9MLQdwDb8(2IxG?gqWtteaLw>*o*6;*Y$*7qU^!yV*a-Q};Yyba?5 zlf|&<80a>?|9;XegFW9;S6N%?vn&j~zP++?390m3{WX326#3VcL(0+S^Q9FVmXufAUtAK$E}BSGf{u_~wX+KmcY4zBP#HZ`pUSBX{ibm>Jh8eo27QMc z&ByD4%_+n4Q^>=w@caSK`*`~BjCu@u6;Cb7r{eP}JOy})@Z5ywi+EPyS&!!-JbUmw zgXbrBdeJ6=&)4w$4$lcZ=keISix>h=3UqcRK0SD@$8!^&Qao$$Jb$t|BbYPs z_fWrtAR5%Q?a;l$`-$h5gT6u7<6->Y;+Li0H~D2EKF0&j7{Aoi!ciLZmgYObU2wj5 zL{sLkg@;+=Duscqgl`R!%(%2$Mu8A~P#FAD*E)aoy_GeHRbyTlycqLe%r=op0v-zbtU*^4#taB91y9MYinm!)U73fnt{5Pp-wrT zG(0)$5xLCHnUmwm$<4{j$iJ!R)!S=grBPGkeaQ zIi5MWbMofo&ncKQcg{Rdj%T)Kj>qH4_2hZ-Jq4b*o_V=BxwCWUc^G~kx}Jw-^Y9A3_D#rj ze9Du%6!L&4R&Pe!_t?9C_R~8;pXqovB3;bn$jZ_+HU9P|P1<0)Hp>ESV!wCc_XPZ= ze=$9Ddzp*9w-Wri7QX0LT{B$sU9PV>XE?v^`g(S@bH)`Hjpav}U1jRjoJJS#@AK%7 z`17K=P?{7^&#J11DkBGjt73LH+GV0X!IF%H{USLWXdke82c3={fO5@z>&S#5WR;I*y6Q#or6>Dt{7B z%kPP2TwQXncuqPmBu=~fx|?qP))P;B|EmuhyPo{w=BKkTc|Ldv3x_3pN%wQl0knt9|n%97E1YRi;RnDS~&d{5fTo?6f&-Ue`1^ z(UC9BS0>oxMBCEE1)fnJ+f2K2W7e&oyV5>Abwbv}v1yK*FhJ3$@iwQr$UeDe#(KPS(#jrI~t?C!PKADixY^7KYevT(VYB-=M`+bZ9$ zjFKF-ly9$C=%~FW(BrJJSB)$F%GkuQiFY{02R3h9D1~lF9#_9~vZ@A-Ua4F+MX0(; znjniCy^}}JSA>nPPv3MZaQ2ENvQrj=ql=bY8~BfFR6#CLF3S}+Ce4t`5|=px&&<7i z)C}2S6O+`yW5GA&(b6dC0eQKaC=1Dn@?1FkYHqyG)oUPEK`6S4vkU%oK9u z+2R~wzj#1=TK<9koOoWjAofd9#}C(Uc=(%7=G<}T!`rq`{9{t`=a!uBn>p+HyT7#j z&-LGY*cglj53)sbiw?quU&lOm+Buu;lZE$wBr}A{rbd7Ho)#z z6Tjb6=C6PByWe~DwO@}KeZ~B%eT(n-;@$TwFY|x%(F14_dG(zWC%Z47w%cU^^tEqcewTEFLfL_ zJ~}n+i+A^&?T-f5e);Wpk|tMFPP}~i*T3=1j~@K#i>YaoCKoTf>1N{pZ#;M?^2X7( zy8hN(UGuHlx?Nc_XYKz{>(7t;`uIDKG4Jj@Ip3Q6f8Ka4dehB!ebHu5PMJ3A%wH=i z3$DHX2H*BaZ(CLO%B!#c=FQ)o?vFCp@~NBNkvA3DFO${L8~-gS@B?MCW8-Dgc)K9a zl5=I7B-m8jXy?-8F}4z$Bu{iYB)epjL`jkoWkpI*g`{!HO}5Kyci2QVEpe&5K)MS0 zX|$T0IA6XzbGd7+d|zhZ6=l=2(gbzW1?da6R7bjlIPN~xsZLP8V7pQ&cFvH&9MbHB z8S(@*K??jEie}CJycB4%Un3<;*VyLTuT(ZgN2l9ojlN2nk~}3juua~ydwjyUEjyH1 z%GF@CbVuN4Q)?3g$0lq{Q3CHIeE5V^;MjQg*ueAlz%LbN`qh$Coog?)C#tmxlcc-k zFE|3h^oh}qQ zt|Fg&xEtYGLD^!dNjQzeF-)Vd%VVy;Gu}75^>`U5SHYUwA zInlLZ@?U4{y>fbvYer?uyEDY6R$Mjd{EC^Z-f=#_m2o7{u34@9`#aCRMpoy2d^|U2qkkfoumm+MMF$!hC8j+fl_SP7p+K9&E2Hg8hX_q9i2HZv_>E zv0^GLGisx6yI_-?;w0f}v`s|IY;=!aB?W?E6BBr^1QG@n>Gwo&9^i|Oa=EZbpvx`= z!7kh);2H}1y@KdSuq_rZLx1?IYDoe{R1$;?hp-YSeE^g=UX-O2c@(~?Lb3qdOP7n2 z@Sj%{Y<59Ra0n1ep-!ACtdnHXfuqWQ01^PLjd~RAs#6qlCeN00@LLhG9f_g~lN6-6 zC`3bPzFideNWv(=MgvM>hnER2PhrwGg%vKQmWvEKbX?+65&9djj~5kTw>V+UC?U%} zK4GSmgSm;~G+_ZSFN%qn7xoIGS5Z_j@9CmlI74U?z>Fy=DPTk4&%#bD;bE3?wj>M9 z=%0y8rQ(Fy@>hlYWc+Cj(J9SFpEluIDMJzL*9nPYt^-C%SS}GNffV6;f@B}ZF)IkE zLXu5VUbfR@(g>@d71a~OzW_EBpO=Xxc6xIk;RB_92}D(xLlC<`d2ocV9plM@%bBfm zN~xkW69{KEAVjz|6`-J(uc#ORI0v`UPyz#Wa}{ix#oW|n22I6;>*ZVUp3M}~7;u0; zOJWyoljI!|E0E{dg(M+W5t7mCXx^hzChSF#*HNEzRjmF+x(|t(frZr{nQ;S-=kxqB>1FySeC1Xqd`%E8OBA`T zrkq0A@@Uk~OYuiR@i_y}M{A?eB6?Spl(J}}uth9Nlk zRrD$NFe=n_2FP@85-Y+o|6T(P%A|1IJ5a zu*Si75OtQKPOeoaz7Lx38z?VBx!uG|)hErDjHUN$(P+Tz%NySp&BulEy(lO9Nbn3V z_oDoDl+V3H`3jW3hw@ADOaSGHU;ku&XhNOazwycZK(PJ_^<)XX{ z<^N`uk0|GNqRt1XGuFh_MdMIEUqhX@>Z8#aW}TdoVA+d0CqmKaB5SPS{MUx^#DGN##76GsX!HYfjEi{u|10iW;Or`^d-se1K@gC~6&30cqoRai zzaL7GkbprV#1I~0^svu9`(#EYGvmyJB!~zaH7d1GqN1XLV#SJpg;w;UqQxskucTMB zYN=YGZCYu|c(I~V=l=iSwB*6y}osp^WbCW!aBYh^dlFb z*C5&i-35K2`dZHD!E+~guEW1k=UvA<=Jhu4t$3H|`)lUw*KW{H2K_1>&mqVq?U}v{`r)8+jCO_(s#W7(2l`IXyNwr&a{}}`LEmHAqsx%3 z=9+84x9v*k2GgmGJ2iZDC+Issf0Xn!^XC!rJP4k3e>6M$0C_N$SI1KFU}fz%?_HRO zWnK=R+rYEXxUw4bJ3&8@@m2Cl`6lQOfWEd1y@v00Fb{vcuzoNOnA$r#!PBi>7{|S! zUkUnR{p}I(TzZw6d%DcMOy`jO(BHtr`M+CPT+kl`eWAKoXXLxJ8{?k<{ZYtYr{kYL z|A9VwHT2tz3Dq`Z9Cv`{(m$D2KlYm0*&9jcxJxd7>R9TShlLGAai?OsNf5nHfuF`3qJl&1|g9m)*zz;uNNwMy)gUq^*cKSuPvEo?p-2=V{ zz_&~1#cj@yyS+Yp6uc+iu<*EY2o~gPK)(?2Qva*^$Fhgu*#RCir<^=GKfP<8_Q3;G znl}T}8TUn_aw}J28Pt4A4#J{Wkll8nC^kp|-1VvM>q+KqIq17V-;IAGO?RQZtp(q0Ca^Yh7%Df(lL#Nw5Yx?NuL38F& z>RbwXc+2eUUAny%+*8!R+XU}Dx6aN!jDIta-PSof!L#GG?){DVxe4^^KsWo2d1Kza zpx^wt+1Z^sKlA8&KtKHUg~#pvu)#eF^iiG1dHaB4K_6a(z6SI=7NHM=?%aX4*Y!Uy ze>*`x{4Zx`Z!-EXhD5apV_W<>98tS@z|H=l&I-Kk+5>Aw9OtlV1yZ`c*S_c3GQ_g1!xO z_S@>%#jj|6R8GFMws!66nwJiFLy6;@(|}3fmRd0i`%_-w)8e$|g+uO8eEf08;hx!d zWBecCZrMAo<)?+~#(9)x(ed78Fh}w(vn*Z`_+B*RMTtWL^r92lQ0fi2$2ZH1os~7@ zVsd1vxY!xsfy%N&_L;mm@JIX!ufExzaPd_&uqtg>=FH5#gkZm#Q^N-i0G&yL`N31_ zt@v959mA2Lf5l*YAPhM7;4f{xFT^M14@3gQIt)0^06y?fYU+%J$8RqKrd>PpM*g=M zZ237J&^CU;(03bb>E8vuSHy=%obLng4+h469PmE?V_H%8T;Mwe{}sTG2>zRaX)kZ{ z^O(UlyV@vme)2nM5 zg5zbteAl4EfU^qtVbGBcNDn%jfgb=q#NZDA^WB3E1J1{QH=uln8v1>}t3~;L0lZQ0 z{}=F4pdV)VkHvoLQbBitPZ0Fi0`qN!4g*dB{4UU`e$3x{f%zuG(%%pKIPz=bzZ-au z$p60r^Ua3k|2c3A@$nv>@g0pl5#MuI`U`;!tAY8>!_qGRz72GID0w{Xajplp z^>rJttna@7J`wU8P5Z!gtHL(EgMoJ-zx$c^GT?he{tMu153Ff+q&Px;oVy-w_;&#x z1#Hv*3i$>8SKt-Ew*HPlLeqkNGVqZHb>cq_m~R0XSU(p7hk|}7a4Im|VLSGn3;Az0 zSVaK*=fK-g9`Qw2z_wSo(Fq z)EA3C4s744us!~_!Iu6VVCs{_KLDnFTKr>R>Z8T~2z;19FnV!*2HXiVvxlwK`pEeo zH&spznEHodMBx*FsejW3&j@+WH;n6Mp`Qm}e87lcO68-VYAX3gLM=i&-}6Y#x){!ZX!@6+wg`uIHXgM$7g;JeU%)Q185 zJrD!SO{h-{8>+q&;KxM$Hh_nZ?4&;oJT2(-Rr$cPI`j_$KP>RafFBk3lfcfiJN%yk zK3w3>0o%7v%>RQ1LkeNg`6)2d*I`ia!+?*$7vw(-`x3r`vh-&GvwRjm7uddSBL6E5 zw)AztEWgF)0<*q!Smta5X8r0g=rn*2*=_MY&M@$>p|XFD0e8a8>{r%n{%!aY_qfiq zpi`gdv-(a^AJ+o^MBtAA?-BUpz>f<2DPXB@p9SuOnc3R~W_r6T{NEFF2lNL8CjYN0 z{J#}+@;~LEPHN<@0n7ZnK+wtm5`oG8iVFW)K_~yK1t$Mkg@0Pm$$yE!^6fZeYIITn&EiKN*O17;uh8V@S;J zcM1A2pcC)H_f}rg-*4zPK7QUN^Hv(eBkn$L)#3SKCuqE zekDHa2+eQl_?dYpMEsOse_0LuEwmpcxnBAt@Qt9`^%CVCeqoIt2s(a=cY|MIa`Byq z4g(H;zHttI5cp=qeya(8h2bAL*5gl}T68qqnn0%L3`1#gE2Q4pg3VDgi zx4OcA_agWt$V>Wa;0G%C=Q|i3O!@+kGkt-{H!ScL&?SBo@PQxb)YqQ^HwFG1;1#d| zv+eZ+@XerG%=jmcukiyx=SSifJ##Moc;H7MZ`2WYT|Wu%-VOF!k5sr$CYH+i>y^8Eokx zF!kBumjYAYby$X9B-Q$8>8AlxA1z)B%=Wc-J@CTR9_DwkXk9n5HmVPWS^}*sHVEYD~{I4xCj)`3ne=L<={ z&Co4BKlvVBhXLm=Kqr>-g`^+$oVomznR|@HswAHZKM zbo->B^StI~z--TT2A@{y^3;s{PGI|%pYfe3@?-Tw*3TP2ml)Bs-^{ZIje~CA&=WHp z>($gJ@igcXZwHq3@fP4t!2SVP*2gE z@yMQ6>;`Tke`}FdJHHd_fcuT3G~MDufgiW^4T(PlKJtT|@p~BfWPvGnn_tu7ramOT z2K*9}ad(BEJ_vLea6Slr=3fV_CxIV8elX1=_Ce=9gEf87*$r&{Es*{jgDrjFXk8wQ zp9*aKFOc6i*wRyAme=BwfUQ3U@{bs7>Epnx4~w?|%l3W~a3{>nUI8rI+g-2gCj}GR z`<;TH?fHpHe4iF{uBUIU#P=71ZuMK%@85tfG4p2qNw9{$2fDGW@*gN{$)N5C)f&w+3JaLu_90&K6Xe}FsN>pFNA zc%5jkeV&W?Uf=_On*u)rcv|3R0`Cy`XyEq<{Cwc61b#8_^#Y#&e4D@#@Lvl2GGO{W z&|%P72~7V7&oJc~HQ3T8f$1CJU_<|i!Iu6BVERq4^luw%=??(Yr^2B|e%4@1-=~K8 zTBOgZgjk0`hfPCY40ipI8*J&Dfa#}!$L4I0KQY+S(Y2NTh64=!uMD>IzXqmn2OL8y z`Ns^l^j`zh?*ot382<~Nr?I6U2fSLypKGwCZv;M5$iLHIOaCKa`jW8ayVGDx|1vQB zOxX7M7lSSRKY;0j!q)GzaqvoP=`~>br#J{-F#l&5Z0WBCrtgaXVd$3{Z0T9+&Z=Y_4`9~o@v4+GN|hHamNpRci{9|8PrA%C*LmVO#AeQ4PD-)OLm=flST0fR05Bf#_lV*Ag%23z{Kf$1NFV?N9GD}yba#uoG)V(aH6FVNW1U10hZ zvGms(Z0R{LeU4cDzS3YzzXo`RkpHs5mi~2M`YPE6Uod}<8f@vm1g0Mo8~-sc)Y#Hr z49xM=Vi%a>sl^GfobOHo?u41yQ-S4tcg3)te_SwezIzDxNR0m%8hpWso=;XA`~)!P zixUn0*&FouJqXP8-0>GV&Mz>iEHiilnB(~&2LCzme+l|8fH}Tf`kO}ec#dmp72lVE zIo@0Pz-B$ZtNKHFtARPbTlzbJetEvgz%TJ`;2V)Y9R{86kuLCqz;_A!Q{cx1-UIyo`>p&k=ihC*i;C=;Iw%3<0zGw$otsnF~v=Dv;_^WjKjFS8kuLZxvuLiyp-HoY_3_gfFPQ)93_cp;1>2Lh=cKO#X8osz zen0ew?e~bmgBR=iw)6m)b;#H3#*=)~4<6ZL&3_+@>+7q}BvatuLAWUxF?%#GLa_uJHq5!1>hi1u6YJ+w z&>yD9mgo5Q7%`F(+)+xC(5yApJX8P}+&|Iq#uQ2qt zZPMj^)Zk$ezpX!+pBv0G9P}F>oi~ei&HRM}qYM(?1bRtdGNAuk%keBiEe`>E~@N z>88Dib%0}s<22o3e$sEA4!V6MJ_7s_laK!5bQo}+4Lb31d|}g*^!0{r`T4m+$e#zg z#H3&QiW)xs6esrokZ#5&--)zB^e81RbgJNj`Sa1;FaXx9(1gE;_jeGkXBA>@TOhM(dN^|2*`1o!{v5yApHAAQ_5Egp z{|=b-MLNg-qqpn&vGR3b){mVJZUDCaAj$s_FzfeRBmaU+=Ei@hC=dH@#PXp1_LH+(7hCH)FuS)cC!?u41y_b~ojYv!w`I9Cfg^Y?jRDgPxw z=Xv^H0ZaM67Ie!0M@9Y@f=>D0ROAOv=;V&_F9Me74+%QuBVd{SiGoh~*Hq-|f=>Ce zB7c#fQ+{Vf{=I@u`CS$H4+%QuKVOmmlAu%muPX9?E$EbIZCoze`=3CU_z_@PKR*}p zjQ??9SwFuObQ}MTBL3&N*#8M!1Kx@Lsq`Nj`byxNftCIPGdv>rr$LvPbov6-VZgZr z^l8Z3@%u)DHGRHMdpoBk)uv(3+-^+kIVPF=M}=SFFMwZS@^3h^#t(!6=PRJExS>XXFz9?8c+Cwp0)#>5o51JaP$NJX zbp8hTf*WcC2!qbw0?YdQd*DuheJZf5zo%WQOi$?#@V@~wJ@!P>zwu_B zzvmeIFCu={|Gt4P58tI(eU|0Bz|bMi7@Rur@{iXPqQo%pE>Ry7z;_6|4fw!ymVdyx z0+{|`br^8o4ZK3&Yk=vu*3z#7rjJ>R`B__E(-8UjB z(9a*ODQPP&@g3lon2hv`t%FWa;xB?<;=6&Dp?o^P-V^u;p+DaOX8A4s{{TN%;O_&o zzAXJmz^qS;9|nG*!2b$-tiX=~zgXb^1U^pSCxBN7JQ%|sRp9-APZ0PZV5!fC19t-M zTY#lL@3~B;KL{r3^Gl%L%pYrxcodlFS$qpH)3f+}SLph)`@x&us_SRa$o~s4%Wv^Z z-lofA@hC9MYva2GnC+w1ljtusk$?7=KLpVFc>qDLOlZ*J6zsoA=?GSYCH{M-I?i%$h+`WBx7e51gx27W@|^MLQZvBUp5;J5y12N%HqN8l0QpMR=D9|xB0xdpfr z@E!E`6bC1E_ z0cLr=X85lV`LXRO>-VF~pQ!H}fuH;7&i;pG*&yimgD&xRfiDNYozKaCx8P^Tk$7L= zt1A2}-dLj;!hqv}E^z{UPlf+l!QTK~V#e~VsTw~JPzeYU4})J~(&7Ju9|)RX;xX_` zOs*RR|1{_llm3XHUjn+smjknYbr^Ks0c`zQQ@=lFu%&+<*!s05{ig<7`W|4`zs3I! zyaD5d#g75AzAgSW@b$p|179${7i1b+`f@6HEi`WAl}nCW3yRO8`+@6_r2 zEh?1b<0LTif2^TDF4ALt9Pu*8`P64S_0PP>^1mE(iAn#~B{hB^3^=Qeyv8_B1D54` zHE<`)%$^S{%l8+^ALCz({8HcRf}i=jv=ZN21)cNr&Psgm6?DpfrXv42L8tuZEAn3w zbgM72ygvk8VwP?Bn`)+r1I~{@mzac6LH|e4CH@)kU8sNCAISfG!GFYwbMbS4zb)G9 zG~jOu{6^r%fo=c44tO{4QxPxw*EfKVx~1mS4916Z@|%em^!P6E&%rM-xy~2-kAp7p zZ-Gxl{QIcb2AvoGA?^=EdK-ZE0Neb%1^B32JLUf~;F~~K`ilHA+;MqLeKLRF1%2(c z77sdq2mEQ2?@(~CeEXcFu@)F~4ghBTTKo)P)|bW41ZI6&d^9lY%i`w)hhn~XF|hS- z&h$1IZ22z${&&dlk1t4nyTO+J9$>bQ#a9C#g7RAay9~DUuK}~YEWQ_*^=t9BfmZ?_ zgfE!huMD>ISz!82w|JkIcl?x--!<6MV_>$I#U}z!03U!a$iK;8OWzD^{il(}6o-X7(&#IX;~OYy-!GNnk0z4Y(7qp8%HfJAiGV{0+cT{!_r6fcMeB zQvP;e8z}!HU@89)a3{>n?g5ta{|0OW<&RuBSN>?=PMDcJ23X3!NYE+2z9N5~pmRLk zSdq^Ko$^;!A#R^)#y=#+oj>bd1V7`PK=W)BCJ<$so-Q=YtXK3fgC#H8PKd5s?k z1M2VLSJc!e@#)}~{r@ZxKl6VMuuOm5P96V+h=J>?*9v~-=N*;!-XrLY@2X0C?-O*& z-(8Xax}a13zKZ<)f=>BgSLC&0eN$Y}mz_GdJo^LNK=}|@)<-7jO#h^c{3=1G{8&YP zO3*34ts?(sL8tsp75UE!I_3YoBL8_or~FSV^8YO8lz*fmKO^XrKkBr(<$oS`9`Q_v~@=N0+S z3p(ZRs>pv;&?)~&MSe!mDgU1p`QHdSNYE)yUO7Hp2)e{2 zu`O5^I@}I8A-y-Ogzr7-Vr=U~*p^E$-L8tt`Rpfsz=#)SDjJf4M2DlSo9|kPz zZ-t;!{=AC(MnPx#c}2bjOnHRz7yB+vp-~$c+*U2yFe-G?H{%}M8zre#s)|5XC$`7oC{0sH@ zJ@HAvydS4Oec~O!e6PUqf%rjS-p}u6%6H7GwEe&eLq89g=hLpiUjU|kjxGO@XKMQ! zi?;&Pet_>g82^`nc|L9BpMMtW?^QMDdK2H3@_f$!9proE-QI0>2fQ{zUgP@%;vv_Z_yqht9@%1=?%3iN6la^Q|=oUkQ9S^2cxp zQn?0LHHN{T1m=0!`M|8t?*Y?3Vxz&&-Js96hE09H7I@e08mNqKALl|~+TSe)ru>J2 zY2OeU{17nh2QB?M=ioeQJ?eK*^Pd7N+wYUWyl=7fzXzE26Sh2OoIAIDKLae=_ki=} z(k}v*^lt+1g#KJ;^0y2H=lwl@_kj6d3C#QU8x4K)1<(()$9}+UpWUb!`tRazs*!)$ z>kuF6<3L5<$NAsDPkebM~0}yQHq|%dNh=^+KE%y$Jei=m+MG@^^JF zznS*A=Z&yO!}zen@V^5QKPc+^qAfU2LjT-p=wG`; z+c)tyGnn2CFzuIC82XuSa@6_hkp^D@%=k$i;gbGqZ8gdcRYG8FzvPIr=9$N ze3_%{!BP|7&<IOwEPttmIr`dGVDb`?uTWo*-Bes(aKMC zmTy~fWP#r-!$#R^crC9{#@Iw6GH;1Fi_0)g^D=4$h^cUOWWF=BHXj=w8)`)@KXJ>% z^BYN+`EeslTdv{@kcG54lr1sYBuleq*z}54>EXXvl_6MSWO)?CY0>hsAS+@o^i*VF z-(~RK{#m{LS^KX>F1mZ_0TN}=VM8^lSRhFR*BuHVpU#GN!IrY94xIXOO29~rApjOInjew2@n zju%5ijqz<|b7<(4@ooIFF)~(+H_@HS$;t7_p`laxaRz?*mC5mcbgCk16lv3ovfOop zv`kfz5+)ZXs)u%sdBgHm%U7yc`s=zu><2B^3(F#Dlv(bpR8ln9D>s~;)~PzDoRY#& zx8EKU_stoZxck>+um5a#R8Qudsr1*^JzLoRi{P=pFqNeLR2Vx&SjYWktba~sgK_uY z;XKwpMO5kg%a3PUP8GjTnf?pmCC+j)@+PLA1XJatADmrIj^v~0lauU1=RwiWqN4jA zsG3k89hojC^U?Yi{Ju>x?6#8BZG~kJG&24gj?(QXQPBQ}xKPbe{g0l(lNgixSI40L z4EX(Pte>gE`5bw?WZp_5TyyHmb*${NY=jL=sBxU6jaUy?=&_u<`|si|+urNH$e!X? z8Ut&retQ&hg;Y?k<`8B_{#Eh#zWTSK`e;&oAF02w`m0j$Q}u5pi&g{=YMpwOi3|xJ6LJ znb&GYSu1QcvBD{nFfE#47W!dpsNE7hIol&uPtH!i?a8XuLAR`@o7U59>-oCrb?bU) z-bIV;Ih(gkjn+4po2Sa@p+Z!i{l1vkuD{pK4-K3sCd<+K@Ca&ISDF1nEn!oeUdX!6 z&fc(c)fx2-XR!k%L6W3_k5xvqjDu3o#87H)j|M& zM>dU>&6NGIzV58E8D*LIQ3JpB<)v|mHaZn;Z~913cwy`(Mb^q1_**oxCeki^KMkT* z6b9@b{j#!(w+%tl`xW324*~sG=_ES>stdJj+<$6X zqhh6Av5rFZ`WZU--TKW#LEdZ@W!%U! z?A4N1s{5kux+*mcFq@XqeEawooFuGOpKANl=UGEoG+Wq&MM;#q*t0a$qOLuG7H%A-Zc@69 zR)dEdZtfScU!*~qWEcb!PJURBpf>Qgy$0$j)gB9ba+>y2TGpQR&A8ZGSoMZE3j{mI z+Z|(6VwO#CUeU~AH*6-IM$syU$sf%aX3k_j)~px9IsO|;Tdg=RaWK)aTfcf-SJ=zu{Wt?IuT?IY4|u&%hE;~H{(Xx@Xh%gG*|U2qw2of^s;7> zgsz)rek+R$7g`1Ed1*5aT%14J)k05J46(?6fC|ng^0ATPBDAW9L&8>$)~FAUk6+}Y z2Dc=Qgz)lhqp1@E-e*Pp$i zzHa52r>{bOqA(1~W)!<+t8BHhP%O-P=LHiJs#^W+obB}#dorx5G4-mB>*j4wrnQU! z#x01o*H*o=*FLD}&Dz;s^wP4dw-*XZAS9VIoi~6HE$yr(@?22uEt3kJO|DUl067EjsWnn*Z)U^Lo1#sT|=qhx^To zUIk&(+P8ozZKPIiaeJ%Nv#NN)ffbS}XWU*&^c2%`RdpB9TTHd2+(jfRBQ?}(o*N@dy`1- zIZG)^Kj%D9S?as$8Bnf;S0-rLZCq(@!%hW%lv-t~xih8vco4d7} zbq1!2Ai#}O;N`6#$AZuEI8~VGP&4|WoeK3ifVxsp(;}pCVO01$%xT6r1uzSO&al(S z+(zg%gT#wMA4dRX8GA0~YS+)avQ;#AtYtc1Z`O`Z_Ka245f-VaR&1F2PC<=F*jx84 zpgWdICvA@hy-T7-xl{?KPoe@;OQ%{`4Uwt-MzwvqSlg?lGQA#F^4VewV5p-yF6gM4 z-O})Q3zHa&I<<9Vx)>h9HSlOT1ciz9)fe?|-ZE9)Jau1bRYiK}k`HJ&Ez@uGJb^hnWOaP$<=r|US8>o-e!Yug!%dZ(ag>;79>FAYQ0bJ-2U5I-%NOJ|Ba35N99T> zx~C^hPhVVOURN}Ib?M<~a^VH6TJxfS*!Qal^=7esIfEqHdnNu`k0tuA9wrux95G^H zqas&zSh?^-gl39YQRzBp@2Ehj4BJG3zxQp=#H5voDxI z^gl|ftn}X2=}J+$r`l7gqQ3X3*bpq3Adh>X2%+7%iGxf}ooUvK@hxL8rCfW~s+DW? zF=2hxS?8R&VezBQ;M|pKvCC`u(B&pfxWXKUlUbyXH`{88OPmPzz?l~%SsX?|lzGj< z4;pz`x`~%GaD8PDSQ~k95zh9DGCRfoD=EjghiE3Jp1JarwWqG;@nzF*`GuQcHS8x| z+2o!S6>27Ly_r!O!;uaIcDRM>X71^Gl5|)4_R%kF>B>#Cu;W>9eHix;qa{q}P8*-x zoKNes{&o5G(eYdv(;>GZ7VC)@M+NSS$~@4uW3 z1#kDT-dS(25qh%f6)na_bQ~-q@fRyY{?+};u7dcD8o;WvnHpw2*UWTkvh>U~pFR`z zaPg@cs-8E-C#P|!+e(5~GjF9)mQ$ta0!d=sOlQimM!{0on`-&g7P<>7w2&H|JxUa6IAR(kf}hVVp*3;)nXC zSrxQ>mW$$I#n_LWs;0_LzaKe0QfZqmPaAddR#IPBP8gCcXY6q9&l>j=3r6QpVi ztdbUC*OQZ4WVKf#i?Az3ZF15!Pg{gt&oHVG+Q_MWvbl(m8U;HeQWK}iMJvstGHSG< zBH;BeY|le4!5Sw_VKipPu3nsK=)%O=FTbvQt-9?kLDDM~r6NYDbze|g)}ECYDY-gr z{XJMFV4Yy`6vnX|Wo|3T;!f@M=4@}Xdb8@5XpdCA1ymJk zy=xma_FV+s4b-4xtRGaDZ(BR6i}Wx|gCN6gY+1l)Ffir_Pyw}8=3kX*<^ju4)otb* zQ|c%yYq&+C*DpxO5c0A-*<4N!k2k0M>Wcu-)CxH+VQDu}VvxdHmpb0%V2Jag7#H6` z6HBcq^1>Cq_5Xh%;@ zCimT1Jb zEh?!!3oTMfim|=rYuBtk$Y@_;E)szn)6H05^SubWZisgEx>1ZBDsB}@FMvf?l(g_B zCUT<|Oi(bI7F21|61`bbN$3Ne1EgMYtD$RYM&4~REY_IoEK*?A9k63IrO3U|jiOc- z=+QvE@=%XEdZ(ZoO{c?Q87pJm zvDNqHl)2rcJ)?uoGit4KLfczFHB_p_)W6#+=Dy3U^t^LG+A~ePy21e|vWinr{GESr zwn(e1p|Eo>lr~#1`)-C&(aij$k@%$-HJW8mmPKA*w>{KRklw7SpGyVAZ4vUj1%_bh(wE{i^4dbGv4;@vi z_GDG5n8(Q!t&WyiBpEd>S1xuJVOInAoH_~@iybwhtPC)!>9MWd$>I>t`n+b8;!#F3 zkMSnbO+$>JjYf`h5SOzyTe>}p^yKfnuIbI%K5_5K`eZWD-a+?{6|IHB>A&seNl!6# zZLUVV-mLvsbmzdQXRNsKGaautt5QBJ0s0kC9izPrhvIg<5$`uPy(q^4f8PRHv-KFz zf92`-SM9|d`+s|;>{&;853jF{a0}6IR`q%duSu9%|5?@N0G-z)y|bs9q+?vrTR@FF zdJyVZ4D=K;SKD?D=(ifoeYI*gvs~0eugW$K@D~}zbTg~*y1jH z=I!88B$e7MCAa39M0EuIN&2o^J`u@wgWKGchVkx=R z)&fhCR2_IJk}ibQjUJwIsDY$?BH3?m)62Z2q^*yDmm;aJd6&|zdXQa8n)+sQNs>$M zr?3%%)-EMYZLGK?NmZ>&k<_>DOKBCou3t);`W|H|l6oh(BuOQ-BuO{g z_NnV9thSe^f*yyKB`L4D;#xvA!NhsVX{ycUQqt7h#U)8DxrTVSxwN|Fx$qJtms~^U zq@M|!(V@@D#XRm`O5N%wCQFetZXZN$H|HZ`P8}u#`Q)_Id6&O+e6l&EFmA!iv5VC| z)%~mbmpZ)Xzxb{negnp)>!an^+%G1}yxIPSZ*!v<1|yqs;yx z??3C>W?;+MR`?l0KGk>XhRlLyIR_$D`YxiCK7Vx!M2YnWtL^!sKpVk&Ea#y^Wl@sPjQ1Tv(>|Y)!Ol`<>Z=j z+al378?Z!y344?NtD3q^+I80>`g0~GdPEPSf4F}sqC76LxLH=B7fk~quhgJSTZ(Dj zHh!mVlCbc@Fvoj>AcG4wZKX0Nm#Uh>Cs)lCS6(oca+@)35O9~(3Sinazow%F6X;&k zl@yW&oA&rcs7So^jMQ*}9)jcE0y>V%{~*cnz)WS|x?_se6C>ORcB`UdeC*;9 zRwYBHO^$D-{^3ALU98zw-xNQ&pQr#~b#k~Y=H$2Tv+Q=b|h-!j_NR(O_gY~1*wnHnD1TpyXLZyCdE2;)K4 z&U_~};cz}W?fLDwj|dOmS~#P|oofl7C%)(D0iZ3ct&rSx=bWVl2&aqZ8ri>ppE>Cg&KN8~l4C~W%8ly^IL zh~6##UY1Y6s~SdUbd8d>24gTgK-u$Fl;$ulz#INDZ*f%PVgnVR)h?OLx2hiEYr9OX zSIm8!#xTFk8Z8({V;a)RxOqaA+P+MiGdQX9LgQ|9UK#MpEW`uFAZ^0^gWu3yRcFEI ze`+!y)En7o1`#F~T&WhVtZXzz+p%)mqhEnrE|}$nt(FffhX!o^Y!j2MJ=IrDN9a9c zZjQOAX;1ZmuWTW8E5t>FB}@|JEm&%VwmDhoIU`o6M=VtG{P7C&iyt;xDU1_CuTfnK zEisoPb8^}6X!C)bCV8_}G`r1WS_8YSce>7#bK{4eHDOMX!)sVj7G;-;juwu;>nu4p zevId7)=FY5IdF}dby>455`WkH!?U1hMOcWy`w2!@+_IsYcUwn1$^6faKW{bsMo~0c zO*r=OeKE~Y5j$%ty2I$Ksi5e75@^0T{EW82p=QkUUt?w8`hn( zp}uP6x((;7Kec|&*~+XO_T(<^mfR5al6rcC zV9UhQ!(1npObnYPLX+(hMh zlwloYUn}F%4CdT^gp(jF&RsW#aRf@M=Z%nYKgSOub8(8Xez?V!Lr% zz`(AET3muR#SSto%F)qqe5}B1e-{3(0^~Ay1BZ=tdU87k@)1tx5ws7lscCl2O-Rxs zZ>)jz(BTOZO*ljB?K<73M9J#`y!rPyr5O)NXP)^68Tdr8zSjs%;9a`IxVbDQIJ z^Y1zxcj?s&6)l6MsaGUX3SU8PQ@6t0f>* zL+EQTJ~5THwu}{A9>=GRQD-xCprmyeOSdqEPq(DiEU;BZ4$O#wwd@$=XSV=pz?}cvD438jYw4|4*TZp`b~lPE(EqUQUxR zfk!!vWJ!RMX#ZkM(bOQysdY#Q3xh0!+jpozrrmoXb3^dZKZQN6eOU!};P#(ukx@Lr zfx|Mo*VkR3O`N|4#JtmH6Uz}Cyd;ejp7GFCV7UrqQ8nB1$w`pvnq8nS=2xsAoAX01 zOtBNhPN7{YRCNR=5qLQOUo_ZG$Fbgq;fb2stf-1m=bv=s^(0<%%{w7fk<5Q>luqXt zm325=M^5l&rv>M8G0yI?ybSdM^Y@k$^X{otV)lV|^)kZ?sKg9lnLhsc-POhdI?;@p zX#~&s@OT&CagUx)e=l#SWIMz$9uQ(x=)stmE@pJkcoGV6cF(tG3zR>_Je@|3COm=r zKH5N~Ja+)~U3C_&-$cP}%5d9z4o<-${PaT84G>FdwwXHDoWnM6nO1#s!QaW4H<$6} zAmAv3=deDM61nLlZBJ3u0f9YO5vSYH{5cxO3V4*5z_A{BeZ=3Hz%7~#njTr=Y6na5Lz2{y({i=~kVIB_Z9rq++$wA6V~2e)%}w7%Za z>eDw|jljgmoWFTES%{JlkCDqb@pEy2oNU3XO#EJg=bL}j`2#6lgy#TP!qWB6{GCoX;-Wo|J$+jv)< z0c_w+S^EeeqHp)W!>j>+a`55VhivBrAj_gg-o*OfPiaDJgrB^+MQMyBZ{lNU%FvJP z_PndFsd+l057xV#OR3_{xqO&=XjFP0{5rr69}a`F42M#-CAzq{Y9|Z7v3u)@wvS}Q zjwjXARRewlnp5!qS{4^^y@Ou~ib6L==fS~fsrPtGaHFT|sB>tH=b-qdm^8rp41UwPc4t`$<<^8Gc1S`UfK;mLAh64wY5SSa)NbJhcj1uv#6t|^pf;YOOGxN3;) z>Bz{ece`p*e=&IGXlgH_u-ln#uG9L=ggrspizw`TwO|x*^$<63X@Ez71)dUka3!5% zY;bY3k|jZacdN10+#vR{82aaP%kA-nNT2QD**R~)T=Z;G&z^@ zV(C%XBe}gO$nQYE_g*{w#kvRv&i@9FgmSq4{d(82YOzok>D|lPeSPUsw0qgoqi8GV zlA~Cx9B3bVBX0dvs!h*Aj*ir!>H^0jN|1BK94j8I`0%z4`-^5#;D(YuM;Ls*x}Mb(Jo>A=q? z3w0}7*FU9D$2DX9;(T;VX}-W>Ai%I4VyBtob`U>>(7A~*XY=U>bwq!9GZ-tkCd%EA zx=!wA>lR~HZX3>Fc&4l$;BUr@;0PWk5%B)v7K_EHYOCjQ zpq;q7<*L6JY;|{w0oAP*F_Y6tFqpV)LhvB;A+u@`*yun z?-o&iS@G?>u@_O;L4WB{*a3U#G1$)CEe2DiMpcqi^c|!ZPfg@o$FRmzYgiZ?^tjo1 z)#>;dvf%>9!ajy@ywit;1-;GmS<#E-u+J#$GGT#2CVK0k4H(QBB`<4uz>Z%$G5=a% z)G}wkVvURIP8g;XIc@<`xStWnA`6aKtr$Q46$fxXg_{#NqU$+gA^x}tE1?iOMQlO! z#{U2FNDQyJ5sV%Ai*YdHFqveZGq(rf*=x=^XYFcxNsKnfe%-_R6V3p*4N-2#bjQOL zUWj8w3@{lyoWbA*zUx$5a!(B_jxa3Yod~}P1G`VZ(cn*bHgcRxdvJ2Mw=v+iEL7*; zi#(V)buVHtqsLyvV05}$4CuG|_yv1hSWH%b;IzGCTXd#YTCAWHK zPvaC&ZR@D^XlUH=!&)xGjd-5m4$(K`Yq#qO)y%ywIBX+zx$NmP1~YE#MIOv_v-BA3 zf_mvO1ZL9g7Q^qOnem%XY+}>QFqKH)>>$Fa7cA=Be352uXAb9*ofEGBesG{J_?6ru zgX=@sbme}@Uv~j}q<Se_fUSLr zoWLhhUW`m{uaCpZwxx{`8n8Von^N3@)%w*gl2ulU>9fIVvudw!|J^I zajvwP4-&Yiz)zWHxN$7;y8~t&03QyE7tt;Q_A-OrPlII!;bg|k!vvQ0Ty9N9)$SOu2vb+NH~p)5Wn@t zGs7fn;y}kPMsbbmQr% z$B-5FDfm$>To?HGo!_u!mw-L}EO|yb;RaQe4$gbA{0QK}*Q^?P$6)GsFJdrT@x6$_ zbkYT5=;=($O!@f9R-AL=dcjA)RWW>g=|=7ufyqI)2-wH;WdGhxLIDdp$Nsz+g!w-u_<>JE{#wJiZ^Fz^%6xN|J?x;%`+2Hq7%m9i9 z1tD%fV4D|4aN`QYH0_aXDW)Mfqi&%WWpt*9C8)I#?5S#tXd3D`*0v>LlCzebG>d3j zm(cSpCsdE?KHs6fT9`^3u>GXpQ@!2z-K0}FSAjjeo44R+hklMQQwHSa|XX8!3GgPb3`oGxMa1CuZuVBx__44U8V7upK_$f)an^PI;?WoPJKb9VY-J&l&20I5X zJqEkPSb7ZhfNJS6*c0D{V!$s9X90eLFp67v7YJ8-F@AokiQi0x2Wu?O3;ckbUQFUm zB7TS}#cJ5aIul2t_+K|??g&%rlfQF~ zv$(hkQvoke6AymPtp@%M5=?YTOeKRNm(XaK(?^&P8jGc(6uo!NSQS|yqluY9)x#3l zX$}qHXID4jk;!^~(9ZYt<~FsV>OR6(Cs_VMdkYSJ8+f<`dr-Z@(0hCCWwPpCrannS z=xv}O;<~`01@UV=(OI~cAV4Gmg8#Hql7D`Z=0*B9ihXHW%|9vU3 zUk(2|PP&~yhh^sTsrV${q4+<&y5^);IL>278zMd|-@*7d`3CX-id$>WijO(Ym4^VB zVELW}jHH~W;Qu@CuQ_+#>Nu}9Jp3Sy;ko$V@*T2U^X*U+{m1ex2V}agp)o#Wu^mX` z|HtEhq&Z;;*=>&VJPYti9)_3Wf0n_9jo@2Xcbuo;i);4L Date: Wed, 30 Oct 2024 10:16:36 -0700 Subject: [PATCH 04/17] feat: executor optimizations (#1712) --- Cargo.lock | 1 + crates/core/executor/src/dependencies.rs | 119 +++-- crates/core/executor/src/disassembler/rrs.rs | 57 +- crates/core/executor/src/events/alu.rs | 4 +- crates/core/executor/src/events/byte.rs | 2 +- crates/core/executor/src/events/cpu.rs | 8 - crates/core/executor/src/events/memory.rs | 8 +- crates/core/executor/src/events/utils.rs | 37 +- crates/core/executor/src/executor.rs | 486 ++++++++---------- crates/core/executor/src/instruction.rs | 4 +- crates/core/executor/src/memory.rs | 27 +- crates/core/executor/src/opcode.rs | 2 +- crates/core/executor/src/program.rs | 7 + crates/core/executor/src/record.rs | 71 ++- crates/core/executor/src/register.rs | 4 +- .../src/syscalls/precompiles/sha256/extend.rs | 10 +- crates/core/machine/Cargo.toml | 1 + crates/core/machine/src/alu/add_sub/mod.rs | 66 +-- crates/core/machine/src/alu/divrem/mod.rs | 28 +- crates/core/machine/src/alu/lt/mod.rs | 51 +- crates/core/machine/src/alu/mul/mod.rs | 283 +++++----- crates/core/machine/src/alu/sr/mod.rs | 73 +-- .../machine/src/cpu/columns/instruction.rs | 6 +- crates/core/machine/src/cpu/columns/opcode.rs | 2 +- crates/core/machine/src/cpu/trace.rs | 213 ++++---- crates/core/machine/src/memory/local.rs | 76 +-- crates/core/machine/src/memory/program.rs | 61 ++- crates/core/machine/src/program/mod.rs | 58 ++- crates/core/machine/src/runtime/utils.rs | 8 +- .../precompiles/edwards/ed_decompress.rs | 2 +- crates/prover/src/lib.rs | 8 +- crates/prover/src/shapes.rs | 21 +- .../recursion/circuit/src/machine/deferred.rs | 2 +- .../compiler/src/circuit/compiler.rs | 5 +- .../core/src/chips/poseidon2_skinny/trace.rs | 4 + .../core/src/chips/poseidon2_wide/trace.rs | 4 + crates/recursion/core/src/machine.rs | 16 +- crates/recursion/core/src/runtime/memory.rs | 2 +- crates/recursion/core/src/runtime/mod.rs | 16 + 39 files changed, 924 insertions(+), 929 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22a73f10b5..748f845ec7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6215,6 +6215,7 @@ dependencies = [ "tracing-forest", "tracing-subscriber", "typenum", + "vec_map", "web-time", ] diff --git a/crates/core/executor/src/dependencies.rs b/crates/core/executor/src/dependencies.rs index 194d8d0eb2..6b0bbbe33c 100644 --- a/crates/core/executor/src/dependencies.rs +++ b/crates/core/executor/src/dependencies.rs @@ -1,5 +1,5 @@ use crate::{ - events::{create_alu_lookups, AluEvent, CpuEvent}, + events::AluEvent, utils::{get_msb, get_quotient_and_remainder, is_signed_operation}, Executor, Opcode, }; @@ -7,6 +7,7 @@ use crate::{ /// Emits the dependencies for division and remainder operations. #[allow(clippy::too_many_lines)] pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { + let shard = executor.shard(); let (quotient, remainder) = get_quotient_and_remainder(event.b, event.c, event.opcode); let c_msb = get_msb(event.c); let rem_msb = get_msb(remainder); @@ -19,27 +20,29 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { } if c_neg == 1 { + let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(AluEvent { lookup_id: event.sub_lookups[4], - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: 0, b: event.c, c: (event.c as i32).unsigned_abs(), - sub_lookups: create_alu_lookups(), + sub_lookups: ids, }); } if rem_neg == 1 { + let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(AluEvent { lookup_id: event.sub_lookups[5], - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: 0, b: remainder, c: (remainder as i32).unsigned_abs(), - sub_lookups: create_alu_lookups(), + sub_lookups: ids, }); } @@ -55,19 +58,19 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { let lower_multiplication = AluEvent { lookup_id: event.sub_lookups[0], - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::MUL, a: lower_word, c: event.c, b: quotient, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.mul_events.push(lower_multiplication); let upper_multiplication = AluEvent { lookup_id: event.sub_lookups[1], - shard: event.shard, + shard, clk: event.clk, opcode: { if is_signed_operation { @@ -79,31 +82,31 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { a: upper_word, c: event.c, b: quotient, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.mul_events.push(upper_multiplication); let lt_event = if is_signed_operation { AluEvent { lookup_id: event.sub_lookups[2], - shard: event.shard, + shard, opcode: Opcode::SLTU, a: 1, b: (remainder as i32).unsigned_abs(), c: u32::max(1, (event.c as i32).unsigned_abs()), clk: event.clk, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), } } else { AluEvent { lookup_id: event.sub_lookups[3], - shard: event.shard, + shard, opcode: Opcode::SLTU, a: 1, b: remainder, c: u32::max(1, event.c), clk: event.clk, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), } }; @@ -114,9 +117,12 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { /// Emit the dependencies for CPU events. #[allow(clippy::too_many_lines)] -pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { +pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { + let event = executor.record.cpu_events[index]; + let shard = executor.shard(); + let instruction = &executor.program.fetch(event.pc); if matches!( - event.instruction.opcode, + instruction.opcode, Opcode::LB | Opcode::LH | Opcode::LW @@ -130,58 +136,57 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { // Add event to ALU check to check that addr == b + c let add_event = AluEvent { lookup_id: event.memory_add_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: memory_addr, b: event.b, c: event.c, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); let addr_offset = (memory_addr % 4_u32) as u8; let mem_value = event.memory_record.unwrap().value(); - if matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) { - let (unsigned_mem_val, most_sig_mem_value_byte, sign_value) = - match event.instruction.opcode { - Opcode::LB => { - let most_sig_mem_value_byte = mem_value.to_le_bytes()[addr_offset as usize]; - let sign_value = 256; - (most_sig_mem_value_byte as u32, most_sig_mem_value_byte, sign_value) - } - Opcode::LH => { - let sign_value = 65536; - let unsigned_mem_val = match (addr_offset >> 1) % 2 { - 0 => mem_value & 0x0000FFFF, - 1 => (mem_value & 0xFFFF0000) >> 16, - _ => unreachable!(), - }; - let most_sig_mem_value_byte = unsigned_mem_val.to_le_bytes()[1]; - (unsigned_mem_val, most_sig_mem_value_byte, sign_value) - } - _ => unreachable!(), - }; + if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { + let (unsigned_mem_val, most_sig_mem_value_byte, sign_value) = match instruction.opcode { + Opcode::LB => { + let most_sig_mem_value_byte = mem_value.to_le_bytes()[addr_offset as usize]; + let sign_value = 256; + (most_sig_mem_value_byte as u32, most_sig_mem_value_byte, sign_value) + } + Opcode::LH => { + let sign_value = 65536; + let unsigned_mem_val = match (addr_offset >> 1) % 2 { + 0 => mem_value & 0x0000FFFF, + 1 => (mem_value & 0xFFFF0000) >> 16, + _ => unreachable!(), + }; + let most_sig_mem_value_byte = unsigned_mem_val.to_le_bytes()[1]; + (unsigned_mem_val, most_sig_mem_value_byte, sign_value) + } + _ => unreachable!(), + }; if most_sig_mem_value_byte >> 7 & 0x01 == 1 { let sub_event = AluEvent { lookup_id: event.memory_sub_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::SUB, a: event.a, b: unsigned_mem_val, c: sign_value, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(sub_event); } } } - if event.instruction.is_branch_instruction() { + if instruction.is_branch_instruction() { let a_eq_b = event.a == event.b; - let use_signed_comparison = matches!(event.instruction.opcode, Opcode::BLT | Opcode::BGE); + let use_signed_comparison = matches!(instruction.opcode, Opcode::BLT | Opcode::BGE); let a_lt_b = if use_signed_comparison { (event.a as i32) < (event.b as i32) } else { @@ -197,27 +202,27 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { // Add the ALU events for the comparisons let lt_comp_event = AluEvent { lookup_id: event.branch_lt_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: alu_op_code, a: a_lt_b as u32, b: event.a, c: event.b, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; let gt_comp_event = AluEvent { lookup_id: event.branch_gt_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: alu_op_code, a: a_gt_b as u32, b: event.b, c: event.a, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.lt_events.push(lt_comp_event); executor.record.lt_events.push(gt_comp_event); - let branching = match event.instruction.opcode { + let branching = match instruction.opcode { Opcode::BEQ => a_eq_b, Opcode::BNE => !a_eq_b, Opcode::BLT | Opcode::BLTU => a_lt_b, @@ -228,31 +233,31 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { let next_pc = event.pc.wrapping_add(event.c); let add_event = AluEvent { lookup_id: event.branch_add_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, c: event.c, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); } } - if event.instruction.is_jump_instruction() { - match event.instruction.opcode { + if instruction.is_jump_instruction() { + match instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); let add_event = AluEvent { lookup_id: event.jump_jal_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, c: event.b, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); } @@ -260,13 +265,13 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { let next_pc = event.b.wrapping_add(event.c); let add_event = AluEvent { lookup_id: event.jump_jalr_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.b, c: event.c, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); } @@ -274,16 +279,16 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { } } - if matches!(event.instruction.opcode, Opcode::AUIPC) { + if matches!(instruction.opcode, Opcode::AUIPC) { let add_event = AluEvent { lookup_id: event.auipc_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: event.a, b: event.pc, c: event.b, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); } diff --git a/crates/core/executor/src/disassembler/rrs.rs b/crates/core/executor/src/disassembler/rrs.rs index 711dbe4e4a..a105e10a81 100644 --- a/crates/core/executor/src/disassembler/rrs.rs +++ b/crates/core/executor/src/disassembler/rrs.rs @@ -9,52 +9,31 @@ impl Instruction { /// Create a new [`Instruction`] from an R-type instruction. #[must_use] pub const fn from_r_type(opcode: Opcode, dec_insn: &RType) -> Self { - Self::new( - opcode, - dec_insn.rd as u32, - dec_insn.rs1 as u32, - dec_insn.rs2 as u32, - false, - false, - ) + Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.rs2 as u32, false, false) } /// Create a new [`Instruction`] from an I-type instruction. #[must_use] pub const fn from_i_type(opcode: Opcode, dec_insn: &IType) -> Self { - Self::new(opcode, dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) + Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) } /// Create a new [`Instruction`] from an I-type instruction with a shamt. #[must_use] pub const fn from_i_type_shamt(opcode: Opcode, dec_insn: &ITypeShamt) -> Self { - Self::new(opcode, dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.shamt, false, true) + Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.shamt, false, true) } /// Create a new [`Instruction`] from an S-type instruction. #[must_use] pub const fn from_s_type(opcode: Opcode, dec_insn: &SType) -> Self { - Self::new( - opcode, - dec_insn.rs2 as u32, - dec_insn.rs1 as u32, - dec_insn.imm as u32, - false, - true, - ) + Self::new(opcode, dec_insn.rs2 as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) } /// Create a new [`Instruction`] from a B-type instruction. #[must_use] pub const fn from_b_type(opcode: Opcode, dec_insn: &BType) -> Self { - Self::new( - opcode, - dec_insn.rs1 as u32, - dec_insn.rs2 as u32, - dec_insn.imm as u32, - false, - true, - ) + Self::new(opcode, dec_insn.rs1 as u8, dec_insn.rs2 as u32, dec_insn.imm as u32, false, true) } /// Create a new [`Instruction`] that is not implemented. @@ -82,9 +61,9 @@ impl Instruction { #[must_use] pub fn r_type(&self) -> (Register, Register, Register) { ( - Register::from_u32(self.op_a), - Register::from_u32(self.op_b), - Register::from_u32(self.op_c), + Register::from_u8(self.op_a), + Register::from_u8(self.op_b as u8), + Register::from_u8(self.op_c as u8), ) } @@ -92,35 +71,35 @@ impl Instruction { #[inline] #[must_use] pub fn i_type(&self) -> (Register, Register, u32) { - (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) + (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) } /// Decode the [`Instruction`] in the S-type format. #[inline] #[must_use] pub fn s_type(&self) -> (Register, Register, u32) { - (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) + (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) } /// Decode the [`Instruction`] in the B-type format. #[inline] #[must_use] pub fn b_type(&self) -> (Register, Register, u32) { - (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) + (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) } /// Decode the [`Instruction`] in the J-type format. #[inline] #[must_use] pub fn j_type(&self) -> (Register, u32) { - (Register::from_u32(self.op_a), self.op_b) + (Register::from_u8(self.op_a), self.op_b) } /// Decode the [`Instruction`] in the U-type format. #[inline] #[must_use] pub fn u_type(&self) -> (Register, u32) { - (Register::from_u32(self.op_a), self.op_b) + (Register::from_u8(self.op_a), self.op_b) } } @@ -263,13 +242,13 @@ impl InstructionProcessor for InstructionTranspiler { } fn process_jal(&mut self, dec_insn: JType) -> Self::InstructionResult { - Instruction::new(Opcode::JAL, dec_insn.rd as u32, dec_insn.imm as u32, 0, true, true) + Instruction::new(Opcode::JAL, dec_insn.rd as u8, dec_insn.imm as u32, 0, true, true) } fn process_jalr(&mut self, dec_insn: IType) -> Self::InstructionResult { Instruction::new( Opcode::JALR, - dec_insn.rd as u32, + dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, @@ -282,14 +261,14 @@ impl InstructionProcessor for InstructionTranspiler { // // Notably, LUI instructions are converted to an SLL instruction with `imm_b` and `imm_c` // turned on. Additionally the `op_c` should be set to 12. - Instruction::new(Opcode::ADD, dec_insn.rd as u32, 0, dec_insn.imm as u32, true, true) + Instruction::new(Opcode::ADD, dec_insn.rd as u8, 0, dec_insn.imm as u32, true, true) } /// AUIPC instructions have the third operand set to imm << 12. fn process_auipc(&mut self, dec_insn: UType) -> Self::InstructionResult { Instruction::new( Opcode::AUIPC, - dec_insn.rd as u32, + dec_insn.rd as u8, dec_insn.imm as u32, dec_insn.imm as u32, true, @@ -300,7 +279,7 @@ impl InstructionProcessor for InstructionTranspiler { fn process_ecall(&mut self) -> Self::InstructionResult { Instruction::new( Opcode::ECALL, - Register::X5 as u32, + Register::X5 as u8, Register::X10 as u32, Register::X11 as u32, false, diff --git a/crates/core/executor/src/events/alu.rs b/crates/core/executor/src/events/alu.rs index bf79a65e4c..2d2b14fe03 100644 --- a/crates/core/executor/src/events/alu.rs +++ b/crates/core/executor/src/events/alu.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::Opcode; -use super::{create_alu_lookups, LookupId}; +use super::{create_random_lookup_ids, LookupId}; /// Arithmetic Logic Unit (ALU) Event. /// @@ -40,7 +40,7 @@ impl AluEvent { a, b, c, - sub_lookups: create_alu_lookups(), + sub_lookups: create_random_lookup_ids(), } } } diff --git a/crates/core/executor/src/events/byte.rs b/crates/core/executor/src/events/byte.rs index 4e5f254373..3db5c7647b 100644 --- a/crates/core/executor/src/events/byte.rs +++ b/crates/core/executor/src/events/byte.rs @@ -233,7 +233,7 @@ impl ByteOpcode { ByteOpcode::MSB, ByteOpcode::U16Range, ]; - assert_eq!(opcodes.len(), NUM_BYTE_OPS); + debug_assert_eq!(opcodes.len(), NUM_BYTE_OPS); opcodes } diff --git a/crates/core/executor/src/events/cpu.rs b/crates/core/executor/src/events/cpu.rs index b2d775cf12..f609e941c0 100644 --- a/crates/core/executor/src/events/cpu.rs +++ b/crates/core/executor/src/events/cpu.rs @@ -1,7 +1,5 @@ use serde::{Deserialize, Serialize}; -use crate::Instruction; - use super::{memory::MemoryRecordEnum, LookupId}; /// CPU Event. @@ -10,16 +8,12 @@ use super::{memory::MemoryRecordEnum, LookupId}; /// shard, opcode, operands, and other relevant information. #[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub struct CpuEvent { - /// The shard number. - pub shard: u32, /// The clock cycle. pub clk: u32, /// The program counter. pub pc: u32, /// The next program counter. pub next_pc: u32, - /// The instruction. - pub instruction: Instruction, /// The first operand. pub a: u32, /// The first operand memory record. @@ -32,8 +26,6 @@ pub struct CpuEvent { pub c: u32, /// The third operand memory record. pub c_record: Option, - /// The memory value. - pub memory: Option, /// The memory record. pub memory_record: Option, /// The exit code. diff --git a/crates/core/executor/src/events/memory.rs b/crates/core/executor/src/events/memory.rs index 4372f21267..655e0fc21d 100644 --- a/crates/core/executor/src/events/memory.rs +++ b/crates/core/executor/src/events/memory.rs @@ -150,7 +150,9 @@ impl MemoryReadRecord { prev_shard: u32, prev_timestamp: u32, ) -> Self { - assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp))); + debug_assert!( + shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)) + ); Self { value, shard, timestamp, prev_shard, prev_timestamp } } } @@ -166,7 +168,9 @@ impl MemoryWriteRecord { prev_shard: u32, prev_timestamp: u32, ) -> Self { - assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)),); + debug_assert!( + shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)), + ); Self { value, shard, timestamp, prev_value, prev_shard, prev_timestamp } } } diff --git a/crates/core/executor/src/events/utils.rs b/crates/core/executor/src/events/utils.rs index 681bc6cc78..d4b38df745 100644 --- a/crates/core/executor/src/events/utils.rs +++ b/crates/core/executor/src/events/utils.rs @@ -5,43 +5,16 @@ use std::{ iter::{Map, Peekable}, }; -use rand::{thread_rng, Rng}; - /// A unique identifier for lookups. -/// -/// We use 4 u32s instead of a u128 to make it compatible with C. #[derive(Deserialize, Serialize, Debug, Clone, Copy, Default, Eq, Hash, PartialEq)] -pub struct LookupId { - /// First part of the id. - pub a: u32, - /// Second part of the id. - pub b: u32, - /// Third part of the id. - pub c: u32, - /// Fourth part of the id. - pub d: u32, -} - -/// Creates a new ALU lookup id with ``LookupId`` -#[must_use] -pub fn create_alu_lookup_id() -> LookupId { - let mut rng = thread_rng(); - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() } -} +pub struct LookupId(pub u64); -/// Creates a new ALU lookup id with ``LookupId`` +/// Create a random lookup id. This is slower than `record.create_lookup_id()` but is useful for +/// testing. #[must_use] -pub fn create_alu_lookups() -> [LookupId; 6] { - let mut rng = thread_rng(); - [ - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - ] +pub(crate) fn create_random_lookup_ids() -> [LookupId; 6] { + std::array::from_fn(|_| LookupId(rand::random())) } /// Returns sorted and formatted rows of a table of counts (e.g. `opcode_counts`). diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index cfbc8cacd5..7244955a37 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -13,9 +13,8 @@ use crate::{ context::SP1Context, dependencies::{emit_cpu_dependencies, emit_divrem_dependencies}, events::{ - create_alu_lookup_id, create_alu_lookups, AluEvent, CpuEvent, LookupId, - MemoryAccessPosition, MemoryInitializeFinalizeEvent, MemoryLocalEvent, MemoryReadRecord, - MemoryRecord, MemoryWriteRecord, SyscallEvent, + AluEvent, CpuEvent, LookupId, MemoryAccessPosition, MemoryInitializeFinalizeEvent, + MemoryLocalEvent, MemoryReadRecord, MemoryRecord, MemoryWriteRecord, SyscallEvent, }, hook::{HookEnv, HookRegistry}, memory::{Entry, PagedMemory}, @@ -269,7 +268,7 @@ impl<'a> Executor<'a> { pub fn registers(&mut self) -> [u32; 32] { let mut registers = [0; 32]; for i in 0..32 { - let addr = Register::from_u32(i as u32) as u32; + let addr = Register::from_u8(i as u8) as u32; let record = self.state.memory.get(addr); // Only add the previous memory state to checkpoint map if we're in checkpoint mode, @@ -407,7 +406,7 @@ impl<'a> Executor<'a> { record.shard = shard; record.timestamp = timestamp; - if !self.unconstrained { + if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { let local_memory_access = if let Some(local_memory_access) = local_memory_access { local_memory_access } else { @@ -486,7 +485,7 @@ impl<'a> Executor<'a> { record.shard = shard; record.timestamp = timestamp; - if !self.unconstrained { + if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { let local_memory_access = if let Some(local_memory_access) = local_memory_access { local_memory_access } else { @@ -553,19 +552,19 @@ impl<'a> Executor<'a> { if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { match position { MemoryAccessPosition::A => { - assert!(self.memory_accesses.a.is_none()); + debug_assert!(self.memory_accesses.a.is_none()); self.memory_accesses.a = Some(record.into()); } MemoryAccessPosition::B => { - assert!(self.memory_accesses.b.is_none()); + debug_assert!(self.memory_accesses.b.is_none()); self.memory_accesses.b = Some(record.into()); } MemoryAccessPosition::C => { - assert!(self.memory_accesses.c.is_none()); + debug_assert!(self.memory_accesses.c.is_none()); self.memory_accesses.c = Some(record.into()); } MemoryAccessPosition::Memory => { - assert!(self.memory_accesses.memory.is_none()); + debug_assert!(self.memory_accesses.memory.is_none()); self.memory_accesses.memory = Some(record.into()); } } @@ -593,49 +592,50 @@ impl<'a> Executor<'a> { #[allow(clippy::too_many_arguments)] fn emit_cpu( &mut self, - shard: u32, clk: u32, pc: u32, next_pc: u32, - instruction: Instruction, a: u32, b: u32, c: u32, - memory_store_value: Option, record: MemoryAccessRecord, exit_code: u32, lookup_id: LookupId, syscall_lookup_id: LookupId, ) { - let cpu_event = CpuEvent { - shard, + let memory_add_lookup_id = self.record.create_lookup_id(); + let memory_sub_lookup_id = self.record.create_lookup_id(); + let branch_lt_lookup_id = self.record.create_lookup_id(); + let branch_gt_lookup_id = self.record.create_lookup_id(); + let branch_add_lookup_id = self.record.create_lookup_id(); + let jump_jal_lookup_id = self.record.create_lookup_id(); + let jump_jalr_lookup_id = self.record.create_lookup_id(); + let auipc_lookup_id = self.record.create_lookup_id(); + self.record.cpu_events.push(CpuEvent { clk, pc, next_pc, - instruction, a, a_record: record.a, b, b_record: record.b, c, c_record: record.c, - memory: memory_store_value, memory_record: record.memory, exit_code, alu_lookup_id: lookup_id, syscall_lookup_id, - memory_add_lookup_id: create_alu_lookup_id(), - memory_sub_lookup_id: create_alu_lookup_id(), - branch_lt_lookup_id: create_alu_lookup_id(), - branch_gt_lookup_id: create_alu_lookup_id(), - branch_add_lookup_id: create_alu_lookup_id(), - jump_jal_lookup_id: create_alu_lookup_id(), - jump_jalr_lookup_id: create_alu_lookup_id(), - auipc_lookup_id: create_alu_lookup_id(), - }; + memory_add_lookup_id, + memory_sub_lookup_id, + branch_lt_lookup_id, + branch_gt_lookup_id, + branch_add_lookup_id, + jump_jal_lookup_id, + jump_jalr_lookup_id, + auipc_lookup_id, + }); - self.record.cpu_events.push(cpu_event); - emit_cpu_dependencies(self, &cpu_event); + emit_cpu_dependencies(self, self.record.cpu_events.len() - 1); } /// Emit an ALU event. @@ -648,7 +648,7 @@ impl<'a> Executor<'a> { a, b, c, - sub_lookups: create_alu_lookups(), + sub_lookups: self.record.create_lookup_ids(), }; match opcode { Opcode::ADD => { @@ -696,7 +696,7 @@ impl<'a> Executor<'a> { arg1, arg2, lookup_id, - nonce: self.record.nonce_lookup[&lookup_id], + nonce: self.record.nonce_lookup[lookup_id.0 as usize], } } @@ -725,9 +725,9 @@ impl<'a> Executor<'a> { let (rd, b, c) = (rd, self.rr(rs1, MemoryAccessPosition::B), imm); (rd, b, c) } else { - assert!(instruction.imm_b && instruction.imm_c); + debug_assert!(instruction.imm_b && instruction.imm_c); let (rd, b, c) = - (Register::from_u32(instruction.op_a), instruction.op_b, instruction.op_c); + (Register::from_u8(instruction.op_a), instruction.op_b, instruction.op_c); (rd, b, c) } } @@ -780,8 +780,7 @@ impl<'a> Executor<'a> { /// Fetch the instruction at the current program counter. #[inline] fn fetch(&self) -> Instruction { - let idx = ((self.state.pc - self.program.pc_base) / 4) as usize; - self.program.instructions[idx] + *self.program.fetch(self.state.pc) } /// Execute the given instruction over the current state of the runtime. @@ -793,21 +792,18 @@ impl<'a> Executor<'a> { let mut next_pc = self.state.pc.wrapping_add(4); - let rd: Register; let (a, b, c): (u32, u32, u32); - let (addr, memory_read_value): (u32, u32); - let mut memory_store_value: Option = None; if self.executor_mode == ExecutorMode::Trace { self.memory_accesses = MemoryAccessRecord::default(); } let lookup_id = if self.executor_mode == ExecutorMode::Trace { - create_alu_lookup_id() + self.record.create_lookup_id() } else { LookupId::default() }; let syscall_lookup_id = if self.executor_mode == ExecutorMode::Trace { - create_alu_lookup_id() + self.record.create_lookup_id() } else { LookupId::default() }; @@ -842,182 +838,40 @@ impl<'a> Executor<'a> { match instruction.opcode { // Arithmetic instructions. - Opcode::ADD => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_add(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SUB => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_sub(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::XOR => { - (rd, b, c) = self.alu_rr(instruction); - a = b ^ c; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::OR => { - (rd, b, c) = self.alu_rr(instruction); - a = b | c; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::AND => { - (rd, b, c) = self.alu_rr(instruction); - a = b & c; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SLL => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_shl(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SRL => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_shr(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SRA => { - (rd, b, c) = self.alu_rr(instruction); - a = (b as i32).wrapping_shr(c) as u32; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SLT => { - (rd, b, c) = self.alu_rr(instruction); - a = if (b as i32) < (c as i32) { 1 } else { 0 }; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SLTU => { - (rd, b, c) = self.alu_rr(instruction); - a = if b < c { 1 } else { 0 }; - self.alu_rw(instruction, rd, a, b, c, lookup_id); + Opcode::ADD + | Opcode::SUB + | Opcode::XOR + | Opcode::OR + | Opcode::AND + | Opcode::SLL + | Opcode::SRL + | Opcode::SRA + | Opcode::SLT + | Opcode::SLTU + | Opcode::MUL + | Opcode::MULH + | Opcode::MULHU + | Opcode::MULHSU + | Opcode::DIV + | Opcode::DIVU + | Opcode::REM + | Opcode::REMU => { + (a, b, c) = self.execute_alu(instruction, lookup_id); } // Load instructions. - Opcode::LB => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - 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); - self.rw(rd, a); - } - Opcode::LH => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LH, addr)); - } - let value = match (addr >> 1) % 2 { - 0 => memory_read_value & 0x0000_FFFF, - 1 => (memory_read_value & 0xFFFF_0000) >> 16, - _ => unreachable!(), - }; - a = ((value as i16) as i32) as u32; - memory_store_value = Some(memory_read_value); - self.rw(rd, a); - } - Opcode::LW => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - if addr % 4 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LW, addr)); - } - a = memory_read_value; - memory_store_value = Some(memory_read_value); - self.rw(rd, a); - } - Opcode::LBU => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - let value = (memory_read_value).to_le_bytes()[(addr % 4) as usize]; - a = value as u32; - memory_store_value = Some(memory_read_value); - self.rw(rd, a); - } - Opcode::LHU => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LHU, addr)); - } - let value = match (addr >> 1) % 2 { - 0 => memory_read_value & 0x0000_FFFF, - 1 => (memory_read_value & 0xFFFF_0000) >> 16, - _ => unreachable!(), - }; - a = (value as u16) as u32; - memory_store_value = Some(memory_read_value); - self.rw(rd, a); + Opcode::LB | Opcode::LH | Opcode::LW | Opcode::LBU | Opcode::LHU => { + (a, b, c) = self.execute_load(instruction)?; } // Store instructions. - Opcode::SB => { - (a, b, c, addr, memory_read_value) = self.store_rr(instruction); - let value = match addr % 4 { - 0 => (a & 0x0000_00FF) + (memory_read_value & 0xFFFF_FF00), - 1 => ((a & 0x0000_00FF) << 8) + (memory_read_value & 0xFFFF_00FF), - 2 => ((a & 0x0000_00FF) << 16) + (memory_read_value & 0xFF00_FFFF), - 3 => ((a & 0x0000_00FF) << 24) + (memory_read_value & 0x00FF_FFFF), - _ => unreachable!(), - }; - memory_store_value = Some(value); - self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); - } - Opcode::SH => { - (a, b, c, addr, memory_read_value) = self.store_rr(instruction); - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::SH, addr)); - } - let value = match (addr >> 1) % 2 { - 0 => (a & 0x0000_FFFF) + (memory_read_value & 0xFFFF_0000), - 1 => ((a & 0x0000_FFFF) << 16) + (memory_read_value & 0x0000_FFFF), - _ => unreachable!(), - }; - memory_store_value = Some(value); - self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); - } - Opcode::SW => { - (a, b, c, addr, _) = self.store_rr(instruction); - if addr % 4 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::SW, addr)); - } - let value = a; - memory_store_value = Some(value); - self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); + Opcode::SB | Opcode::SH | Opcode::SW => { + (a, b, c) = self.execute_store(instruction)?; } - // B-type instructions. - Opcode::BEQ => { - (a, b, c) = self.branch_rr(instruction); - if a == b { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BNE => { - (a, b, c) = self.branch_rr(instruction); - if a != b { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BLT => { - (a, b, c) = self.branch_rr(instruction); - if (a as i32) < (b as i32) { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BGE => { - (a, b, c) = self.branch_rr(instruction); - if (a as i32) >= (b as i32) { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BLTU => { - (a, b, c) = self.branch_rr(instruction); - if a < b { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BGEU => { - (a, b, c) = self.branch_rr(instruction); - if a >= b { - next_pc = self.state.pc.wrapping_add(c); - } + // Branch instructions. + Opcode::BEQ | Opcode::BNE | Opcode::BLT | Opcode::BGE | Opcode::BLTU | Opcode::BGEU => { + (a, b, c, next_pc) = self.execute_branch(instruction, next_pc); } // Jump instructions. @@ -1080,7 +934,7 @@ impl<'a> Executor<'a> { _ => (self.opts.split_opts.deferred, 1), }; let nonce = (((*syscall_count as usize) % threshold) * multiplier) as u32; - self.record.nonce_lookup.insert(syscall_lookup_id, nonce); + self.record.nonce_lookup[syscall_lookup_id.0 as usize] = nonce; *syscall_count += 1; let syscall_impl = self.get_syscall(syscall).cloned(); @@ -1130,64 +984,6 @@ impl<'a> Executor<'a> { return Err(ExecutionError::Breakpoint()); } - // Multiply instructions. - Opcode::MUL => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_mul(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::MULH => { - (rd, b, c) = self.alu_rr(instruction); - a = (((b as i32) as i64).wrapping_mul((c as i32) as i64) >> 32) as u32; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::MULHU => { - (rd, b, c) = self.alu_rr(instruction); - a = ((b as u64).wrapping_mul(c as u64) >> 32) as u32; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::MULHSU => { - (rd, b, c) = self.alu_rr(instruction); - a = (((b as i32) as i64).wrapping_mul(c as i64) >> 32) as u32; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::DIV => { - (rd, b, c) = self.alu_rr(instruction); - if c == 0 { - a = u32::MAX; - } else { - a = (b as i32).wrapping_div(c as i32) as u32; - } - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::DIVU => { - (rd, b, c) = self.alu_rr(instruction); - if c == 0 { - a = u32::MAX; - } else { - a = b.wrapping_div(c); - } - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::REM => { - (rd, b, c) = self.alu_rr(instruction); - if c == 0 { - a = b; - } else { - a = (b as i32).wrapping_rem(c as i32) as u32; - } - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::REMU => { - (rd, b, c) = self.alu_rr(instruction); - if c == 0 { - a = b; - } else { - a = b.wrapping_rem(c); - } - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - // See https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#instruction-aliases Opcode::UNIMP => { return Err(ExecutionError::Unimplemented()); @@ -1203,15 +999,12 @@ impl<'a> Executor<'a> { // Emit the CPU event for this cycle. if self.executor_mode == ExecutorMode::Trace { self.emit_cpu( - self.shard(), clk, pc, next_pc, - *instruction, a, b, c, - memory_store_value, self.memory_accesses, exit_code, lookup_id, @@ -1221,6 +1014,153 @@ impl<'a> Executor<'a> { Ok(()) } + fn execute_alu(&mut self, instruction: &Instruction, lookup_id: LookupId) -> (u32, u32, u32) { + let (rd, b, c) = self.alu_rr(instruction); + let a = match instruction.opcode { + Opcode::ADD => b.wrapping_add(c), + Opcode::SUB => b.wrapping_sub(c), + Opcode::XOR => b ^ c, + Opcode::OR => b | c, + Opcode::AND => b & c, + Opcode::SLL => b.wrapping_shl(c), + Opcode::SRL => b.wrapping_shr(c), + Opcode::SRA => (b as i32).wrapping_shr(c) as u32, + Opcode::SLT => { + if (b as i32) < (c as i32) { + 1 + } else { + 0 + } + } + Opcode::SLTU => { + if b < c { + 1 + } else { + 0 + } + } + Opcode::MUL => b.wrapping_mul(c), + Opcode::MULH => (((b as i32) as i64).wrapping_mul((c as i32) as i64) >> 32) as u32, + Opcode::MULHU => ((b as u64).wrapping_mul(c as u64) >> 32) as u32, + Opcode::MULHSU => (((b as i32) as i64).wrapping_mul(c as i64) >> 32) as u32, + Opcode::DIV => { + if c == 0 { + u32::MAX + } else { + (b as i32).wrapping_div(c as i32) as u32 + } + } + Opcode::DIVU => { + if c == 0 { + u32::MAX + } else { + b.wrapping_div(c) + } + } + Opcode::REM => { + if c == 0 { + b + } else { + (b as i32).wrapping_rem(c as i32) as u32 + } + } + Opcode::REMU => { + if c == 0 { + b + } else { + b.wrapping_rem(c) + } + } + _ => unreachable!(), + }; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + (a, b, c) + } + + fn execute_load( + &mut self, + instruction: &Instruction, + ) -> Result<(u32, u32, u32), ExecutionError> { + let (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + let a = match instruction.opcode { + Opcode::LB => ((memory_read_value >> ((addr % 4) * 8)) & 0xFF) as i8 as i32 as u32, + Opcode::LH => { + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LH, addr)); + } + ((memory_read_value >> (((addr / 2) % 2) * 16)) & 0xFFFF) as i16 as i32 as u32 + } + Opcode::LW => { + if addr % 4 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LW, addr)); + } + memory_read_value + } + Opcode::LBU => (memory_read_value >> ((addr % 4) * 8)) & 0xFF, + Opcode::LHU => { + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LHU, addr)); + } + (memory_read_value >> (((addr / 2) % 2) * 16)) & 0xFFFF + } + _ => unreachable!(), + }; + self.rw(rd, a); + Ok((a, b, c)) + } + + fn execute_store( + &mut self, + instruction: &Instruction, + ) -> Result<(u32, u32, u32), ExecutionError> { + let (a, b, c, addr, memory_read_value) = self.store_rr(instruction); + let memory_store_value = match instruction.opcode { + Opcode::SB => { + let shift = (addr % 4) * 8; + ((a & 0xFF) << shift) | (memory_read_value & !(0xFF << shift)) + } + Opcode::SH => { + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::SH, addr)); + } + let shift = ((addr / 2) % 2) * 16; + ((a & 0xFFFF) << shift) | (memory_read_value & !(0xFFFF << shift)) + } + Opcode::SW => { + if addr % 4 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::SW, addr)); + } + a + } + _ => unreachable!(), + }; + self.mw_cpu(align(addr), memory_store_value, MemoryAccessPosition::Memory); + Ok((a, b, c)) + } + + fn execute_branch( + &mut self, + instruction: &Instruction, + mut next_pc: u32, + ) -> (u32, u32, u32, u32) { + let (a, b, c) = self.branch_rr(instruction); + let branch = match instruction.opcode { + Opcode::BEQ => a == b, + Opcode::BNE => a != b, + Opcode::BLT => (a as i32) < (b as i32), + Opcode::BGE => (a as i32) >= (b as i32), + Opcode::BLTU => a < b, + Opcode::BGEU => a >= b, + _ => { + unreachable!() + } + }; + if branch { + next_pc = self.state.pc.wrapping_add(c); + } + (a, b, c, next_pc) + } + /// Executes one cycle of the program, returning whether the program has finished. #[inline] #[allow(clippy::too_many_lines)] @@ -1397,6 +1337,7 @@ impl<'a> Executor<'a> { std::mem::replace(&mut self.record, ExecutionRecord::new(self.program.clone())); let public_values = removed_record.public_values; self.record.public_values = public_values; + self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; self.records.push(removed_record); } @@ -1471,6 +1412,8 @@ impl<'a> Executor<'a> { } fn initialize(&mut self) { + self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; + self.state.clk = 0; tracing::debug!("loading memory image"); @@ -1506,6 +1449,11 @@ impl<'a> Executor<'a> { /// Executes up to `self.shard_batch_size` cycles of the program, returning whether the program /// has finished. pub fn execute(&mut self) -> Result { + // Initialize the nonce lookup table if it's uninitialized. + if self.record.nonce_lookup.len() <= 2 { + self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; + } + // Get the program. let program = self.program.clone(); diff --git a/crates/core/executor/src/instruction.rs b/crates/core/executor/src/instruction.rs index bc1df27ba0..10dfa5476d 100644 --- a/crates/core/executor/src/instruction.rs +++ b/crates/core/executor/src/instruction.rs @@ -15,7 +15,7 @@ pub struct Instruction { /// The operation to execute. pub opcode: Opcode, /// The first operand. - pub op_a: u32, + pub op_a: u8, /// The second operand. pub op_b: u32, /// The third operand. @@ -31,7 +31,7 @@ impl Instruction { #[must_use] pub const fn new( opcode: Opcode, - op_a: u32, + op_a: u8, op_b: u32, op_c: u32, imm_b: bool, diff --git a/crates/core/executor/src/memory.rs b/crates/core/executor/src/memory.rs index 6e375753d4..a036bbf5ca 100644 --- a/crates/core/executor/src/memory.rs +++ b/crates/core/executor/src/memory.rs @@ -11,10 +11,10 @@ impl Default for Page { } } -const LOG_PAGE_LEN: usize = 15; +const LOG_PAGE_LEN: usize = 14; const PAGE_LEN: usize = 1 << LOG_PAGE_LEN; const MAX_PAGE_COUNT: usize = ((1 << 31) - (1 << 27)) / 4 / PAGE_LEN + 1; -const NO_PAGE: usize = usize::MAX; +const NO_PAGE: u16 = u16::MAX; const PAGE_MASK: usize = PAGE_LEN - 1; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -41,7 +41,7 @@ impl Default for NewPage { pub struct PagedMemory { /// The internal page table. pub page_table: Vec>, - pub index: Vec, + pub index: Vec, } impl PagedMemory { @@ -50,8 +50,7 @@ impl PagedMemory { /// The number of registers in the virtual machine. const NUM_REGISTERS: usize = 32; /// The offset subtracted from the main address space to make it contiguous. - const ADDR_COMPRESS_OFFSET: usize = - Self::NUM_REGISTERS - (Self::NUM_REGISTERS >> Self::NUM_IGNORED_LOWER_BITS); + const ADDR_COMPRESS_OFFSET: usize = Self::NUM_REGISTERS; /// Create a `PagedMemory` with capacity `MAX_PAGE_COUNT`. pub fn new_preallocated() -> Self { @@ -65,7 +64,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index].0[lower].as_ref() + self.page_table[index as usize].0[lower].as_ref() } } @@ -76,7 +75,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index].0[lower].as_mut() + self.page_table[index as usize].0[lower].as_mut() } } @@ -85,11 +84,11 @@ impl PagedMemory { let (upper, lower) = Self::indices(addr); let mut index = self.index[upper]; if index == NO_PAGE { - index = self.page_table.len(); + index = self.page_table.len() as u16; self.index[upper] = index; self.page_table.push(NewPage::new()); } - self.page_table[index].0[lower].replace(value) + self.page_table[index as usize].0[lower].replace(value) } /// Remove the value at the given address if it exists, returning it. @@ -99,7 +98,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index].0[lower].take() + self.page_table[index as usize].0[lower].take() } } @@ -109,11 +108,11 @@ impl PagedMemory { let index = self.index[upper]; if index == NO_PAGE { let index = self.page_table.len(); - self.index[upper] = index; + self.index[upper] = index as u16; self.page_table.push(NewPage::new()); Entry::Vacant(VacantEntry { entry: &mut self.page_table[index].0[lower] }) } else { - let option = &mut self.page_table[index].0[lower]; + let option = &mut self.page_table[index as usize].0[lower]; match option { Some(_) => Entry::Occupied(OccupiedEntry { entry: option }), None => Entry::Vacant(VacantEntry { entry: option }), @@ -125,7 +124,7 @@ impl PagedMemory { pub fn keys(&self) -> impl Iterator + '_ { self.index.iter().enumerate().filter(|(_, &i)| i != NO_PAGE).flat_map(|(i, index)| { let upper = i << LOG_PAGE_LEN; - self.page_table[*index] + self.page_table[*index as usize] .0 .iter() .enumerate() @@ -275,7 +274,7 @@ impl IntoIterator for PagedMemory { move |(i, index)| { let upper = i << LOG_PAGE_LEN; let replacement = NewPage::new(); - std::mem::replace(&mut self.page_table[index], replacement) + std::mem::replace(&mut self.page_table[index as usize], replacement) .0 .into_iter() .enumerate() diff --git a/crates/core/executor/src/opcode.rs b/crates/core/executor/src/opcode.rs index 6d0589ca91..818b5b1f2b 100644 --- a/crates/core/executor/src/opcode.rs +++ b/crates/core/executor/src/opcode.rs @@ -100,7 +100,7 @@ pub enum Opcode { /// rd ← rs1 % rs2 (unsigned), pc ← pc + 4 REMU = 37, /// Unimplemented instruction. - UNIMP = 39, + UNIMP = 38, } /// Byte Opcode. diff --git a/crates/core/executor/src/program.rs b/crates/core/executor/src/program.rs index 29743a4c8f..09bb70cac4 100644 --- a/crates/core/executor/src/program.rs +++ b/crates/core/executor/src/program.rs @@ -89,6 +89,13 @@ impl Program { }) .copied() } + + #[must_use] + /// Fetch the instruction at the given program counter. + pub fn fetch(&self, pc: u32) -> &Instruction { + let idx = ((pc - self.pc_base) / 4) as usize; + &self.instructions[idx] + } } impl MachineProgram for Program { diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index b6c23c45f8..f9e89acb4c 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -23,7 +23,7 @@ use crate::{ /// A record of the execution of a program. /// /// The trace of the execution is represented as a list of "events" that occur every cycle. -#[derive(Default, Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct ExecutionRecord { /// The program. pub program: Arc, @@ -60,16 +60,63 @@ pub struct ExecutionRecord { /// The public values. pub public_values: PublicValues, /// The nonce lookup. - pub nonce_lookup: HashMap, + pub nonce_lookup: Vec, + /// The next nonce to use for a new lookup. + pub next_nonce: u64, /// The shape of the proof. pub shape: Option, } +impl Default for ExecutionRecord { + fn default() -> Self { + let mut res = Self { + program: Arc::default(), + cpu_events: Vec::default(), + add_events: Vec::default(), + mul_events: Vec::default(), + sub_events: Vec::default(), + bitwise_events: Vec::default(), + shift_left_events: Vec::default(), + shift_right_events: Vec::default(), + divrem_events: Vec::default(), + lt_events: Vec::default(), + byte_lookups: HashMap::default(), + precompile_events: PrecompileEvents::default(), + global_memory_initialize_events: Vec::default(), + global_memory_finalize_events: Vec::default(), + cpu_local_memory_access: Vec::default(), + syscall_events: Vec::default(), + public_values: PublicValues::default(), + nonce_lookup: Vec::default(), + next_nonce: 0, + shape: None, + }; + res.nonce_lookup.insert(0, 0); + res + } +} + impl ExecutionRecord { /// Create a new [`ExecutionRecord`]. #[must_use] pub fn new(program: Arc) -> Self { - Self { program, ..Default::default() } + let mut res = Self { program, ..Default::default() }; + res.nonce_lookup.insert(0, 0); + res + } + + /// Create a lookup id for an event. + pub fn create_lookup_id(&mut self) -> LookupId { + // let id = self.nonce_lookup.len() as u64; + let id = self.next_nonce; + self.next_nonce += 1; + // self.nonce_lookup.insert(id as usize, 0); + LookupId(id) + } + + /// Create 6 lookup ids for an ALU event. + pub fn create_lookup_ids(&mut self) -> [LookupId; 6] { + std::array::from_fn(|_| self.create_lookup_id()) } /// Add a mul event to the execution record. @@ -299,7 +346,7 @@ impl MachineRecord for ExecutionRecord { ); stats.insert("local_memory_access_events".to_string(), self.cpu_local_memory_access.len()); if !self.cpu_events.is_empty() { - let shard = self.cpu_events[0].shard; + let shard = self.public_values.shard; stats.insert( "byte_lookups".to_string(), self.byte_lookups.get(&shard).map_or(0, hashbrown::HashMap::len), @@ -337,35 +384,35 @@ impl MachineRecord for ExecutionRecord { fn register_nonces(&mut self, _opts: &Self::Config) { self.add_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.sub_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, (self.add_events.len() + i) as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = (self.add_events.len() + i) as u32; }); self.mul_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.bitwise_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.shift_left_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.shift_right_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.divrem_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.lt_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); } diff --git a/crates/core/executor/src/register.rs b/crates/core/executor/src/register.rs index 176ef1c951..c24b75decc 100644 --- a/crates/core/executor/src/register.rs +++ b/crates/core/executor/src/register.rs @@ -70,14 +70,14 @@ pub enum Register { } impl Register { - /// Create a new register from a u32. + /// Create a new register from a u8. /// /// # Panics /// /// This function will panic if the register is invalid. #[inline] #[must_use] - pub fn from_u32(value: u32) -> Self { + pub fn from_u8(value: u8) -> Self { match value { 0 => Register::X0, 1 => Register::X1, diff --git a/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs b/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs index 36f1b56542..1d4a2a769e 100644 --- a/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs +++ b/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs @@ -22,11 +22,11 @@ impl Syscall for Sha256ExtendSyscall { assert!(arg2 == 0, "arg2 must be 0"); let w_ptr_init = w_ptr; - let mut w_i_minus_15_reads = Vec::new(); - let mut w_i_minus_2_reads = Vec::new(); - let mut w_i_minus_16_reads = Vec::new(); - let mut w_i_minus_7_reads = Vec::new(); - let mut w_i_writes = Vec::new(); + let mut w_i_minus_15_reads = Vec::with_capacity(48); + let mut w_i_minus_2_reads = Vec::with_capacity(48); + let mut w_i_minus_16_reads = Vec::with_capacity(48); + let mut w_i_minus_7_reads = Vec::with_capacity(48); + let mut w_i_writes = Vec::with_capacity(48); for i in 16..64 { // Read w[i-15]. let (record, w_i_minus_15) = rt.mr(w_ptr + (i - 15) * 4); diff --git a/crates/core/machine/Cargo.toml b/crates/core/machine/Cargo.toml index 7e2bd5a50a..3b0b0f34f9 100644 --- a/crates/core/machine/Cargo.toml +++ b/crates/core/machine/Cargo.toml @@ -54,6 +54,7 @@ static_assertions = "1.1.0" sp1-stark = { workspace = true } sp1-core-executor = { workspace = true } sp1-curves = { workspace = true } +vec_map = "0.8.2" [dev-dependencies] tiny-keccak = { version = "2.0.2", features = ["keccak"] } diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index bf6dabef42..d276820755 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ events::{AluEvent, ByteLookupEvent, ByteRecord}, ExecutionRecord, Opcode, Program, @@ -19,7 +19,10 @@ use sp1_stark::{ Word, }; -use crate::{operations::AddOperation, utils::pad_rows_fixed}; +use crate::{ + operations::AddOperation, + utils::{next_power_of_two, zeroed_f_vec}, +}; /// The number of main trace columns for `AddSubChip`. pub const NUM_ADD_SUB_COLS: usize = size_of::>(); @@ -79,46 +82,29 @@ impl MachineAir for AddSubChip { std::cmp::max((input.add_events.len() + input.sub_events.len()) / num_cpus::get(), 1); let merged_events = input.add_events.iter().chain(input.sub_events.iter()).collect::>(); - - let row_batches = merged_events - .par_chunks(chunk_size) - .map(|events| { - let rows = events - .iter() - .map(|event| { - let mut row = [F::zero(); NUM_ADD_SUB_COLS]; - let cols: &mut AddSubCols = row.as_mut_slice().borrow_mut(); - let mut blu = Vec::new(); - self.event_to_row(event, cols, &mut blu); - row - }) - .collect::>(); - rows - }) - .collect::>(); - - let mut rows: Vec<[F; NUM_ADD_SUB_COLS]> = vec![]; - for row_batch in row_batches { - rows.extend(row_batch); - } - - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_ADD_SUB_COLS], - input.fixed_log2_rows::(self), + let nb_rows = merged_events.len(); + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_ADD_SUB_COLS); + + values.chunks_mut(chunk_size * NUM_ADD_SUB_COLS).enumerate().par_bridge().for_each( + |(i, rows)| { + rows.chunks_mut(NUM_ADD_SUB_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + let cols: &mut AddSubCols = row.borrow_mut(); + + if idx < merged_events.len() { + let mut byte_lookup_events = Vec::new(); + let event = &merged_events[idx]; + self.event_to_row(event, cols, &mut byte_lookup_events); + } + cols.nonce = F::from_canonical_usize(idx); + }); + }, ); - // Convert the trace to a row major matrix. - let mut trace = - RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_ADD_SUB_COLS); - - // Write the nonces to the trace. - for i in 0..trace.height() { - let cols: &mut AddSubCols = - trace.values[i * NUM_ADD_SUB_COLS..(i + 1) * NUM_ADD_SUB_COLS].borrow_mut(); - cols.nonce = F::from_canonical_usize(i); - } - trace + // Convert the trace to a row major matrix. + RowMajorMatrix::new(values, NUM_ADD_SUB_COLS) } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index 9170b87b5f..1d4d539fc4 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -279,11 +279,19 @@ impl MachineAir for DivRemChip { // Set the `alu_event` flags. cols.abs_c_alu_event = cols.c_neg * cols.is_real; cols.abs_c_alu_event_nonce = F::from_canonical_u32( - input.nonce_lookup.get(&event.sub_lookups[4]).copied().unwrap_or_default(), + input + .nonce_lookup + .get(event.sub_lookups[4].0 as usize) + .copied() + .unwrap_or_default(), ); cols.abs_rem_alu_event = cols.rem_neg * cols.is_real; cols.abs_rem_alu_event_nonce = F::from_canonical_u32( - input.nonce_lookup.get(&event.sub_lookups[5]).copied().unwrap_or_default(), + input + .nonce_lookup + .get(event.sub_lookups[5].0 as usize) + .copied() + .unwrap_or_default(), ); // Insert the MSB lookup events. @@ -344,16 +352,24 @@ impl MachineAir for DivRemChip { // Insert the necessary multiplication & LT events. { cols.lower_nonce = F::from_canonical_u32( - input.nonce_lookup.get(&event.sub_lookups[0]).copied().unwrap_or_default(), + input + .nonce_lookup + .get(event.sub_lookups[0].0 as usize) + .copied() + .unwrap_or_default(), ); cols.upper_nonce = F::from_canonical_u32( - input.nonce_lookup.get(&event.sub_lookups[1]).copied().unwrap_or_default(), + input + .nonce_lookup + .get(event.sub_lookups[1].0 as usize) + .copied() + .unwrap_or_default(), ); if is_signed_operation(event.opcode) { cols.abs_nonce = F::from_canonical_u32( input .nonce_lookup - .get(&event.sub_lookups[2]) + .get(event.sub_lookups[2].0 as usize) .copied() .unwrap_or_default(), ); @@ -361,7 +377,7 @@ impl MachineAir for DivRemChip { cols.abs_nonce = F::from_canonical_u32( input .nonce_lookup - .get(&event.sub_lookups[3]) + .get(event.sub_lookups[3].0 as usize) .copied() .unwrap_or_default(), ); diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index 211cf5d912..876fdaaf8f 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -19,7 +19,7 @@ use sp1_stark::{ Word, }; -use crate::utils::pad_rows_fixed; +use crate::utils::{next_power_of_two, zeroed_f_vec}; /// The number of main trace columns for `LtChip`. pub const NUM_LT_COLS: usize = size_of::>(); @@ -107,38 +107,31 @@ impl MachineAir for LtChip { _: &mut ExecutionRecord, ) -> RowMajorMatrix { // Generate the trace rows for each event. - let mut rows = input - .lt_events - .par_iter() - .map(|event| { - let mut row = [F::zero(); NUM_LT_COLS]; - let mut new_byte_lookup_events: Vec = Vec::new(); - let cols: &mut LtCols = row.as_mut_slice().borrow_mut(); - self.event_to_row(event, cols, &mut new_byte_lookup_events); - - row - }) - .collect::>(); - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_LT_COLS], - input.fixed_log2_rows::(self), + let nb_rows = input.lt_events.len(); + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_LT_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values.chunks_mut(chunk_size * NUM_LT_COLS).enumerate().par_bridge().for_each( + |(i, rows)| { + rows.chunks_mut(NUM_LT_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + let cols: &mut LtCols = row.borrow_mut(); + + if idx < nb_rows { + let mut byte_lookup_events = Vec::new(); + let event = &input.lt_events[idx]; + self.event_to_row(event, cols, &mut byte_lookup_events); + } + cols.nonce = F::from_canonical_usize(idx); + }); + }, ); // Convert the trace to a row major matrix. - let mut trace = - RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_LT_COLS); - - // Write the nonces to the trace. - for i in 0..trace.height() { - let cols: &mut LtCols = - trace.values[i * NUM_LT_COLS..(i + 1) * NUM_LT_COLS].borrow_mut(); - cols.nonce = F::from_canonical_usize(i); - } - trace + RowMajorMatrix::new(values, NUM_LT_COLS) } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index 0453cb5f87..6a1ce272fe 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -35,19 +35,24 @@ use core::{ mem::size_of, }; +use hashbrown::HashMap; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{ByteLookupEvent, ByteRecord}, + events::{AluEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; use sp1_primitives::consts::WORD_SIZE; -use sp1_stark::{air::MachineAir, MachineRecord, Word}; +use sp1_stark::{air::MachineAir, Word}; -use crate::{air::SP1CoreAirBuilder, alu::mul::utils::get_msb, utils::pad_rows_fixed}; +use crate::{ + air::SP1CoreAirBuilder, + alu::mul::utils::get_msb, + utils::{next_power_of_two, zeroed_f_vec}, +}; /// The number of main trace columns for `MulChip`. pub const NUM_MUL_COLS: usize = size_of::>(); @@ -131,148 +136,54 @@ impl MachineAir for MulChip { fn generate_trace( &self, input: &ExecutionRecord, - output: &mut ExecutionRecord, + _: &mut ExecutionRecord, ) -> RowMajorMatrix { - let mul_events = input.mul_events.clone(); - // Compute the chunk size based on the number of events and the number of CPUs. - let chunk_size = std::cmp::max(mul_events.len() / num_cpus::get(), 1); + // Generate the trace rows for each event. + let nb_rows = input.mul_events.len(); + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_MUL_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values.chunks_mut(chunk_size * NUM_MUL_COLS).enumerate().par_bridge().for_each( + |(i, rows)| { + rows.chunks_mut(NUM_MUL_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + let cols: &mut MulCols = row.borrow_mut(); + + if idx < nb_rows { + let mut byte_lookup_events = Vec::new(); + let event = &input.mul_events[idx]; + self.event_to_row(event, cols, &mut byte_lookup_events); + } + cols.nonce = F::from_canonical_usize(idx); + }); + }, + ); - // Generate the trace rows & corresponding records for each chunk of events in parallel. - let rows_and_records = mul_events + // Convert the trace to a row major matrix. + + RowMajorMatrix::new(values, NUM_MUL_COLS) + } + + fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { + let chunk_size = std::cmp::max(input.mul_events.len() / num_cpus::get(), 1); + + let blu_batches = input + .mul_events .par_chunks(chunk_size) .map(|events| { - let mut record = ExecutionRecord::default(); - let rows = events - .iter() - .map(|event| { - // Ensure that the opcode is MUL, MULHU, MULH, or MULHSU. - assert!( - event.opcode == Opcode::MUL - || event.opcode == Opcode::MULHU - || event.opcode == Opcode::MULH - || event.opcode == Opcode::MULHSU - ); - let mut row = [F::zero(); NUM_MUL_COLS]; - let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); - - let a_word = event.a.to_le_bytes(); - let b_word = event.b.to_le_bytes(); - let c_word = event.c.to_le_bytes(); - - let mut b = b_word.to_vec(); - let mut c = c_word.to_vec(); - - // Handle b and c's signs. - { - let b_msb = get_msb(b_word); - cols.b_msb = F::from_canonical_u8(b_msb); - let c_msb = get_msb(c_word); - cols.c_msb = F::from_canonical_u8(c_msb); - - // If b is signed and it is negative, sign extend b. - if (event.opcode == Opcode::MULH || event.opcode == Opcode::MULHSU) - && b_msb == 1 - { - cols.b_sign_extend = F::one(); - b.resize(PRODUCT_SIZE, BYTE_MASK); - } - - // If c is signed and it is negative, sign extend c. - if event.opcode == Opcode::MULH && c_msb == 1 { - cols.c_sign_extend = F::one(); - c.resize(PRODUCT_SIZE, BYTE_MASK); - } - - // Insert the MSB lookup events. - { - let words = [b_word, c_word]; - let mut blu_events: Vec = vec![]; - for word in words.iter() { - let most_significant_byte = word[WORD_SIZE - 1]; - blu_events.push(ByteLookupEvent { - shard: event.shard, - opcode: ByteOpcode::MSB, - a1: get_msb(*word) as u16, - a2: 0, - b: most_significant_byte, - c: 0, - }); - } - record.add_byte_lookup_events(blu_events); - } - } - - let mut product = [0u32; PRODUCT_SIZE]; - for i in 0..b.len() { - for j in 0..c.len() { - if i + j < PRODUCT_SIZE { - product[i + j] += (b[i] as u32) * (c[j] as u32); - } - } - } - - // Calculate the correct product using the `product` array. We store the - // correct carry value for verification. - let base = (1 << BYTE_SIZE) as u32; - let mut carry = [0u32; PRODUCT_SIZE]; - for i in 0..PRODUCT_SIZE { - carry[i] = product[i] / base; - product[i] %= base; - if i + 1 < PRODUCT_SIZE { - product[i + 1] += carry[i]; - } - cols.carry[i] = F::from_canonical_u32(carry[i]); - } - - cols.product = product.map(F::from_canonical_u32); - cols.a = Word(a_word.map(F::from_canonical_u8)); - cols.b = Word(b_word.map(F::from_canonical_u8)); - cols.c = Word(c_word.map(F::from_canonical_u8)); - cols.is_real = F::one(); - cols.is_mul = F::from_bool(event.opcode == Opcode::MUL); - cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); - cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); - cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); - cols.shard = F::from_canonical_u32(event.shard); - - // Range check. - { - record.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); - record.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); - } - row - }) - .collect::>(); - (rows, record) + let mut blu: HashMap> = HashMap::new(); + events.iter().for_each(|event| { + let mut row = [F::zero(); NUM_MUL_COLS]; + let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); + self.event_to_row(event, cols, &mut blu); + }); + blu }) .collect::>(); - // Generate the trace rows for each event. - let mut rows: Vec<[F; NUM_MUL_COLS]> = vec![]; - for mut row_and_record in rows_and_records { - rows.extend(row_and_record.0); - output.append(&mut row_and_record.1); - } - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_MUL_COLS], - input.fixed_log2_rows::(self), - ); - - // Convert the trace to a row major matrix. - let mut trace = - RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_MUL_COLS); - - // Write the nonces to the trace. - for i in 0..trace.height() { - let cols: &mut MulCols = - trace.values[i * NUM_MUL_COLS..(i + 1) * NUM_MUL_COLS].borrow_mut(); - cols.nonce = F::from_canonical_usize(i); - } - - trace + output.add_sharded_byte_lookup_events(blu_batches.iter().collect::>()); } fn included(&self, shard: &Self::Record) -> bool { @@ -284,6 +195,100 @@ impl MachineAir for MulChip { } } +impl MulChip { + /// Create a row from an event. + fn event_to_row( + &self, + event: &AluEvent, + cols: &mut MulCols, + blu: &mut impl ByteRecord, + ) { + let a_word = event.a.to_le_bytes(); + let b_word = event.b.to_le_bytes(); + let c_word = event.c.to_le_bytes(); + + let mut b = b_word.to_vec(); + let mut c = c_word.to_vec(); + + // Handle b and c's signs. + { + let b_msb = get_msb(b_word); + cols.b_msb = F::from_canonical_u8(b_msb); + let c_msb = get_msb(c_word); + cols.c_msb = F::from_canonical_u8(c_msb); + + // If b is signed and it is negative, sign extend b. + if (event.opcode == Opcode::MULH || event.opcode == Opcode::MULHSU) && b_msb == 1 { + cols.b_sign_extend = F::one(); + b.resize(PRODUCT_SIZE, BYTE_MASK); + } + + // If c is signed and it is negative, sign extend c. + if event.opcode == Opcode::MULH && c_msb == 1 { + cols.c_sign_extend = F::one(); + c.resize(PRODUCT_SIZE, BYTE_MASK); + } + + // Insert the MSB lookup events. + { + let words = [b_word, c_word]; + let mut blu_events: Vec = vec![]; + for word in words.iter() { + let most_significant_byte = word[WORD_SIZE - 1]; + blu_events.push(ByteLookupEvent { + shard: event.shard, + opcode: ByteOpcode::MSB, + a1: get_msb(*word) as u16, + a2: 0, + b: most_significant_byte, + c: 0, + }); + } + blu.add_byte_lookup_events(blu_events); + } + } + + let mut product = [0u32; PRODUCT_SIZE]; + for i in 0..b.len() { + for j in 0..c.len() { + if i + j < PRODUCT_SIZE { + product[i + j] += (b[i] as u32) * (c[j] as u32); + } + } + } + + // Calculate the correct product using the `product` array. We store the + // correct carry value for verification. + let base = (1 << BYTE_SIZE) as u32; + let mut carry = [0u32; PRODUCT_SIZE]; + for i in 0..PRODUCT_SIZE { + carry[i] = product[i] / base; + product[i] %= base; + if i + 1 < PRODUCT_SIZE { + product[i + 1] += carry[i]; + } + cols.carry[i] = F::from_canonical_u32(carry[i]); + } + + cols.product = product.map(F::from_canonical_u32); + cols.a = Word(a_word.map(F::from_canonical_u8)); + cols.b = Word(b_word.map(F::from_canonical_u8)); + cols.c = Word(c_word.map(F::from_canonical_u8)); + cols.is_real = F::one(); + cols.is_mul = F::from_bool(event.opcode == Opcode::MUL); + cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); + cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); + cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); + cols.shard = F::from_canonical_u32(event.shard); + + // Range check. + { + blu.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); + blu.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); + } + } +} + impl BaseAir for MulChip { fn width(&self) -> usize { NUM_MUL_COLS diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index 9c19b4491c..b26c949945 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -52,7 +52,7 @@ use itertools::Itertools; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ events::{AluEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, @@ -65,7 +65,7 @@ use crate::{ air::SP1CoreAirBuilder, alu::sr::utils::{nb_bits_to_shift, nb_bytes_to_shift}, bytes::utils::shr_carry, - utils::pad_rows_fixed, + utils::{next_power_of_two, zeroed_f_vec}, }; /// The number of main trace columns for `ShiftRightChip`. @@ -149,54 +149,33 @@ impl MachineAir for ShiftRightChip { _: &mut ExecutionRecord, ) -> RowMajorMatrix { // Generate the trace rows for each event. - let mut rows: Vec<[F; NUM_SHIFT_RIGHT_COLS]> = Vec::new(); - let sr_events = input.shift_right_events.clone(); - for event in sr_events.iter() { - assert!(event.opcode == Opcode::SRL || event.opcode == Opcode::SRA); - let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; - let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); - let mut blu = Vec::new(); - self.event_to_row(event, cols, &mut blu); - rows.push(row); - } - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_SHIFT_RIGHT_COLS], - input.fixed_log2_rows::(self), + let nb_rows = input.shift_right_events.len(); + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_SHIFT_RIGHT_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values.chunks_mut(chunk_size * NUM_SHIFT_RIGHT_COLS).enumerate().par_bridge().for_each( + |(i, rows)| { + rows.chunks_mut(NUM_SHIFT_RIGHT_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + let cols: &mut ShiftRightCols = row.borrow_mut(); + + if idx < nb_rows { + let mut byte_lookup_events = Vec::new(); + let event = &input.shift_right_events[idx]; + self.event_to_row(event, cols, &mut byte_lookup_events); + } else { + cols.shift_by_n_bits[0] = F::one(); + cols.shift_by_n_bytes[0] = F::one(); + } + cols.nonce = F::from_canonical_usize(idx); + }); + }, ); // Convert the trace to a row major matrix. - let mut trace = RowMajorMatrix::new( - rows.into_iter().flatten().collect::>(), - NUM_SHIFT_RIGHT_COLS, - ); - - // Create the template for the padded rows. These are fake rows that don't fail on some - // sanity checks. - let padded_row_template = { - let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; - let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); - // Shift 0 by 0 bits and 0 bytes. - // cols.is_srl = F::one(); - cols.shift_by_n_bits[0] = F::one(); - cols.shift_by_n_bytes[0] = F::one(); - row - }; - debug_assert!(padded_row_template.len() == NUM_SHIFT_RIGHT_COLS); - for i in input.shift_right_events.len() * NUM_SHIFT_RIGHT_COLS..trace.values.len() { - trace.values[i] = padded_row_template[i % NUM_SHIFT_RIGHT_COLS]; - } - - // Write the nonces to the trace. - for i in 0..trace.height() { - let cols: &mut ShiftRightCols = - trace.values[i * NUM_SHIFT_RIGHT_COLS..(i + 1) * NUM_SHIFT_RIGHT_COLS].borrow_mut(); - cols.nonce = F::from_canonical_usize(i); - } - - trace + RowMajorMatrix::new(values, NUM_SHIFT_RIGHT_COLS) } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/cpu/columns/instruction.rs b/crates/core/machine/src/cpu/columns/instruction.rs index a16de4fb08..27dd1f6a91 100644 --- a/crates/core/machine/src/cpu/columns/instruction.rs +++ b/crates/core/machine/src/cpu/columns/instruction.rs @@ -27,13 +27,13 @@ pub struct InstructionCols { } impl InstructionCols { - pub fn populate(&mut self, instruction: Instruction) { + pub fn populate(&mut self, instruction: &Instruction) { self.opcode = instruction.opcode.as_field::(); - self.op_a = instruction.op_a.into(); + self.op_a = (instruction.op_a as u32).into(); self.op_b = instruction.op_b.into(); self.op_c = instruction.op_c.into(); - self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u32); + self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u8); } } diff --git a/crates/core/machine/src/cpu/columns/opcode.rs b/crates/core/machine/src/cpu/columns/opcode.rs index 9b4344d036..4de8f11ba7 100644 --- a/crates/core/machine/src/cpu/columns/opcode.rs +++ b/crates/core/machine/src/cpu/columns/opcode.rs @@ -63,7 +63,7 @@ pub struct OpcodeSelectorCols { } impl OpcodeSelectorCols { - pub fn populate(&mut self, instruction: Instruction) { + pub fn populate(&mut self, instruction: &Instruction) { self.imm_b = F::from_bool(instruction.imm_b); self.imm_c = F::from_bool(instruction.imm_c); diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index 01b1489127..c9831c66c0 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -1,10 +1,10 @@ use hashbrown::HashMap; use itertools::Itertools; use sp1_core_executor::{ - events::{ByteLookupEvent, ByteRecord, CpuEvent, LookupId, MemoryRecordEnum}, + events::{ByteLookupEvent, ByteRecord, CpuEvent, MemoryRecordEnum}, syscalls::SyscallCode, ByteOpcode::{self, U16Range}, - CoreShape, ExecutionRecord, Opcode, Program, + ExecutionRecord, Instruction, Opcode, Program, Register::X0, }; use sp1_primitives::consts::WORD_SIZE; @@ -13,15 +13,10 @@ use std::{array, borrow::BorrowMut}; use p3_field::{PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; -use p3_maybe_rayon::prelude::{ - IntoParallelRefMutIterator, ParallelBridge, ParallelIterator, ParallelSlice, -}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use tracing::instrument; -use super::{ - columns::{CPU_COL_MAP, NUM_CPU_COLS}, - CpuChip, -}; +use super::{columns::NUM_CPU_COLS, CpuChip}; use crate::{cpu::columns::CpuCols, memory::MemoryCols, utils::zeroed_f_vec}; impl MachineAir for CpuChip { @@ -38,7 +33,16 @@ impl MachineAir for CpuChip { input: &ExecutionRecord, _: &mut ExecutionRecord, ) -> RowMajorMatrix { - let mut values = zeroed_f_vec(input.cpu_events.len() * NUM_CPU_COLS); + let n_real_rows = input.cpu_events.len(); + let padded_nb_rows = if let Some(shape) = &input.shape { + 1 << shape.inner[&MachineAir::::name(self)] + } else if n_real_rows < 16 { + 16 + } else { + n_real_rows.next_power_of_two() + }; + let mut values = zeroed_f_vec(padded_nb_rows * NUM_CPU_COLS); + let shard = input.public_values.shard; let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); values.chunks_mut(chunk_size * NUM_CPU_COLS).enumerate().par_bridge().for_each( @@ -46,30 +50,36 @@ impl MachineAir for CpuChip { rows.chunks_mut(NUM_CPU_COLS).enumerate().for_each(|(j, row)| { let idx = i * chunk_size + j; let cols: &mut CpuCols = row.borrow_mut(); - let mut byte_lookup_events = Vec::new(); - self.event_to_row( - &input.cpu_events[idx], - &input.nonce_lookup, - cols, - &mut byte_lookup_events, - ); + + if idx >= input.cpu_events.len() { + cols.selectors.imm_b = F::one(); + cols.selectors.imm_c = F::one(); + } else { + let mut byte_lookup_events = Vec::new(); + let event = &input.cpu_events[idx]; + let instruction = &input.program.fetch(event.pc); + self.event_to_row( + event, + &input.nonce_lookup, + cols, + &mut byte_lookup_events, + shard, + instruction, + ); + } }); }, ); // Convert the trace to a row major matrix. - let mut trace = RowMajorMatrix::new(values, NUM_CPU_COLS); - - // Pad the trace to a power of two. - Self::pad_to_power_of_two::(self, &input.shape, &mut trace.values); - - trace + RowMajorMatrix::new(values, NUM_CPU_COLS) } #[instrument(name = "generate cpu dependencies", level = "debug", skip_all)] fn generate_dependencies(&self, input: &ExecutionRecord, output: &mut ExecutionRecord) { // Generate the trace rows for each event. let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); + let shard = input.public_values.shard; let blu_events: Vec<_> = input .cpu_events @@ -80,7 +90,15 @@ impl MachineAir for CpuChip { ops.iter().for_each(|op| { let mut row = [F::zero(); NUM_CPU_COLS]; let cols: &mut CpuCols = row.as_mut_slice().borrow_mut(); - self.event_to_row::(op, &HashMap::new(), cols, &mut blu); + let instruction = &input.program.fetch(op.pc); + self.event_to_row::( + op, + &input.nonce_lookup, + cols, + &mut blu, + shard, + instruction, + ); }); blu }) @@ -103,23 +121,25 @@ impl CpuChip { fn event_to_row( &self, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], cols: &mut CpuCols, blu_events: &mut impl ByteRecord, + shard: u32, + instruction: &Instruction, ) { // Populate shard and clk columns. - self.populate_shard_clk(cols, event, blu_events); + self.populate_shard_clk(cols, event, blu_events, shard); // Populate the nonce. cols.nonce = F::from_canonical_u32( - nonce_lookup.get(&event.alu_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.alu_lookup_id.0 as usize).copied().unwrap_or_default(), ); // Populate basic fields. cols.pc = F::from_canonical_u32(event.pc); cols.next_pc = F::from_canonical_u32(event.next_pc); - cols.instruction.populate(event.instruction); - cols.selectors.populate(event.instruction); + cols.instruction.populate(instruction); + cols.selectors.populate(instruction); *cols.op_a_access.value_mut() = event.a.into(); *cols.op_b_access.value_mut() = event.b.into(); *cols.op_c_access.value_mut() = event.c.into(); @@ -145,7 +165,7 @@ impl CpuChip { .map(|x| x.as_canonical_u32()) .collect::>(); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, + shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -153,7 +173,7 @@ impl CpuChip { c: a_bytes[1] as u8, }); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, + shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -162,23 +182,20 @@ impl CpuChip { }); // Populate memory accesses for reading from memory. - assert_eq!(event.memory_record.is_some(), event.memory.is_some()); let memory_columns = cols.opcode_specific_columns.memory_mut(); if let Some(record) = event.memory_record { memory_columns.memory_access.populate(record, blu_events) } // Populate memory, branch, jump, and auipc specific fields. - self.populate_memory(cols, event, blu_events, nonce_lookup); - self.populate_branch(cols, event, nonce_lookup); - self.populate_jump(cols, event, nonce_lookup); - self.populate_auipc(cols, event, nonce_lookup); + self.populate_memory(cols, event, blu_events, nonce_lookup, shard, instruction); + self.populate_branch(cols, event, nonce_lookup, instruction); + self.populate_jump(cols, event, nonce_lookup, instruction); + self.populate_auipc(cols, event, nonce_lookup, instruction); let is_halt = self.populate_ecall(cols, event, nonce_lookup); cols.is_sequential_instr = F::from_bool( - !event.instruction.is_branch_instruction() - && !event.instruction.is_jump_instruction() - && !is_halt, + !instruction.is_branch_instruction() && !instruction.is_jump_instruction() && !is_halt, ); // Assert that the instruction is not a no-op. @@ -191,8 +208,9 @@ impl CpuChip { cols: &mut CpuCols, event: &CpuEvent, blu_events: &mut impl ByteRecord, + shard: u32, ) { - cols.shard = F::from_canonical_u32(event.shard); + cols.shard = F::from_canonical_u32(shard); cols.clk = F::from_canonical_u32(event.clk); let clk_16bit_limb = (event.clk & 0xffff) as u16; @@ -201,15 +219,15 @@ impl CpuChip { cols.clk_8bit_limb = F::from_canonical_u8(clk_8bit_limb); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - event.shard, + shard, U16Range, - event.shard as u16, + shard as u16, 0, 0, 0, )); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - event.shard, + shard, U16Range, clk_16bit_limb, 0, @@ -217,7 +235,7 @@ impl CpuChip { 0, )); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - event.shard, + shard, ByteOpcode::U8Range, 0, 0, @@ -232,10 +250,12 @@ impl CpuChip { cols: &mut CpuCols, event: &CpuEvent, blu_events: &mut impl ByteRecord, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], + shard: u32, + instruction: &Instruction, ) { if !matches!( - event.instruction.opcode, + instruction.opcode, Opcode::LB | Opcode::LH | Opcode::LW @@ -262,7 +282,7 @@ impl CpuChip { let bits: [bool; 8] = array::from_fn(|i| aligned_addr_ls_byte & (1 << i) != 0); memory_columns.aa_least_sig_byte_decomp = array::from_fn(|i| F::from_bool(bits[i + 2])); memory_columns.addr_word_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.memory_add_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.memory_add_lookup_id.0 as usize).copied().unwrap_or_default(), ); // Populate memory offsets. @@ -275,10 +295,10 @@ impl CpuChip { // If it is a load instruction, set the unsigned_mem_val column. let mem_value = event.memory_record.unwrap().value(); if matches!( - event.instruction.opcode, + instruction.opcode, Opcode::LB | Opcode::LBU | Opcode::LH | Opcode::LHU | Opcode::LW ) { - match event.instruction.opcode { + match instruction.opcode { Opcode::LB | Opcode::LBU => { cols.unsigned_mem_val = (mem_value.to_le_bytes()[addr_offset as usize] as u32).into(); @@ -298,8 +318,8 @@ impl CpuChip { } // For the signed load instructions, we need to check if the loaded value is negative. - if matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) { - let most_sig_mem_value_byte = if matches!(event.instruction.opcode, Opcode::LB) { + if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { + let most_sig_mem_value_byte = if matches!(instruction.opcode, Opcode::LB) { cols.unsigned_mem_val.to_u32().to_le_bytes()[0] } else { cols.unsigned_mem_val.to_u32().to_le_bytes()[1] @@ -310,20 +330,22 @@ impl CpuChip { F::from_canonical_u8(most_sig_mem_value_byte >> i & 0x01); } if memory_columns.most_sig_byte_decomp[7] == F::one() { - cols.mem_value_is_neg_not_x0 = - F::from_bool(event.instruction.op_a != (X0 as u32)); + cols.mem_value_is_neg_not_x0 = F::from_bool(instruction.op_a != (X0 as u8)); cols.unsigned_mem_val_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.memory_sub_lookup_id).copied().unwrap_or_default(), + nonce_lookup + .get(event.memory_sub_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), ); } } // Set the `mem_value_is_pos_not_x0` composite flag. cols.mem_value_is_pos_not_x0 = F::from_bool( - ((matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) + ((matches!(instruction.opcode, Opcode::LB | Opcode::LH) && (memory_columns.most_sig_byte_decomp[7] == F::zero())) - || matches!(event.instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) - && event.instruction.op_a != (X0 as u32), + || matches!(instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) + && instruction.op_a != (X0 as u8), ); } @@ -331,7 +353,7 @@ impl CpuChip { let addr_bytes = memory_addr.to_le_bytes(); for byte_pair in addr_bytes.chunks_exact(2) { blu_events.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, + shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -346,15 +368,15 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], + instruction: &Instruction, ) { - if event.instruction.is_branch_instruction() { + if instruction.is_branch_instruction() { let branch_columns = cols.opcode_specific_columns.branch_mut(); let a_eq_b = event.a == event.b; - let use_signed_comparison = - matches!(event.instruction.opcode, Opcode::BLT | Opcode::BGE); + let use_signed_comparison = matches!(instruction.opcode, Opcode::BLT | Opcode::BGE); let a_lt_b = if use_signed_comparison { (event.a as i32) < (event.b as i32) @@ -368,18 +390,18 @@ impl CpuChip { }; branch_columns.a_lt_b_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.branch_lt_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.branch_lt_lookup_id.0 as usize).copied().unwrap_or_default(), ); branch_columns.a_gt_b_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.branch_gt_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.branch_gt_lookup_id.0 as usize).copied().unwrap_or_default(), ); branch_columns.a_eq_b = F::from_bool(a_eq_b); branch_columns.a_lt_b = F::from_bool(a_lt_b); branch_columns.a_gt_b = F::from_bool(a_gt_b); - let branching = match event.instruction.opcode { + let branching = match instruction.opcode { Opcode::BEQ => a_eq_b, Opcode::BNE => !a_eq_b, Opcode::BLT | Opcode::BLTU => a_lt_b, @@ -396,7 +418,10 @@ impl CpuChip { if branching { cols.branching = F::one(); branch_columns.next_pc_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.branch_add_lookup_id).copied().unwrap_or_default(), + nonce_lookup + .get(event.branch_add_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), ); } else { cols.not_branching = F::one(); @@ -409,12 +434,13 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], + instruction: &Instruction, ) { - if event.instruction.is_jump_instruction() { + if instruction.is_jump_instruction() { let jump_columns = cols.opcode_specific_columns.jump_mut(); - match event.instruction.opcode { + match instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); jump_columns.op_a_range_checker.populate(event.a); @@ -423,7 +449,10 @@ impl CpuChip { jump_columns.next_pc = Word::from(next_pc); jump_columns.next_pc_range_checker.populate(next_pc); jump_columns.jal_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.jump_jal_lookup_id).copied().unwrap_or_default(), + nonce_lookup + .get(event.jump_jal_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), ); } Opcode::JALR => { @@ -432,7 +461,10 @@ impl CpuChip { jump_columns.next_pc = Word::from(next_pc); jump_columns.next_pc_range_checker.populate(next_pc); jump_columns.jalr_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.jump_jalr_lookup_id).copied().unwrap_or_default(), + nonce_lookup + .get(event.jump_jalr_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), ); } _ => unreachable!(), @@ -445,15 +477,16 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], + instruction: &Instruction, ) { - if matches!(event.instruction.opcode, Opcode::AUIPC) { + if matches!(instruction.opcode, Opcode::AUIPC) { let auipc_columns = cols.opcode_specific_columns.auipc_mut(); auipc_columns.pc = Word::from(event.pc); auipc_columns.pc_range_checker.populate(event.pc); auipc_columns.auipc_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.auipc_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.auipc_lookup_id.0 as usize).copied().unwrap_or_default(), ); } } @@ -463,7 +496,7 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], ) -> bool { let mut is_halt = false; @@ -516,9 +549,8 @@ impl CpuChip { } // Write the syscall nonce. - ecall_cols.syscall_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.syscall_lookup_id).copied().unwrap_or_default(), - ); + ecall_cols.syscall_nonce = + F::from_canonical_u32(nonce_lookup[event.syscall_lookup_id.0 as usize]); is_halt = syscall_id == F::from_canonical_u32(SyscallCode::HALT.syscall_id()); @@ -540,29 +572,4 @@ impl CpuChip { is_halt } - - fn pad_to_power_of_two(&self, shape: &Option, values: &mut Vec) { - let n_real_rows = values.len() / NUM_CPU_COLS; - let padded_nb_rows = if let Some(shape) = shape { - 1 << shape.inner[&MachineAir::::name(self)] - } else if n_real_rows < 16 { - 16 - } else { - n_real_rows.next_power_of_two() - }; - values.resize(padded_nb_rows * NUM_CPU_COLS, F::zero()); - - // Interpret values as a slice of arrays of length `NUM_CPU_COLS` - let rows = unsafe { - core::slice::from_raw_parts_mut( - values.as_mut_ptr() as *mut [F; NUM_CPU_COLS], - values.len() / NUM_CPU_COLS, - ) - }; - - rows[n_real_rows..].par_iter_mut().for_each(|padded_row| { - padded_row[CPU_COL_MAP.selectors.imm_b] = F::one(); - padded_row[CPU_COL_MAP.selectors.imm_c] = F::one(); - }); - } } diff --git a/crates/core/machine/src/memory/local.rs b/crates/core/machine/src/memory/local.rs index bf109d028e..8be4377031 100644 --- a/crates/core/machine/src/memory/local.rs +++ b/crates/core/machine/src/memory/local.rs @@ -3,11 +3,11 @@ use std::{ mem::size_of, }; -use crate::utils::pad_rows_fixed; -use itertools::Itertools; +use crate::utils::{next_power_of_two, zeroed_f_vec}; use p3_air::{Air, BaseAir}; use p3_field::PrimeField32; use p3_matrix::{dense::RowMajorMatrix, Matrix}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -86,39 +86,45 @@ impl MachineAir for MemoryLocalChip { input: &ExecutionRecord, _output: &mut ExecutionRecord, ) -> RowMajorMatrix { - let mut rows = Vec::<[F; NUM_MEMORY_LOCAL_INIT_COLS]>::new(); - - for local_mem_events in - &input.get_local_mem_events().chunks(NUM_LOCAL_MEMORY_ENTRIES_PER_ROW) - { - let mut row = [F::zero(); NUM_MEMORY_LOCAL_INIT_COLS]; - let cols: &mut MemoryLocalCols = row.as_mut_slice().borrow_mut(); - - for (cols, event) in cols.memory_local_entries.iter_mut().zip(local_mem_events) { - cols.addr = F::from_canonical_u32(event.addr); - cols.initial_shard = F::from_canonical_u32(event.initial_mem_access.shard); - cols.final_shard = F::from_canonical_u32(event.final_mem_access.shard); - cols.initial_clk = F::from_canonical_u32(event.initial_mem_access.timestamp); - cols.final_clk = F::from_canonical_u32(event.final_mem_access.timestamp); - cols.initial_value = event.initial_mem_access.value.into(); - cols.final_value = event.final_mem_access.value.into(); - cols.is_real = F::one(); - } - - rows.push(row); - } - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_MEMORY_LOCAL_INIT_COLS], - input.fixed_log2_rows::(self), - ); - - RowMajorMatrix::new( - rows.into_iter().flatten().collect::>(), - NUM_MEMORY_LOCAL_INIT_COLS, - ) + // Generate the trace rows for each event. + let events = input.get_local_mem_events().collect::>(); + let nb_rows = (events.len() + 3) / 4; + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_MEMORY_LOCAL_INIT_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values + .chunks_mut(chunk_size * NUM_MEMORY_LOCAL_INIT_COLS) + .enumerate() + .par_bridge() + .for_each(|(i, rows)| { + rows.chunks_mut(NUM_MEMORY_LOCAL_INIT_COLS).enumerate().for_each(|(j, row)| { + let idx = (i * chunk_size + j) * NUM_LOCAL_MEMORY_ENTRIES_PER_ROW; + + let cols: &mut MemoryLocalCols = row.borrow_mut(); + for k in 0..NUM_LOCAL_MEMORY_ENTRIES_PER_ROW { + let cols = &mut cols.memory_local_entries[k]; + if idx + k < events.len() { + let event = &events[idx + k]; + cols.addr = F::from_canonical_u32(event.addr); + cols.initial_shard = + F::from_canonical_u32(event.initial_mem_access.shard); + cols.final_shard = F::from_canonical_u32(event.final_mem_access.shard); + cols.initial_clk = + F::from_canonical_u32(event.initial_mem_access.timestamp); + cols.final_clk = + F::from_canonical_u32(event.final_mem_access.timestamp); + cols.initial_value = event.initial_mem_access.value.into(); + cols.final_value = event.final_mem_access.value.into(); + cols.is_real = F::one(); + } + } + }); + }); + + // Convert the trace to a row major matrix. + RowMajorMatrix::new(values, NUM_MEMORY_LOCAL_INIT_COLS) } fn included(&self, shard: &Self::Record) -> bool { diff --git a/crates/core/machine/src/memory/program.rs b/crates/core/machine/src/memory/program.rs index 7b68661624..699e052c0d 100644 --- a/crates/core/machine/src/memory/program.rs +++ b/crates/core/machine/src/memory/program.rs @@ -7,6 +7,7 @@ use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, PairBuilder}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -17,7 +18,10 @@ use sp1_stark::{ InteractionKind, Word, }; -use crate::{operations::IsZeroOperation, utils::pad_rows_fixed}; +use crate::{ + operations::IsZeroOperation, + utils::{next_power_of_two, pad_rows_fixed, zeroed_f_vec}, +}; pub const NUM_MEMORY_PROGRAM_PREPROCESSED_COLS: usize = size_of::>(); @@ -71,35 +75,36 @@ impl MachineAir for MemoryProgramChip { } fn generate_preprocessed_trace(&self, program: &Self::Program) -> Option> { - let program_memory = &program.memory_image; - // Note that BTreeMap is guaranteed to be sorted by key. This makes the row order - // deterministic. - let mut rows = program_memory - .iter() - .sorted() - .map(|(&addr, &word)| { - let mut row = [F::zero(); NUM_MEMORY_PROGRAM_PREPROCESSED_COLS]; - let cols: &mut MemoryProgramPreprocessedCols = row.as_mut_slice().borrow_mut(); - cols.addr = F::from_canonical_u32(addr); - cols.value = Word::from(word); - cols.is_real = F::one(); - row - }) - .collect::>(); - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_MEMORY_PROGRAM_PREPROCESSED_COLS], - program.fixed_log2_rows::(self), - ); + // Generate the trace rows for each event. + let nb_rows = program.memory_image.len(); + let size_log2 = program.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_MEMORY_PROGRAM_PREPROCESSED_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + let memory = program.memory_image.iter().collect::>(); + values + .chunks_mut(chunk_size * NUM_MEMORY_PROGRAM_PREPROCESSED_COLS) + .enumerate() + .par_bridge() + .for_each(|(i, rows)| { + rows.chunks_mut(NUM_MEMORY_PROGRAM_PREPROCESSED_COLS).enumerate().for_each( + |(j, row)| { + let idx = i * chunk_size + j; + + if idx < nb_rows { + let (addr, word) = memory[idx]; + let cols: &mut MemoryProgramPreprocessedCols = row.borrow_mut(); + cols.addr = F::from_canonical_u32(*addr); + cols.value = Word::from(*word); + cols.is_real = F::one(); + } + }, + ); + }); // Convert the trace to a row major matrix. - let trace = RowMajorMatrix::new( - rows.into_iter().flatten().collect::>(), - NUM_MEMORY_PROGRAM_PREPROCESSED_COLS, - ); - Some(trace) + Some(RowMajorMatrix::new(values, NUM_MEMORY_PROGRAM_PREPROCESSED_COLS)) } fn generate_dependencies(&self, _input: &ExecutionRecord, _output: &mut ExecutionRecord) { diff --git a/crates/core/machine/src/program/mod.rs b/crates/core/machine/src/program/mod.rs index 39dfb6a765..f6c1f3bc0c 100644 --- a/crates/core/machine/src/program/mod.rs +++ b/crates/core/machine/src/program/mod.rs @@ -4,10 +4,14 @@ use core::{ }; use std::collections::HashMap; -use crate::{air::ProgramAirBuilder, utils::pad_rows_fixed}; +use crate::{ + air::ProgramAirBuilder, + utils::{next_power_of_two, pad_rows_fixed, zeroed_f_vec}, +}; use p3_air::{Air, BaseAir, PairBuilder}; use p3_field::PrimeField; use p3_matrix::{dense::RowMajorMatrix, Matrix}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::air::{MachineAir, SP1AirBuilder}; @@ -65,36 +69,34 @@ impl MachineAir for ProgramChip { !program.instructions.is_empty() || program.preprocessed_shape.is_some(), "empty program" ); - let mut rows = program - .instructions - .iter() + // Generate the trace rows for each event. + let nb_rows = program.instructions.len(); + let size_log2 = program.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_PROGRAM_PREPROCESSED_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values + .chunks_mut(chunk_size * NUM_PROGRAM_PREPROCESSED_COLS) .enumerate() - .map(|(i, &instruction)| { - let pc = program.pc_base + (i as u32 * 4); - let mut row = [F::zero(); NUM_PROGRAM_PREPROCESSED_COLS]; - let cols: &mut ProgramPreprocessedCols = row.as_mut_slice().borrow_mut(); - cols.pc = F::from_canonical_u32(pc); - cols.instruction.populate(instruction); - cols.selectors.populate(instruction); - - row - }) - .collect::>(); - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_PROGRAM_PREPROCESSED_COLS], - program.fixed_log2_rows::(self), - ); + .par_bridge() + .for_each(|(i, rows)| { + rows.chunks_mut(NUM_PROGRAM_PREPROCESSED_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + + if idx < nb_rows { + let cols: &mut ProgramPreprocessedCols = row.borrow_mut(); + let instruction = &program.instructions[idx]; + let pc = program.pc_base + (idx as u32 * 4); + cols.pc = F::from_canonical_u32(pc); + cols.instruction.populate(instruction); + cols.selectors.populate(instruction); + } + }); + }); // Convert the trace to a row major matrix. - let trace = RowMajorMatrix::new( - rows.into_iter().flatten().collect::>(), - NUM_PROGRAM_PREPROCESSED_COLS, - ); - - Some(trace) + Some(RowMajorMatrix::new(values, NUM_PROGRAM_PREPROCESSED_COLS)) } fn generate_dependencies(&self, _input: &ExecutionRecord, _output: &mut ExecutionRecord) { diff --git a/crates/core/machine/src/runtime/utils.rs b/crates/core/machine/src/runtime/utils.rs index 7c0ad541e7..483400e294 100644 --- a/crates/core/machine/src/runtime/utils.rs +++ b/crates/core/machine/src/runtime/utils.rs @@ -19,7 +19,7 @@ macro_rules! assert_valid_memory_access { assert!($addr > 40); } _ => { - Register::from_u32($addr); + Register::from_u8($addr); } }; } @@ -69,11 +69,7 @@ impl<'a> Runtime<'a> { ); if !self.unconstrained && self.state.global_clk % 10_000_000 == 0 { - log::info!( - "clk = {} pc = 0x{:x?}", - self.state.global_clk, - self.state.pc - ); + log::info!("clk = {} pc = 0x{:x?}", self.state.global_clk, self.state.pc); } } } diff --git a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs index c9c5ae93c8..97d0e526fe 100644 --- a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs +++ b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs @@ -72,7 +72,7 @@ impl EdDecompressCols { self.clk = F::from_canonical_u32(event.clk); self.ptr = F::from_canonical_u32(event.ptr); self.nonce = F::from_canonical_u32( - record.nonce_lookup.get(&event.lookup_id).copied().unwrap_or_default(), + record.nonce_lookup.get(event.lookup_id.0 as usize).copied().unwrap_or_default(), ); self.sign = F::from_bool(event.sign); for i in 0..8 { diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index be4d816264..fb46afd4ed 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -33,11 +33,7 @@ use std::{ }; use lru::LruCache; - -use tracing::instrument; - use p3_baby_bear::BabyBear; - use p3_challenger::CanObserve; use p3_field::{AbstractField, PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; @@ -80,6 +76,7 @@ use sp1_stark::{ MachineProver, SP1CoreOpts, SP1ProverOpts, ShardProof, StarkGenericConfig, StarkVerifyingKey, Val, Word, DIGEST_SIZE, }; +use tracing::instrument; pub use types::*; use utils::{sp1_committed_values_digest_bn254, sp1_vkey_digest_bn254, words_to_bytes}; @@ -356,8 +353,9 @@ impl SP1Prover { input: &SP1CompressWithVKeyWitnessValues, ) -> Arc> { let mut cache = self.compress_programs.lock().unwrap_or_else(|e| e.into_inner()); + let shape = input.shape(); cache - .get_or_insert(input.shape(), || { + .get_or_insert(shape.clone(), || { let misses = self.compress_cache_misses.fetch_add(1, Ordering::Relaxed); tracing::debug!("compress cache miss, misses: {}", misses); // Get the operations. diff --git a/crates/prover/src/shapes.rs b/crates/prover/src/shapes.rs index b7adddc0e5..74f7ba177e 100644 --- a/crates/prover/src/shapes.rs +++ b/crates/prover/src/shapes.rs @@ -1,11 +1,13 @@ use std::{ collections::{BTreeMap, BTreeSet, HashSet}, fs::File, + hash::{DefaultHasher, Hash, Hasher}, panic::{catch_unwind, AssertUnwindSafe}, path::PathBuf, sync::{Arc, Mutex}, }; +use eyre::Result; use thiserror::Error; use p3_baby_bear::BabyBear; @@ -29,7 +31,7 @@ pub enum SP1ProofShape { Shrink(ProofShape), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash)] pub enum SP1CompressProgramShape { Recursion(SP1RecursionShape), Compress(SP1CompressWithVkeyShape), @@ -37,6 +39,14 @@ pub enum SP1CompressProgramShape { Shrink(SP1CompressWithVkeyShape), } +impl SP1CompressProgramShape { + pub fn hash_u64(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + Hash::hash(&self, &mut hasher); + hasher.finish() + } +} + #[derive(Debug, Error)] pub enum VkBuildError { #[error("IO error: {0}")] @@ -231,6 +241,15 @@ impl SP1ProofShape { ) } + pub fn generate_compress_shapes( + recursion_shape_config: &'_ RecursionShapeConfig>, + reduce_batch_size: usize, + ) -> impl Iterator + '_ { + (1..=reduce_batch_size).flat_map(|batch_size| { + recursion_shape_config.get_all_shape_combinations(batch_size).map(Self::Compress) + }) + } + pub fn dummy_vk_map<'a>( core_shape_config: &'a CoreShapeConfig, recursion_shape_config: &'a RecursionShapeConfig>, diff --git a/crates/recursion/circuit/src/machine/deferred.rs b/crates/recursion/circuit/src/machine/deferred.rs index 0f38620a7d..d5ab720973 100644 --- a/crates/recursion/circuit/src/machine/deferred.rs +++ b/crates/recursion/circuit/src/machine/deferred.rs @@ -43,7 +43,7 @@ pub struct SP1DeferredVerifier { _phantom: std::marker::PhantomData<(C, SC, A)>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash)] pub struct SP1DeferredShape { inner: SP1CompressShape, height: usize, diff --git a/crates/recursion/compiler/src/circuit/compiler.rs b/crates/recursion/compiler/src/circuit/compiler.rs index d75c0d3d6e..b44b38a1dd 100644 --- a/crates/recursion/compiler/src/circuit/compiler.rs +++ b/crates/recursion/compiler/src/circuit/compiler.rs @@ -17,6 +17,9 @@ use sp1_recursion_core::*; use crate::prelude::*; +/// The number of instructions to preallocate in a recursion program +const PREALLOC_INSTRUCTIONS: usize = 10000000; + /// The backend for the circuit compiler. #[derive(Debug, Clone, Default)] pub struct AsmCompiler { @@ -511,7 +514,7 @@ where // Compile each IR instruction into a list of ASM instructions, then combine them. // This step also counts the number of times each address is read from. let (mut instrs, traces) = tracing::debug_span!("compile_one loop").in_scope(|| { - let mut instrs = Vec::with_capacity(operations.vec.len()); + let mut instrs = Vec::with_capacity(PREALLOC_INSTRUCTIONS); let mut traces = vec![]; if debug_mode { let mut span_builder = diff --git a/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs b/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs index ecd9c57550..7e67f54362 100644 --- a/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs @@ -41,6 +41,10 @@ impl MachineAir for Poseidon2SkinnyChip format!("Poseidon2SkinnyDeg{}", DEGREE) } + fn generate_dependencies(&self, _: &Self::Record, _: &mut Self::Record) { + // This is a no-op. + } + #[instrument(name = "generate poseidon2 skinny trace", level = "debug", skip_all, fields(rows = input.poseidon2_events.len()))] fn generate_trace( &self, diff --git a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs index 0d5c666265..19a3b6f287 100644 --- a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs @@ -37,6 +37,10 @@ impl MachineAir for Poseidon2WideChip, const DEGREE: u #[derive(Debug, Clone, Copy, Default)] pub struct RecursionAirEventCount { - mem_const_events: usize, - mem_var_events: usize, - base_alu_events: usize, - ext_alu_events: usize, - poseidon2_wide_events: usize, - fri_fold_events: usize, - select_events: usize, - exp_reverse_bits_len_events: usize, + pub mem_const_events: usize, + pub mem_var_events: usize, + pub base_alu_events: usize, + pub ext_alu_events: usize, + pub poseidon2_wide_events: usize, + pub fri_fold_events: usize, + pub select_events: usize, + pub exp_reverse_bits_len_events: usize, } impl, const DEGREE: usize> RecursionAir { diff --git a/crates/recursion/core/src/runtime/memory.rs b/crates/recursion/core/src/runtime/memory.rs index a82337b684..d0b7f0f229 100644 --- a/crates/recursion/core/src/runtime/memory.rs +++ b/crates/recursion/core/src/runtime/memory.rs @@ -5,7 +5,7 @@ use vec_map::{Entry, VecMap}; use crate::{air::Block, Address}; -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, Copy)] pub struct MemoryEntry { pub val: Block, pub mult: F, diff --git a/crates/recursion/core/src/runtime/mod.rs b/crates/recursion/core/src/runtime/mod.rs index f95ef87a14..2478a45ddb 100644 --- a/crates/recursion/core/src/runtime/mod.rs +++ b/crates/recursion/core/src/runtime/mod.rs @@ -8,6 +8,7 @@ mod record; use backtrace::Backtrace as Trace; pub use instruction::Instruction; use instruction::{FieldEltType, HintBitsInstr, HintExt2FeltsInstr, HintInstr, PrintInstr}; +use machine::RecursionAirEventCount; use memory::*; pub use opcode::*; pub use program::*; @@ -249,6 +250,7 @@ where pub fn run(&mut self) -> Result<(), RuntimeError> { let early_exit_ts = std::env::var("RECURSION_EARLY_EXIT_TS") .map_or(usize::MAX, |ts: String| ts.parse().unwrap()); + self.preallocate_record(); while self.pc < F::from_canonical_u32(self.program.instructions.len() as u32) { let idx = self.pc.as_canonical_u32() as usize; let instruction = self.program.instructions[idx].clone(); @@ -544,4 +546,18 @@ where } Ok(()) } + + pub fn preallocate_record(&mut self) { + let event_counts = self + .program + .instructions + .iter() + .fold(RecursionAirEventCount::default(), |heights, instruction| heights + instruction); + self.record.poseidon2_events.reserve(event_counts.poseidon2_wide_events); + self.record.mem_var_events.reserve(event_counts.mem_var_events); + self.record.base_alu_events.reserve(event_counts.base_alu_events); + self.record.ext_alu_events.reserve(event_counts.ext_alu_events); + self.record.exp_reverse_bits_len_events.reserve(event_counts.exp_reverse_bits_len_events); + self.record.select_events.reserve(event_counts.select_events); + } } From a70df029ff7ea12e9a2f51d1e82a6e8d0e6a6a03 Mon Sep 17 00:00:00 2001 From: Tamir Hemo Date: Wed, 30 Oct 2024 18:22:02 -0700 Subject: [PATCH 05/17] fix: Revert "feat: executor optimizations" (#1718) --- Cargo.lock | 1 - crates/core/executor/src/dependencies.rs | 119 ++--- crates/core/executor/src/disassembler/rrs.rs | 57 +- crates/core/executor/src/events/alu.rs | 4 +- crates/core/executor/src/events/byte.rs | 2 +- crates/core/executor/src/events/cpu.rs | 8 + crates/core/executor/src/events/memory.rs | 8 +- crates/core/executor/src/events/utils.rs | 37 +- crates/core/executor/src/executor.rs | 486 ++++++++++-------- crates/core/executor/src/instruction.rs | 4 +- crates/core/executor/src/memory.rs | 27 +- crates/core/executor/src/opcode.rs | 2 +- crates/core/executor/src/program.rs | 7 - crates/core/executor/src/record.rs | 71 +-- crates/core/executor/src/register.rs | 4 +- .../src/syscalls/precompiles/sha256/extend.rs | 10 +- crates/core/machine/Cargo.toml | 1 - crates/core/machine/src/alu/add_sub/mod.rs | 66 ++- crates/core/machine/src/alu/divrem/mod.rs | 28 +- crates/core/machine/src/alu/lt/mod.rs | 51 +- crates/core/machine/src/alu/mul/mod.rs | 283 +++++----- crates/core/machine/src/alu/sr/mod.rs | 73 ++- .../machine/src/cpu/columns/instruction.rs | 6 +- crates/core/machine/src/cpu/columns/opcode.rs | 2 +- crates/core/machine/src/cpu/trace.rs | 213 ++++---- crates/core/machine/src/memory/local.rs | 76 ++- crates/core/machine/src/memory/program.rs | 61 +-- crates/core/machine/src/program/mod.rs | 58 +-- crates/core/machine/src/runtime/utils.rs | 8 +- .../precompiles/edwards/ed_decompress.rs | 2 +- crates/prover/src/lib.rs | 8 +- crates/prover/src/shapes.rs | 21 +- .../recursion/circuit/src/machine/deferred.rs | 2 +- .../compiler/src/circuit/compiler.rs | 5 +- .../core/src/chips/poseidon2_skinny/trace.rs | 4 - .../core/src/chips/poseidon2_wide/trace.rs | 4 - crates/recursion/core/src/machine.rs | 16 +- crates/recursion/core/src/runtime/memory.rs | 2 +- crates/recursion/core/src/runtime/mod.rs | 16 - 39 files changed, 929 insertions(+), 924 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 748f845ec7..22a73f10b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6215,7 +6215,6 @@ dependencies = [ "tracing-forest", "tracing-subscriber", "typenum", - "vec_map", "web-time", ] diff --git a/crates/core/executor/src/dependencies.rs b/crates/core/executor/src/dependencies.rs index 6b0bbbe33c..194d8d0eb2 100644 --- a/crates/core/executor/src/dependencies.rs +++ b/crates/core/executor/src/dependencies.rs @@ -1,5 +1,5 @@ use crate::{ - events::AluEvent, + events::{create_alu_lookups, AluEvent, CpuEvent}, utils::{get_msb, get_quotient_and_remainder, is_signed_operation}, Executor, Opcode, }; @@ -7,7 +7,6 @@ use crate::{ /// Emits the dependencies for division and remainder operations. #[allow(clippy::too_many_lines)] pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { - let shard = executor.shard(); let (quotient, remainder) = get_quotient_and_remainder(event.b, event.c, event.opcode); let c_msb = get_msb(event.c); let rem_msb = get_msb(remainder); @@ -20,29 +19,27 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { } if c_neg == 1 { - let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(AluEvent { lookup_id: event.sub_lookups[4], - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: 0, b: event.c, c: (event.c as i32).unsigned_abs(), - sub_lookups: ids, + sub_lookups: create_alu_lookups(), }); } if rem_neg == 1 { - let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(AluEvent { lookup_id: event.sub_lookups[5], - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: 0, b: remainder, c: (remainder as i32).unsigned_abs(), - sub_lookups: ids, + sub_lookups: create_alu_lookups(), }); } @@ -58,19 +55,19 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { let lower_multiplication = AluEvent { lookup_id: event.sub_lookups[0], - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::MUL, a: lower_word, c: event.c, b: quotient, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.mul_events.push(lower_multiplication); let upper_multiplication = AluEvent { lookup_id: event.sub_lookups[1], - shard, + shard: event.shard, clk: event.clk, opcode: { if is_signed_operation { @@ -82,31 +79,31 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { a: upper_word, c: event.c, b: quotient, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.mul_events.push(upper_multiplication); let lt_event = if is_signed_operation { AluEvent { lookup_id: event.sub_lookups[2], - shard, + shard: event.shard, opcode: Opcode::SLTU, a: 1, b: (remainder as i32).unsigned_abs(), c: u32::max(1, (event.c as i32).unsigned_abs()), clk: event.clk, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), } } else { AluEvent { lookup_id: event.sub_lookups[3], - shard, + shard: event.shard, opcode: Opcode::SLTU, a: 1, b: remainder, c: u32::max(1, event.c), clk: event.clk, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), } }; @@ -117,12 +114,9 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { /// Emit the dependencies for CPU events. #[allow(clippy::too_many_lines)] -pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { - let event = executor.record.cpu_events[index]; - let shard = executor.shard(); - let instruction = &executor.program.fetch(event.pc); +pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { if matches!( - instruction.opcode, + event.instruction.opcode, Opcode::LB | Opcode::LH | Opcode::LW @@ -136,57 +130,58 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { // Add event to ALU check to check that addr == b + c let add_event = AluEvent { lookup_id: event.memory_add_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: memory_addr, b: event.b, c: event.c, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); let addr_offset = (memory_addr % 4_u32) as u8; let mem_value = event.memory_record.unwrap().value(); - if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { - let (unsigned_mem_val, most_sig_mem_value_byte, sign_value) = match instruction.opcode { - Opcode::LB => { - let most_sig_mem_value_byte = mem_value.to_le_bytes()[addr_offset as usize]; - let sign_value = 256; - (most_sig_mem_value_byte as u32, most_sig_mem_value_byte, sign_value) - } - Opcode::LH => { - let sign_value = 65536; - let unsigned_mem_val = match (addr_offset >> 1) % 2 { - 0 => mem_value & 0x0000FFFF, - 1 => (mem_value & 0xFFFF0000) >> 16, - _ => unreachable!(), - }; - let most_sig_mem_value_byte = unsigned_mem_val.to_le_bytes()[1]; - (unsigned_mem_val, most_sig_mem_value_byte, sign_value) - } - _ => unreachable!(), - }; + if matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) { + let (unsigned_mem_val, most_sig_mem_value_byte, sign_value) = + match event.instruction.opcode { + Opcode::LB => { + let most_sig_mem_value_byte = mem_value.to_le_bytes()[addr_offset as usize]; + let sign_value = 256; + (most_sig_mem_value_byte as u32, most_sig_mem_value_byte, sign_value) + } + Opcode::LH => { + let sign_value = 65536; + let unsigned_mem_val = match (addr_offset >> 1) % 2 { + 0 => mem_value & 0x0000FFFF, + 1 => (mem_value & 0xFFFF0000) >> 16, + _ => unreachable!(), + }; + let most_sig_mem_value_byte = unsigned_mem_val.to_le_bytes()[1]; + (unsigned_mem_val, most_sig_mem_value_byte, sign_value) + } + _ => unreachable!(), + }; if most_sig_mem_value_byte >> 7 & 0x01 == 1 { let sub_event = AluEvent { lookup_id: event.memory_sub_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::SUB, a: event.a, b: unsigned_mem_val, c: sign_value, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(sub_event); } } } - if instruction.is_branch_instruction() { + if event.instruction.is_branch_instruction() { let a_eq_b = event.a == event.b; - let use_signed_comparison = matches!(instruction.opcode, Opcode::BLT | Opcode::BGE); + let use_signed_comparison = matches!(event.instruction.opcode, Opcode::BLT | Opcode::BGE); let a_lt_b = if use_signed_comparison { (event.a as i32) < (event.b as i32) } else { @@ -202,27 +197,27 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { // Add the ALU events for the comparisons let lt_comp_event = AluEvent { lookup_id: event.branch_lt_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: alu_op_code, a: a_lt_b as u32, b: event.a, c: event.b, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; let gt_comp_event = AluEvent { lookup_id: event.branch_gt_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: alu_op_code, a: a_gt_b as u32, b: event.b, c: event.a, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.lt_events.push(lt_comp_event); executor.record.lt_events.push(gt_comp_event); - let branching = match instruction.opcode { + let branching = match event.instruction.opcode { Opcode::BEQ => a_eq_b, Opcode::BNE => !a_eq_b, Opcode::BLT | Opcode::BLTU => a_lt_b, @@ -233,31 +228,31 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { let next_pc = event.pc.wrapping_add(event.c); let add_event = AluEvent { lookup_id: event.branch_add_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, c: event.c, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); } } - if instruction.is_jump_instruction() { - match instruction.opcode { + if event.instruction.is_jump_instruction() { + match event.instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); let add_event = AluEvent { lookup_id: event.jump_jal_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, c: event.b, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); } @@ -265,13 +260,13 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { let next_pc = event.b.wrapping_add(event.c); let add_event = AluEvent { lookup_id: event.jump_jalr_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.b, c: event.c, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); } @@ -279,16 +274,16 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { } } - if matches!(instruction.opcode, Opcode::AUIPC) { + if matches!(event.instruction.opcode, Opcode::AUIPC) { let add_event = AluEvent { lookup_id: event.auipc_lookup_id, - shard, + shard: event.shard, clk: event.clk, opcode: Opcode::ADD, a: event.a, b: event.pc, c: event.b, - sub_lookups: executor.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; executor.record.add_events.push(add_event); } diff --git a/crates/core/executor/src/disassembler/rrs.rs b/crates/core/executor/src/disassembler/rrs.rs index a105e10a81..711dbe4e4a 100644 --- a/crates/core/executor/src/disassembler/rrs.rs +++ b/crates/core/executor/src/disassembler/rrs.rs @@ -9,31 +9,52 @@ impl Instruction { /// Create a new [`Instruction`] from an R-type instruction. #[must_use] pub const fn from_r_type(opcode: Opcode, dec_insn: &RType) -> Self { - Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.rs2 as u32, false, false) + Self::new( + opcode, + dec_insn.rd as u32, + dec_insn.rs1 as u32, + dec_insn.rs2 as u32, + false, + false, + ) } /// Create a new [`Instruction`] from an I-type instruction. #[must_use] pub const fn from_i_type(opcode: Opcode, dec_insn: &IType) -> Self { - Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) + Self::new(opcode, dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) } /// Create a new [`Instruction`] from an I-type instruction with a shamt. #[must_use] pub const fn from_i_type_shamt(opcode: Opcode, dec_insn: &ITypeShamt) -> Self { - Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.shamt, false, true) + Self::new(opcode, dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.shamt, false, true) } /// Create a new [`Instruction`] from an S-type instruction. #[must_use] pub const fn from_s_type(opcode: Opcode, dec_insn: &SType) -> Self { - Self::new(opcode, dec_insn.rs2 as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) + Self::new( + opcode, + dec_insn.rs2 as u32, + dec_insn.rs1 as u32, + dec_insn.imm as u32, + false, + true, + ) } /// Create a new [`Instruction`] from a B-type instruction. #[must_use] pub const fn from_b_type(opcode: Opcode, dec_insn: &BType) -> Self { - Self::new(opcode, dec_insn.rs1 as u8, dec_insn.rs2 as u32, dec_insn.imm as u32, false, true) + Self::new( + opcode, + dec_insn.rs1 as u32, + dec_insn.rs2 as u32, + dec_insn.imm as u32, + false, + true, + ) } /// Create a new [`Instruction`] that is not implemented. @@ -61,9 +82,9 @@ impl Instruction { #[must_use] pub fn r_type(&self) -> (Register, Register, Register) { ( - Register::from_u8(self.op_a), - Register::from_u8(self.op_b as u8), - Register::from_u8(self.op_c as u8), + Register::from_u32(self.op_a), + Register::from_u32(self.op_b), + Register::from_u32(self.op_c), ) } @@ -71,35 +92,35 @@ impl Instruction { #[inline] #[must_use] pub fn i_type(&self) -> (Register, Register, u32) { - (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) + (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) } /// Decode the [`Instruction`] in the S-type format. #[inline] #[must_use] pub fn s_type(&self) -> (Register, Register, u32) { - (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) + (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) } /// Decode the [`Instruction`] in the B-type format. #[inline] #[must_use] pub fn b_type(&self) -> (Register, Register, u32) { - (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) + (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) } /// Decode the [`Instruction`] in the J-type format. #[inline] #[must_use] pub fn j_type(&self) -> (Register, u32) { - (Register::from_u8(self.op_a), self.op_b) + (Register::from_u32(self.op_a), self.op_b) } /// Decode the [`Instruction`] in the U-type format. #[inline] #[must_use] pub fn u_type(&self) -> (Register, u32) { - (Register::from_u8(self.op_a), self.op_b) + (Register::from_u32(self.op_a), self.op_b) } } @@ -242,13 +263,13 @@ impl InstructionProcessor for InstructionTranspiler { } fn process_jal(&mut self, dec_insn: JType) -> Self::InstructionResult { - Instruction::new(Opcode::JAL, dec_insn.rd as u8, dec_insn.imm as u32, 0, true, true) + Instruction::new(Opcode::JAL, dec_insn.rd as u32, dec_insn.imm as u32, 0, true, true) } fn process_jalr(&mut self, dec_insn: IType) -> Self::InstructionResult { Instruction::new( Opcode::JALR, - dec_insn.rd as u8, + dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.imm as u32, false, @@ -261,14 +282,14 @@ impl InstructionProcessor for InstructionTranspiler { // // Notably, LUI instructions are converted to an SLL instruction with `imm_b` and `imm_c` // turned on. Additionally the `op_c` should be set to 12. - Instruction::new(Opcode::ADD, dec_insn.rd as u8, 0, dec_insn.imm as u32, true, true) + Instruction::new(Opcode::ADD, dec_insn.rd as u32, 0, dec_insn.imm as u32, true, true) } /// AUIPC instructions have the third operand set to imm << 12. fn process_auipc(&mut self, dec_insn: UType) -> Self::InstructionResult { Instruction::new( Opcode::AUIPC, - dec_insn.rd as u8, + dec_insn.rd as u32, dec_insn.imm as u32, dec_insn.imm as u32, true, @@ -279,7 +300,7 @@ impl InstructionProcessor for InstructionTranspiler { fn process_ecall(&mut self) -> Self::InstructionResult { Instruction::new( Opcode::ECALL, - Register::X5 as u8, + Register::X5 as u32, Register::X10 as u32, Register::X11 as u32, false, diff --git a/crates/core/executor/src/events/alu.rs b/crates/core/executor/src/events/alu.rs index 2d2b14fe03..bf79a65e4c 100644 --- a/crates/core/executor/src/events/alu.rs +++ b/crates/core/executor/src/events/alu.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::Opcode; -use super::{create_random_lookup_ids, LookupId}; +use super::{create_alu_lookups, LookupId}; /// Arithmetic Logic Unit (ALU) Event. /// @@ -40,7 +40,7 @@ impl AluEvent { a, b, c, - sub_lookups: create_random_lookup_ids(), + sub_lookups: create_alu_lookups(), } } } diff --git a/crates/core/executor/src/events/byte.rs b/crates/core/executor/src/events/byte.rs index 3db5c7647b..4e5f254373 100644 --- a/crates/core/executor/src/events/byte.rs +++ b/crates/core/executor/src/events/byte.rs @@ -233,7 +233,7 @@ impl ByteOpcode { ByteOpcode::MSB, ByteOpcode::U16Range, ]; - debug_assert_eq!(opcodes.len(), NUM_BYTE_OPS); + assert_eq!(opcodes.len(), NUM_BYTE_OPS); opcodes } diff --git a/crates/core/executor/src/events/cpu.rs b/crates/core/executor/src/events/cpu.rs index f609e941c0..b2d775cf12 100644 --- a/crates/core/executor/src/events/cpu.rs +++ b/crates/core/executor/src/events/cpu.rs @@ -1,5 +1,7 @@ use serde::{Deserialize, Serialize}; +use crate::Instruction; + use super::{memory::MemoryRecordEnum, LookupId}; /// CPU Event. @@ -8,12 +10,16 @@ use super::{memory::MemoryRecordEnum, LookupId}; /// shard, opcode, operands, and other relevant information. #[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub struct CpuEvent { + /// The shard number. + pub shard: u32, /// The clock cycle. pub clk: u32, /// The program counter. pub pc: u32, /// The next program counter. pub next_pc: u32, + /// The instruction. + pub instruction: Instruction, /// The first operand. pub a: u32, /// The first operand memory record. @@ -26,6 +32,8 @@ pub struct CpuEvent { pub c: u32, /// The third operand memory record. pub c_record: Option, + /// The memory value. + pub memory: Option, /// The memory record. pub memory_record: Option, /// The exit code. diff --git a/crates/core/executor/src/events/memory.rs b/crates/core/executor/src/events/memory.rs index 655e0fc21d..4372f21267 100644 --- a/crates/core/executor/src/events/memory.rs +++ b/crates/core/executor/src/events/memory.rs @@ -150,9 +150,7 @@ impl MemoryReadRecord { prev_shard: u32, prev_timestamp: u32, ) -> Self { - debug_assert!( - shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)) - ); + assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp))); Self { value, shard, timestamp, prev_shard, prev_timestamp } } } @@ -168,9 +166,7 @@ impl MemoryWriteRecord { prev_shard: u32, prev_timestamp: u32, ) -> Self { - debug_assert!( - shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)), - ); + assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)),); Self { value, shard, timestamp, prev_value, prev_shard, prev_timestamp } } } diff --git a/crates/core/executor/src/events/utils.rs b/crates/core/executor/src/events/utils.rs index d4b38df745..681bc6cc78 100644 --- a/crates/core/executor/src/events/utils.rs +++ b/crates/core/executor/src/events/utils.rs @@ -5,16 +5,43 @@ use std::{ iter::{Map, Peekable}, }; +use rand::{thread_rng, Rng}; + /// A unique identifier for lookups. +/// +/// We use 4 u32s instead of a u128 to make it compatible with C. #[derive(Deserialize, Serialize, Debug, Clone, Copy, Default, Eq, Hash, PartialEq)] -pub struct LookupId(pub u64); +pub struct LookupId { + /// First part of the id. + pub a: u32, + /// Second part of the id. + pub b: u32, + /// Third part of the id. + pub c: u32, + /// Fourth part of the id. + pub d: u32, +} + +/// Creates a new ALU lookup id with ``LookupId`` +#[must_use] +pub fn create_alu_lookup_id() -> LookupId { + let mut rng = thread_rng(); + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() } +} -/// Create a random lookup id. This is slower than `record.create_lookup_id()` but is useful for -/// testing. +/// Creates a new ALU lookup id with ``LookupId`` #[must_use] -pub(crate) fn create_random_lookup_ids() -> [LookupId; 6] { - std::array::from_fn(|_| LookupId(rand::random())) +pub fn create_alu_lookups() -> [LookupId; 6] { + let mut rng = thread_rng(); + [ + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, + ] } /// Returns sorted and formatted rows of a table of counts (e.g. `opcode_counts`). diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index 7244955a37..cfbc8cacd5 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -13,8 +13,9 @@ use crate::{ context::SP1Context, dependencies::{emit_cpu_dependencies, emit_divrem_dependencies}, events::{ - AluEvent, CpuEvent, LookupId, MemoryAccessPosition, MemoryInitializeFinalizeEvent, - MemoryLocalEvent, MemoryReadRecord, MemoryRecord, MemoryWriteRecord, SyscallEvent, + create_alu_lookup_id, create_alu_lookups, AluEvent, CpuEvent, LookupId, + MemoryAccessPosition, MemoryInitializeFinalizeEvent, MemoryLocalEvent, MemoryReadRecord, + MemoryRecord, MemoryWriteRecord, SyscallEvent, }, hook::{HookEnv, HookRegistry}, memory::{Entry, PagedMemory}, @@ -268,7 +269,7 @@ impl<'a> Executor<'a> { pub fn registers(&mut self) -> [u32; 32] { let mut registers = [0; 32]; for i in 0..32 { - let addr = Register::from_u8(i as u8) as u32; + let addr = Register::from_u32(i as u32) as u32; let record = self.state.memory.get(addr); // Only add the previous memory state to checkpoint map if we're in checkpoint mode, @@ -406,7 +407,7 @@ impl<'a> Executor<'a> { record.shard = shard; record.timestamp = timestamp; - if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { + if !self.unconstrained { let local_memory_access = if let Some(local_memory_access) = local_memory_access { local_memory_access } else { @@ -485,7 +486,7 @@ impl<'a> Executor<'a> { record.shard = shard; record.timestamp = timestamp; - if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { + if !self.unconstrained { let local_memory_access = if let Some(local_memory_access) = local_memory_access { local_memory_access } else { @@ -552,19 +553,19 @@ impl<'a> Executor<'a> { if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { match position { MemoryAccessPosition::A => { - debug_assert!(self.memory_accesses.a.is_none()); + assert!(self.memory_accesses.a.is_none()); self.memory_accesses.a = Some(record.into()); } MemoryAccessPosition::B => { - debug_assert!(self.memory_accesses.b.is_none()); + assert!(self.memory_accesses.b.is_none()); self.memory_accesses.b = Some(record.into()); } MemoryAccessPosition::C => { - debug_assert!(self.memory_accesses.c.is_none()); + assert!(self.memory_accesses.c.is_none()); self.memory_accesses.c = Some(record.into()); } MemoryAccessPosition::Memory => { - debug_assert!(self.memory_accesses.memory.is_none()); + assert!(self.memory_accesses.memory.is_none()); self.memory_accesses.memory = Some(record.into()); } } @@ -592,50 +593,49 @@ impl<'a> Executor<'a> { #[allow(clippy::too_many_arguments)] fn emit_cpu( &mut self, + shard: u32, clk: u32, pc: u32, next_pc: u32, + instruction: Instruction, a: u32, b: u32, c: u32, + memory_store_value: Option, record: MemoryAccessRecord, exit_code: u32, lookup_id: LookupId, syscall_lookup_id: LookupId, ) { - let memory_add_lookup_id = self.record.create_lookup_id(); - let memory_sub_lookup_id = self.record.create_lookup_id(); - let branch_lt_lookup_id = self.record.create_lookup_id(); - let branch_gt_lookup_id = self.record.create_lookup_id(); - let branch_add_lookup_id = self.record.create_lookup_id(); - let jump_jal_lookup_id = self.record.create_lookup_id(); - let jump_jalr_lookup_id = self.record.create_lookup_id(); - let auipc_lookup_id = self.record.create_lookup_id(); - self.record.cpu_events.push(CpuEvent { + let cpu_event = CpuEvent { + shard, clk, pc, next_pc, + instruction, a, a_record: record.a, b, b_record: record.b, c, c_record: record.c, + memory: memory_store_value, memory_record: record.memory, exit_code, alu_lookup_id: lookup_id, syscall_lookup_id, - memory_add_lookup_id, - memory_sub_lookup_id, - branch_lt_lookup_id, - branch_gt_lookup_id, - branch_add_lookup_id, - jump_jal_lookup_id, - jump_jalr_lookup_id, - auipc_lookup_id, - }); + memory_add_lookup_id: create_alu_lookup_id(), + memory_sub_lookup_id: create_alu_lookup_id(), + branch_lt_lookup_id: create_alu_lookup_id(), + branch_gt_lookup_id: create_alu_lookup_id(), + branch_add_lookup_id: create_alu_lookup_id(), + jump_jal_lookup_id: create_alu_lookup_id(), + jump_jalr_lookup_id: create_alu_lookup_id(), + auipc_lookup_id: create_alu_lookup_id(), + }; - emit_cpu_dependencies(self, self.record.cpu_events.len() - 1); + self.record.cpu_events.push(cpu_event); + emit_cpu_dependencies(self, &cpu_event); } /// Emit an ALU event. @@ -648,7 +648,7 @@ impl<'a> Executor<'a> { a, b, c, - sub_lookups: self.record.create_lookup_ids(), + sub_lookups: create_alu_lookups(), }; match opcode { Opcode::ADD => { @@ -696,7 +696,7 @@ impl<'a> Executor<'a> { arg1, arg2, lookup_id, - nonce: self.record.nonce_lookup[lookup_id.0 as usize], + nonce: self.record.nonce_lookup[&lookup_id], } } @@ -725,9 +725,9 @@ impl<'a> Executor<'a> { let (rd, b, c) = (rd, self.rr(rs1, MemoryAccessPosition::B), imm); (rd, b, c) } else { - debug_assert!(instruction.imm_b && instruction.imm_c); + assert!(instruction.imm_b && instruction.imm_c); let (rd, b, c) = - (Register::from_u8(instruction.op_a), instruction.op_b, instruction.op_c); + (Register::from_u32(instruction.op_a), instruction.op_b, instruction.op_c); (rd, b, c) } } @@ -780,7 +780,8 @@ impl<'a> Executor<'a> { /// Fetch the instruction at the current program counter. #[inline] fn fetch(&self) -> Instruction { - *self.program.fetch(self.state.pc) + let idx = ((self.state.pc - self.program.pc_base) / 4) as usize; + self.program.instructions[idx] } /// Execute the given instruction over the current state of the runtime. @@ -792,18 +793,21 @@ impl<'a> Executor<'a> { let mut next_pc = self.state.pc.wrapping_add(4); + let rd: Register; let (a, b, c): (u32, u32, u32); + let (addr, memory_read_value): (u32, u32); + let mut memory_store_value: Option = None; if self.executor_mode == ExecutorMode::Trace { self.memory_accesses = MemoryAccessRecord::default(); } let lookup_id = if self.executor_mode == ExecutorMode::Trace { - self.record.create_lookup_id() + create_alu_lookup_id() } else { LookupId::default() }; let syscall_lookup_id = if self.executor_mode == ExecutorMode::Trace { - self.record.create_lookup_id() + create_alu_lookup_id() } else { LookupId::default() }; @@ -838,40 +842,182 @@ impl<'a> Executor<'a> { match instruction.opcode { // Arithmetic instructions. - Opcode::ADD - | Opcode::SUB - | Opcode::XOR - | Opcode::OR - | Opcode::AND - | Opcode::SLL - | Opcode::SRL - | Opcode::SRA - | Opcode::SLT - | Opcode::SLTU - | Opcode::MUL - | Opcode::MULH - | Opcode::MULHU - | Opcode::MULHSU - | Opcode::DIV - | Opcode::DIVU - | Opcode::REM - | Opcode::REMU => { - (a, b, c) = self.execute_alu(instruction, lookup_id); + Opcode::ADD => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_add(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SUB => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_sub(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::XOR => { + (rd, b, c) = self.alu_rr(instruction); + a = b ^ c; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::OR => { + (rd, b, c) = self.alu_rr(instruction); + a = b | c; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::AND => { + (rd, b, c) = self.alu_rr(instruction); + a = b & c; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SLL => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_shl(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SRL => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_shr(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SRA => { + (rd, b, c) = self.alu_rr(instruction); + a = (b as i32).wrapping_shr(c) as u32; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SLT => { + (rd, b, c) = self.alu_rr(instruction); + a = if (b as i32) < (c as i32) { 1 } else { 0 }; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::SLTU => { + (rd, b, c) = self.alu_rr(instruction); + a = if b < c { 1 } else { 0 }; + self.alu_rw(instruction, rd, a, b, c, lookup_id); } // Load instructions. - Opcode::LB | Opcode::LH | Opcode::LW | Opcode::LBU | Opcode::LHU => { - (a, b, c) = self.execute_load(instruction)?; + Opcode::LB => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + 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); + self.rw(rd, a); + } + Opcode::LH => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LH, addr)); + } + let value = match (addr >> 1) % 2 { + 0 => memory_read_value & 0x0000_FFFF, + 1 => (memory_read_value & 0xFFFF_0000) >> 16, + _ => unreachable!(), + }; + a = ((value as i16) as i32) as u32; + memory_store_value = Some(memory_read_value); + self.rw(rd, a); + } + Opcode::LW => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + if addr % 4 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LW, addr)); + } + a = memory_read_value; + memory_store_value = Some(memory_read_value); + self.rw(rd, a); + } + Opcode::LBU => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + let value = (memory_read_value).to_le_bytes()[(addr % 4) as usize]; + a = value as u32; + memory_store_value = Some(memory_read_value); + self.rw(rd, a); + } + Opcode::LHU => { + (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LHU, addr)); + } + let value = match (addr >> 1) % 2 { + 0 => memory_read_value & 0x0000_FFFF, + 1 => (memory_read_value & 0xFFFF_0000) >> 16, + _ => unreachable!(), + }; + a = (value as u16) as u32; + memory_store_value = Some(memory_read_value); + self.rw(rd, a); } // Store instructions. - Opcode::SB | Opcode::SH | Opcode::SW => { - (a, b, c) = self.execute_store(instruction)?; + Opcode::SB => { + (a, b, c, addr, memory_read_value) = self.store_rr(instruction); + let value = match addr % 4 { + 0 => (a & 0x0000_00FF) + (memory_read_value & 0xFFFF_FF00), + 1 => ((a & 0x0000_00FF) << 8) + (memory_read_value & 0xFFFF_00FF), + 2 => ((a & 0x0000_00FF) << 16) + (memory_read_value & 0xFF00_FFFF), + 3 => ((a & 0x0000_00FF) << 24) + (memory_read_value & 0x00FF_FFFF), + _ => unreachable!(), + }; + memory_store_value = Some(value); + self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); + } + Opcode::SH => { + (a, b, c, addr, memory_read_value) = self.store_rr(instruction); + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::SH, addr)); + } + let value = match (addr >> 1) % 2 { + 0 => (a & 0x0000_FFFF) + (memory_read_value & 0xFFFF_0000), + 1 => ((a & 0x0000_FFFF) << 16) + (memory_read_value & 0x0000_FFFF), + _ => unreachable!(), + }; + memory_store_value = Some(value); + self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); + } + Opcode::SW => { + (a, b, c, addr, _) = self.store_rr(instruction); + if addr % 4 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::SW, addr)); + } + let value = a; + memory_store_value = Some(value); + self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); } - // Branch instructions. - Opcode::BEQ | Opcode::BNE | Opcode::BLT | Opcode::BGE | Opcode::BLTU | Opcode::BGEU => { - (a, b, c, next_pc) = self.execute_branch(instruction, next_pc); + // B-type instructions. + Opcode::BEQ => { + (a, b, c) = self.branch_rr(instruction); + if a == b { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BNE => { + (a, b, c) = self.branch_rr(instruction); + if a != b { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BLT => { + (a, b, c) = self.branch_rr(instruction); + if (a as i32) < (b as i32) { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BGE => { + (a, b, c) = self.branch_rr(instruction); + if (a as i32) >= (b as i32) { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BLTU => { + (a, b, c) = self.branch_rr(instruction); + if a < b { + next_pc = self.state.pc.wrapping_add(c); + } + } + Opcode::BGEU => { + (a, b, c) = self.branch_rr(instruction); + if a >= b { + next_pc = self.state.pc.wrapping_add(c); + } } // Jump instructions. @@ -934,7 +1080,7 @@ impl<'a> Executor<'a> { _ => (self.opts.split_opts.deferred, 1), }; let nonce = (((*syscall_count as usize) % threshold) * multiplier) as u32; - self.record.nonce_lookup[syscall_lookup_id.0 as usize] = nonce; + self.record.nonce_lookup.insert(syscall_lookup_id, nonce); *syscall_count += 1; let syscall_impl = self.get_syscall(syscall).cloned(); @@ -984,181 +1130,95 @@ impl<'a> Executor<'a> { return Err(ExecutionError::Breakpoint()); } - // See https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#instruction-aliases - Opcode::UNIMP => { - return Err(ExecutionError::Unimplemented()); + // Multiply instructions. + Opcode::MUL => { + (rd, b, c) = self.alu_rr(instruction); + a = b.wrapping_mul(c); + self.alu_rw(instruction, rd, a, b, c, lookup_id); } - } - - // Update the program counter. - self.state.pc = next_pc; - - // Update the clk to the next cycle. - self.state.clk += 4; - - // Emit the CPU event for this cycle. - if self.executor_mode == ExecutorMode::Trace { - self.emit_cpu( - clk, - pc, - next_pc, - a, - b, - c, - self.memory_accesses, - exit_code, - lookup_id, - syscall_lookup_id, - ); - }; - Ok(()) - } - - fn execute_alu(&mut self, instruction: &Instruction, lookup_id: LookupId) -> (u32, u32, u32) { - let (rd, b, c) = self.alu_rr(instruction); - let a = match instruction.opcode { - Opcode::ADD => b.wrapping_add(c), - Opcode::SUB => b.wrapping_sub(c), - Opcode::XOR => b ^ c, - Opcode::OR => b | c, - Opcode::AND => b & c, - Opcode::SLL => b.wrapping_shl(c), - Opcode::SRL => b.wrapping_shr(c), - Opcode::SRA => (b as i32).wrapping_shr(c) as u32, - Opcode::SLT => { - if (b as i32) < (c as i32) { - 1 - } else { - 0 - } + Opcode::MULH => { + (rd, b, c) = self.alu_rr(instruction); + a = (((b as i32) as i64).wrapping_mul((c as i32) as i64) >> 32) as u32; + self.alu_rw(instruction, rd, a, b, c, lookup_id); } - Opcode::SLTU => { - if b < c { - 1 - } else { - 0 - } + Opcode::MULHU => { + (rd, b, c) = self.alu_rr(instruction); + a = ((b as u64).wrapping_mul(c as u64) >> 32) as u32; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + } + Opcode::MULHSU => { + (rd, b, c) = self.alu_rr(instruction); + a = (((b as i32) as i64).wrapping_mul(c as i64) >> 32) as u32; + self.alu_rw(instruction, rd, a, b, c, lookup_id); } - Opcode::MUL => b.wrapping_mul(c), - Opcode::MULH => (((b as i32) as i64).wrapping_mul((c as i32) as i64) >> 32) as u32, - Opcode::MULHU => ((b as u64).wrapping_mul(c as u64) >> 32) as u32, - Opcode::MULHSU => (((b as i32) as i64).wrapping_mul(c as i64) >> 32) as u32, Opcode::DIV => { + (rd, b, c) = self.alu_rr(instruction); if c == 0 { - u32::MAX + a = u32::MAX; } else { - (b as i32).wrapping_div(c as i32) as u32 + a = (b as i32).wrapping_div(c as i32) as u32; } + self.alu_rw(instruction, rd, a, b, c, lookup_id); } Opcode::DIVU => { + (rd, b, c) = self.alu_rr(instruction); if c == 0 { - u32::MAX + a = u32::MAX; } else { - b.wrapping_div(c) + a = b.wrapping_div(c); } + self.alu_rw(instruction, rd, a, b, c, lookup_id); } Opcode::REM => { + (rd, b, c) = self.alu_rr(instruction); if c == 0 { - b + a = b; } else { - (b as i32).wrapping_rem(c as i32) as u32 + a = (b as i32).wrapping_rem(c as i32) as u32; } + self.alu_rw(instruction, rd, a, b, c, lookup_id); } Opcode::REMU => { + (rd, b, c) = self.alu_rr(instruction); if c == 0 { - b + a = b; } else { - b.wrapping_rem(c) + a = b.wrapping_rem(c); } + self.alu_rw(instruction, rd, a, b, c, lookup_id); } - _ => unreachable!(), - }; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - (a, b, c) - } - fn execute_load( - &mut self, - instruction: &Instruction, - ) -> Result<(u32, u32, u32), ExecutionError> { - let (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - let a = match instruction.opcode { - Opcode::LB => ((memory_read_value >> ((addr % 4) * 8)) & 0xFF) as i8 as i32 as u32, - Opcode::LH => { - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LH, addr)); - } - ((memory_read_value >> (((addr / 2) % 2) * 16)) & 0xFFFF) as i16 as i32 as u32 - } - Opcode::LW => { - if addr % 4 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LW, addr)); - } - memory_read_value - } - Opcode::LBU => (memory_read_value >> ((addr % 4) * 8)) & 0xFF, - Opcode::LHU => { - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LHU, addr)); - } - (memory_read_value >> (((addr / 2) % 2) * 16)) & 0xFFFF + // See https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#instruction-aliases + Opcode::UNIMP => { + return Err(ExecutionError::Unimplemented()); } - _ => unreachable!(), - }; - self.rw(rd, a); - Ok((a, b, c)) - } + } - fn execute_store( - &mut self, - instruction: &Instruction, - ) -> Result<(u32, u32, u32), ExecutionError> { - let (a, b, c, addr, memory_read_value) = self.store_rr(instruction); - let memory_store_value = match instruction.opcode { - Opcode::SB => { - let shift = (addr % 4) * 8; - ((a & 0xFF) << shift) | (memory_read_value & !(0xFF << shift)) - } - Opcode::SH => { - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::SH, addr)); - } - let shift = ((addr / 2) % 2) * 16; - ((a & 0xFFFF) << shift) | (memory_read_value & !(0xFFFF << shift)) - } - Opcode::SW => { - if addr % 4 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::SW, addr)); - } - a - } - _ => unreachable!(), - }; - self.mw_cpu(align(addr), memory_store_value, MemoryAccessPosition::Memory); - Ok((a, b, c)) - } + // Update the program counter. + self.state.pc = next_pc; - fn execute_branch( - &mut self, - instruction: &Instruction, - mut next_pc: u32, - ) -> (u32, u32, u32, u32) { - let (a, b, c) = self.branch_rr(instruction); - let branch = match instruction.opcode { - Opcode::BEQ => a == b, - Opcode::BNE => a != b, - Opcode::BLT => (a as i32) < (b as i32), - Opcode::BGE => (a as i32) >= (b as i32), - Opcode::BLTU => a < b, - Opcode::BGEU => a >= b, - _ => { - unreachable!() - } + // Update the clk to the next cycle. + self.state.clk += 4; + + // Emit the CPU event for this cycle. + if self.executor_mode == ExecutorMode::Trace { + self.emit_cpu( + self.shard(), + clk, + pc, + next_pc, + *instruction, + a, + b, + c, + memory_store_value, + self.memory_accesses, + exit_code, + lookup_id, + syscall_lookup_id, + ); }; - if branch { - next_pc = self.state.pc.wrapping_add(c); - } - (a, b, c, next_pc) + Ok(()) } /// Executes one cycle of the program, returning whether the program has finished. @@ -1337,7 +1397,6 @@ impl<'a> Executor<'a> { std::mem::replace(&mut self.record, ExecutionRecord::new(self.program.clone())); let public_values = removed_record.public_values; self.record.public_values = public_values; - self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; self.records.push(removed_record); } @@ -1412,8 +1471,6 @@ impl<'a> Executor<'a> { } fn initialize(&mut self) { - self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; - self.state.clk = 0; tracing::debug!("loading memory image"); @@ -1449,11 +1506,6 @@ impl<'a> Executor<'a> { /// Executes up to `self.shard_batch_size` cycles of the program, returning whether the program /// has finished. pub fn execute(&mut self) -> Result { - // Initialize the nonce lookup table if it's uninitialized. - if self.record.nonce_lookup.len() <= 2 { - self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; - } - // Get the program. let program = self.program.clone(); diff --git a/crates/core/executor/src/instruction.rs b/crates/core/executor/src/instruction.rs index 10dfa5476d..bc1df27ba0 100644 --- a/crates/core/executor/src/instruction.rs +++ b/crates/core/executor/src/instruction.rs @@ -15,7 +15,7 @@ pub struct Instruction { /// The operation to execute. pub opcode: Opcode, /// The first operand. - pub op_a: u8, + pub op_a: u32, /// The second operand. pub op_b: u32, /// The third operand. @@ -31,7 +31,7 @@ impl Instruction { #[must_use] pub const fn new( opcode: Opcode, - op_a: u8, + op_a: u32, op_b: u32, op_c: u32, imm_b: bool, diff --git a/crates/core/executor/src/memory.rs b/crates/core/executor/src/memory.rs index a036bbf5ca..6e375753d4 100644 --- a/crates/core/executor/src/memory.rs +++ b/crates/core/executor/src/memory.rs @@ -11,10 +11,10 @@ impl Default for Page { } } -const LOG_PAGE_LEN: usize = 14; +const LOG_PAGE_LEN: usize = 15; const PAGE_LEN: usize = 1 << LOG_PAGE_LEN; const MAX_PAGE_COUNT: usize = ((1 << 31) - (1 << 27)) / 4 / PAGE_LEN + 1; -const NO_PAGE: u16 = u16::MAX; +const NO_PAGE: usize = usize::MAX; const PAGE_MASK: usize = PAGE_LEN - 1; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -41,7 +41,7 @@ impl Default for NewPage { pub struct PagedMemory { /// The internal page table. pub page_table: Vec>, - pub index: Vec, + pub index: Vec, } impl PagedMemory { @@ -50,7 +50,8 @@ impl PagedMemory { /// The number of registers in the virtual machine. const NUM_REGISTERS: usize = 32; /// The offset subtracted from the main address space to make it contiguous. - const ADDR_COMPRESS_OFFSET: usize = Self::NUM_REGISTERS; + const ADDR_COMPRESS_OFFSET: usize = + Self::NUM_REGISTERS - (Self::NUM_REGISTERS >> Self::NUM_IGNORED_LOWER_BITS); /// Create a `PagedMemory` with capacity `MAX_PAGE_COUNT`. pub fn new_preallocated() -> Self { @@ -64,7 +65,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index as usize].0[lower].as_ref() + self.page_table[index].0[lower].as_ref() } } @@ -75,7 +76,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index as usize].0[lower].as_mut() + self.page_table[index].0[lower].as_mut() } } @@ -84,11 +85,11 @@ impl PagedMemory { let (upper, lower) = Self::indices(addr); let mut index = self.index[upper]; if index == NO_PAGE { - index = self.page_table.len() as u16; + index = self.page_table.len(); self.index[upper] = index; self.page_table.push(NewPage::new()); } - self.page_table[index as usize].0[lower].replace(value) + self.page_table[index].0[lower].replace(value) } /// Remove the value at the given address if it exists, returning it. @@ -98,7 +99,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index as usize].0[lower].take() + self.page_table[index].0[lower].take() } } @@ -108,11 +109,11 @@ impl PagedMemory { let index = self.index[upper]; if index == NO_PAGE { let index = self.page_table.len(); - self.index[upper] = index as u16; + self.index[upper] = index; self.page_table.push(NewPage::new()); Entry::Vacant(VacantEntry { entry: &mut self.page_table[index].0[lower] }) } else { - let option = &mut self.page_table[index as usize].0[lower]; + let option = &mut self.page_table[index].0[lower]; match option { Some(_) => Entry::Occupied(OccupiedEntry { entry: option }), None => Entry::Vacant(VacantEntry { entry: option }), @@ -124,7 +125,7 @@ impl PagedMemory { pub fn keys(&self) -> impl Iterator + '_ { self.index.iter().enumerate().filter(|(_, &i)| i != NO_PAGE).flat_map(|(i, index)| { let upper = i << LOG_PAGE_LEN; - self.page_table[*index as usize] + self.page_table[*index] .0 .iter() .enumerate() @@ -274,7 +275,7 @@ impl IntoIterator for PagedMemory { move |(i, index)| { let upper = i << LOG_PAGE_LEN; let replacement = NewPage::new(); - std::mem::replace(&mut self.page_table[index as usize], replacement) + std::mem::replace(&mut self.page_table[index], replacement) .0 .into_iter() .enumerate() diff --git a/crates/core/executor/src/opcode.rs b/crates/core/executor/src/opcode.rs index 818b5b1f2b..6d0589ca91 100644 --- a/crates/core/executor/src/opcode.rs +++ b/crates/core/executor/src/opcode.rs @@ -100,7 +100,7 @@ pub enum Opcode { /// rd ← rs1 % rs2 (unsigned), pc ← pc + 4 REMU = 37, /// Unimplemented instruction. - UNIMP = 38, + UNIMP = 39, } /// Byte Opcode. diff --git a/crates/core/executor/src/program.rs b/crates/core/executor/src/program.rs index 09bb70cac4..29743a4c8f 100644 --- a/crates/core/executor/src/program.rs +++ b/crates/core/executor/src/program.rs @@ -89,13 +89,6 @@ impl Program { }) .copied() } - - #[must_use] - /// Fetch the instruction at the given program counter. - pub fn fetch(&self, pc: u32) -> &Instruction { - let idx = ((pc - self.pc_base) / 4) as usize; - &self.instructions[idx] - } } impl MachineProgram for Program { diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index f9e89acb4c..b6c23c45f8 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -23,7 +23,7 @@ use crate::{ /// A record of the execution of a program. /// /// The trace of the execution is represented as a list of "events" that occur every cycle. -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Default, Clone, Debug, Serialize, Deserialize)] pub struct ExecutionRecord { /// The program. pub program: Arc, @@ -60,63 +60,16 @@ pub struct ExecutionRecord { /// The public values. pub public_values: PublicValues, /// The nonce lookup. - pub nonce_lookup: Vec, - /// The next nonce to use for a new lookup. - pub next_nonce: u64, + pub nonce_lookup: HashMap, /// The shape of the proof. pub shape: Option, } -impl Default for ExecutionRecord { - fn default() -> Self { - let mut res = Self { - program: Arc::default(), - cpu_events: Vec::default(), - add_events: Vec::default(), - mul_events: Vec::default(), - sub_events: Vec::default(), - bitwise_events: Vec::default(), - shift_left_events: Vec::default(), - shift_right_events: Vec::default(), - divrem_events: Vec::default(), - lt_events: Vec::default(), - byte_lookups: HashMap::default(), - precompile_events: PrecompileEvents::default(), - global_memory_initialize_events: Vec::default(), - global_memory_finalize_events: Vec::default(), - cpu_local_memory_access: Vec::default(), - syscall_events: Vec::default(), - public_values: PublicValues::default(), - nonce_lookup: Vec::default(), - next_nonce: 0, - shape: None, - }; - res.nonce_lookup.insert(0, 0); - res - } -} - impl ExecutionRecord { /// Create a new [`ExecutionRecord`]. #[must_use] pub fn new(program: Arc) -> Self { - let mut res = Self { program, ..Default::default() }; - res.nonce_lookup.insert(0, 0); - res - } - - /// Create a lookup id for an event. - pub fn create_lookup_id(&mut self) -> LookupId { - // let id = self.nonce_lookup.len() as u64; - let id = self.next_nonce; - self.next_nonce += 1; - // self.nonce_lookup.insert(id as usize, 0); - LookupId(id) - } - - /// Create 6 lookup ids for an ALU event. - pub fn create_lookup_ids(&mut self) -> [LookupId; 6] { - std::array::from_fn(|_| self.create_lookup_id()) + Self { program, ..Default::default() } } /// Add a mul event to the execution record. @@ -346,7 +299,7 @@ impl MachineRecord for ExecutionRecord { ); stats.insert("local_memory_access_events".to_string(), self.cpu_local_memory_access.len()); if !self.cpu_events.is_empty() { - let shard = self.public_values.shard; + let shard = self.cpu_events[0].shard; stats.insert( "byte_lookups".to_string(), self.byte_lookups.get(&shard).map_or(0, hashbrown::HashMap::len), @@ -384,35 +337,35 @@ impl MachineRecord for ExecutionRecord { fn register_nonces(&mut self, _opts: &Self::Config) { self.add_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.sub_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = (self.add_events.len() + i) as u32; + self.nonce_lookup.insert(event.lookup_id, (self.add_events.len() + i) as u32); }); self.mul_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.bitwise_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.shift_left_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.shift_right_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.divrem_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); self.lt_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; + self.nonce_lookup.insert(event.lookup_id, i as u32); }); } diff --git a/crates/core/executor/src/register.rs b/crates/core/executor/src/register.rs index c24b75decc..176ef1c951 100644 --- a/crates/core/executor/src/register.rs +++ b/crates/core/executor/src/register.rs @@ -70,14 +70,14 @@ pub enum Register { } impl Register { - /// Create a new register from a u8. + /// Create a new register from a u32. /// /// # Panics /// /// This function will panic if the register is invalid. #[inline] #[must_use] - pub fn from_u8(value: u8) -> Self { + pub fn from_u32(value: u32) -> Self { match value { 0 => Register::X0, 1 => Register::X1, diff --git a/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs b/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs index 1d4a2a769e..36f1b56542 100644 --- a/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs +++ b/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs @@ -22,11 +22,11 @@ impl Syscall for Sha256ExtendSyscall { assert!(arg2 == 0, "arg2 must be 0"); let w_ptr_init = w_ptr; - let mut w_i_minus_15_reads = Vec::with_capacity(48); - let mut w_i_minus_2_reads = Vec::with_capacity(48); - let mut w_i_minus_16_reads = Vec::with_capacity(48); - let mut w_i_minus_7_reads = Vec::with_capacity(48); - let mut w_i_writes = Vec::with_capacity(48); + let mut w_i_minus_15_reads = Vec::new(); + let mut w_i_minus_2_reads = Vec::new(); + let mut w_i_minus_16_reads = Vec::new(); + let mut w_i_minus_7_reads = Vec::new(); + let mut w_i_writes = Vec::new(); for i in 16..64 { // Read w[i-15]. let (record, w_i_minus_15) = rt.mr(w_ptr + (i - 15) * 4); diff --git a/crates/core/machine/Cargo.toml b/crates/core/machine/Cargo.toml index 3b0b0f34f9..7e2bd5a50a 100644 --- a/crates/core/machine/Cargo.toml +++ b/crates/core/machine/Cargo.toml @@ -54,7 +54,6 @@ static_assertions = "1.1.0" sp1-stark = { workspace = true } sp1-core-executor = { workspace = true } sp1-curves = { workspace = true } -vec_map = "0.8.2" [dev-dependencies] tiny-keccak = { version = "2.0.2", features = ["keccak"] } diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index d276820755..bf6dabef42 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ events::{AluEvent, ByteLookupEvent, ByteRecord}, ExecutionRecord, Opcode, Program, @@ -19,10 +19,7 @@ use sp1_stark::{ Word, }; -use crate::{ - operations::AddOperation, - utils::{next_power_of_two, zeroed_f_vec}, -}; +use crate::{operations::AddOperation, utils::pad_rows_fixed}; /// The number of main trace columns for `AddSubChip`. pub const NUM_ADD_SUB_COLS: usize = size_of::>(); @@ -82,29 +79,46 @@ impl MachineAir for AddSubChip { std::cmp::max((input.add_events.len() + input.sub_events.len()) / num_cpus::get(), 1); let merged_events = input.add_events.iter().chain(input.sub_events.iter()).collect::>(); - let nb_rows = merged_events.len(); - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_ADD_SUB_COLS); - - values.chunks_mut(chunk_size * NUM_ADD_SUB_COLS).enumerate().par_bridge().for_each( - |(i, rows)| { - rows.chunks_mut(NUM_ADD_SUB_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - let cols: &mut AddSubCols = row.borrow_mut(); - - if idx < merged_events.len() { - let mut byte_lookup_events = Vec::new(); - let event = &merged_events[idx]; - self.event_to_row(event, cols, &mut byte_lookup_events); - } - cols.nonce = F::from_canonical_usize(idx); - }); - }, - ); + let row_batches = merged_events + .par_chunks(chunk_size) + .map(|events| { + let rows = events + .iter() + .map(|event| { + let mut row = [F::zero(); NUM_ADD_SUB_COLS]; + let cols: &mut AddSubCols = row.as_mut_slice().borrow_mut(); + let mut blu = Vec::new(); + self.event_to_row(event, cols, &mut blu); + row + }) + .collect::>(); + rows + }) + .collect::>(); + + let mut rows: Vec<[F; NUM_ADD_SUB_COLS]> = vec![]; + for row_batch in row_batches { + rows.extend(row_batch); + } + + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_ADD_SUB_COLS], + input.fixed_log2_rows::(self), + ); // Convert the trace to a row major matrix. - RowMajorMatrix::new(values, NUM_ADD_SUB_COLS) + let mut trace = + RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_ADD_SUB_COLS); + + // Write the nonces to the trace. + for i in 0..trace.height() { + let cols: &mut AddSubCols = + trace.values[i * NUM_ADD_SUB_COLS..(i + 1) * NUM_ADD_SUB_COLS].borrow_mut(); + cols.nonce = F::from_canonical_usize(i); + } + + trace } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index 1d4d539fc4..9170b87b5f 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -279,19 +279,11 @@ impl MachineAir for DivRemChip { // Set the `alu_event` flags. cols.abs_c_alu_event = cols.c_neg * cols.is_real; cols.abs_c_alu_event_nonce = F::from_canonical_u32( - input - .nonce_lookup - .get(event.sub_lookups[4].0 as usize) - .copied() - .unwrap_or_default(), + input.nonce_lookup.get(&event.sub_lookups[4]).copied().unwrap_or_default(), ); cols.abs_rem_alu_event = cols.rem_neg * cols.is_real; cols.abs_rem_alu_event_nonce = F::from_canonical_u32( - input - .nonce_lookup - .get(event.sub_lookups[5].0 as usize) - .copied() - .unwrap_or_default(), + input.nonce_lookup.get(&event.sub_lookups[5]).copied().unwrap_or_default(), ); // Insert the MSB lookup events. @@ -352,24 +344,16 @@ impl MachineAir for DivRemChip { // Insert the necessary multiplication & LT events. { cols.lower_nonce = F::from_canonical_u32( - input - .nonce_lookup - .get(event.sub_lookups[0].0 as usize) - .copied() - .unwrap_or_default(), + input.nonce_lookup.get(&event.sub_lookups[0]).copied().unwrap_or_default(), ); cols.upper_nonce = F::from_canonical_u32( - input - .nonce_lookup - .get(event.sub_lookups[1].0 as usize) - .copied() - .unwrap_or_default(), + input.nonce_lookup.get(&event.sub_lookups[1]).copied().unwrap_or_default(), ); if is_signed_operation(event.opcode) { cols.abs_nonce = F::from_canonical_u32( input .nonce_lookup - .get(event.sub_lookups[2].0 as usize) + .get(&event.sub_lookups[2]) .copied() .unwrap_or_default(), ); @@ -377,7 +361,7 @@ impl MachineAir for DivRemChip { cols.abs_nonce = F::from_canonical_u32( input .nonce_lookup - .get(event.sub_lookups[3].0 as usize) + .get(&event.sub_lookups[3]) .copied() .unwrap_or_default(), ); diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index 876fdaaf8f..211cf5d912 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -19,7 +19,7 @@ use sp1_stark::{ Word, }; -use crate::utils::{next_power_of_two, zeroed_f_vec}; +use crate::utils::pad_rows_fixed; /// The number of main trace columns for `LtChip`. pub const NUM_LT_COLS: usize = size_of::>(); @@ -107,31 +107,38 @@ impl MachineAir for LtChip { _: &mut ExecutionRecord, ) -> RowMajorMatrix { // Generate the trace rows for each event. - let nb_rows = input.lt_events.len(); - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_LT_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values.chunks_mut(chunk_size * NUM_LT_COLS).enumerate().par_bridge().for_each( - |(i, rows)| { - rows.chunks_mut(NUM_LT_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - let cols: &mut LtCols = row.borrow_mut(); - - if idx < nb_rows { - let mut byte_lookup_events = Vec::new(); - let event = &input.lt_events[idx]; - self.event_to_row(event, cols, &mut byte_lookup_events); - } - cols.nonce = F::from_canonical_usize(idx); - }); - }, + let mut rows = input + .lt_events + .par_iter() + .map(|event| { + let mut row = [F::zero(); NUM_LT_COLS]; + let mut new_byte_lookup_events: Vec = Vec::new(); + let cols: &mut LtCols = row.as_mut_slice().borrow_mut(); + self.event_to_row(event, cols, &mut new_byte_lookup_events); + + row + }) + .collect::>(); + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_LT_COLS], + input.fixed_log2_rows::(self), ); // Convert the trace to a row major matrix. + let mut trace = + RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_LT_COLS); + + // Write the nonces to the trace. + for i in 0..trace.height() { + let cols: &mut LtCols = + trace.values[i * NUM_LT_COLS..(i + 1) * NUM_LT_COLS].borrow_mut(); + cols.nonce = F::from_canonical_usize(i); + } - RowMajorMatrix::new(values, NUM_LT_COLS) + trace } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index 6a1ce272fe..0453cb5f87 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -35,24 +35,19 @@ use core::{ mem::size_of, }; -use hashbrown::HashMap; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{AluEvent, ByteLookupEvent, ByteRecord}, + events::{ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; use sp1_primitives::consts::WORD_SIZE; -use sp1_stark::{air::MachineAir, Word}; +use sp1_stark::{air::MachineAir, MachineRecord, Word}; -use crate::{ - air::SP1CoreAirBuilder, - alu::mul::utils::get_msb, - utils::{next_power_of_two, zeroed_f_vec}, -}; +use crate::{air::SP1CoreAirBuilder, alu::mul::utils::get_msb, utils::pad_rows_fixed}; /// The number of main trace columns for `MulChip`. pub const NUM_MUL_COLS: usize = size_of::>(); @@ -136,54 +131,148 @@ impl MachineAir for MulChip { fn generate_trace( &self, input: &ExecutionRecord, - _: &mut ExecutionRecord, + output: &mut ExecutionRecord, ) -> RowMajorMatrix { - // Generate the trace rows for each event. - let nb_rows = input.mul_events.len(); - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_MUL_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values.chunks_mut(chunk_size * NUM_MUL_COLS).enumerate().par_bridge().for_each( - |(i, rows)| { - rows.chunks_mut(NUM_MUL_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - let cols: &mut MulCols = row.borrow_mut(); - - if idx < nb_rows { - let mut byte_lookup_events = Vec::new(); - let event = &input.mul_events[idx]; - self.event_to_row(event, cols, &mut byte_lookup_events); - } - cols.nonce = F::from_canonical_usize(idx); - }); - }, - ); + let mul_events = input.mul_events.clone(); + // Compute the chunk size based on the number of events and the number of CPUs. + let chunk_size = std::cmp::max(mul_events.len() / num_cpus::get(), 1); - // Convert the trace to a row major matrix. - - RowMajorMatrix::new(values, NUM_MUL_COLS) - } - - fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { - let chunk_size = std::cmp::max(input.mul_events.len() / num_cpus::get(), 1); - - let blu_batches = input - .mul_events + // Generate the trace rows & corresponding records for each chunk of events in parallel. + let rows_and_records = mul_events .par_chunks(chunk_size) .map(|events| { - let mut blu: HashMap> = HashMap::new(); - events.iter().for_each(|event| { - let mut row = [F::zero(); NUM_MUL_COLS]; - let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); - self.event_to_row(event, cols, &mut blu); - }); - blu + let mut record = ExecutionRecord::default(); + let rows = events + .iter() + .map(|event| { + // Ensure that the opcode is MUL, MULHU, MULH, or MULHSU. + assert!( + event.opcode == Opcode::MUL + || event.opcode == Opcode::MULHU + || event.opcode == Opcode::MULH + || event.opcode == Opcode::MULHSU + ); + let mut row = [F::zero(); NUM_MUL_COLS]; + let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); + + let a_word = event.a.to_le_bytes(); + let b_word = event.b.to_le_bytes(); + let c_word = event.c.to_le_bytes(); + + let mut b = b_word.to_vec(); + let mut c = c_word.to_vec(); + + // Handle b and c's signs. + { + let b_msb = get_msb(b_word); + cols.b_msb = F::from_canonical_u8(b_msb); + let c_msb = get_msb(c_word); + cols.c_msb = F::from_canonical_u8(c_msb); + + // If b is signed and it is negative, sign extend b. + if (event.opcode == Opcode::MULH || event.opcode == Opcode::MULHSU) + && b_msb == 1 + { + cols.b_sign_extend = F::one(); + b.resize(PRODUCT_SIZE, BYTE_MASK); + } + + // If c is signed and it is negative, sign extend c. + if event.opcode == Opcode::MULH && c_msb == 1 { + cols.c_sign_extend = F::one(); + c.resize(PRODUCT_SIZE, BYTE_MASK); + } + + // Insert the MSB lookup events. + { + let words = [b_word, c_word]; + let mut blu_events: Vec = vec![]; + for word in words.iter() { + let most_significant_byte = word[WORD_SIZE - 1]; + blu_events.push(ByteLookupEvent { + shard: event.shard, + opcode: ByteOpcode::MSB, + a1: get_msb(*word) as u16, + a2: 0, + b: most_significant_byte, + c: 0, + }); + } + record.add_byte_lookup_events(blu_events); + } + } + + let mut product = [0u32; PRODUCT_SIZE]; + for i in 0..b.len() { + for j in 0..c.len() { + if i + j < PRODUCT_SIZE { + product[i + j] += (b[i] as u32) * (c[j] as u32); + } + } + } + + // Calculate the correct product using the `product` array. We store the + // correct carry value for verification. + let base = (1 << BYTE_SIZE) as u32; + let mut carry = [0u32; PRODUCT_SIZE]; + for i in 0..PRODUCT_SIZE { + carry[i] = product[i] / base; + product[i] %= base; + if i + 1 < PRODUCT_SIZE { + product[i + 1] += carry[i]; + } + cols.carry[i] = F::from_canonical_u32(carry[i]); + } + + cols.product = product.map(F::from_canonical_u32); + cols.a = Word(a_word.map(F::from_canonical_u8)); + cols.b = Word(b_word.map(F::from_canonical_u8)); + cols.c = Word(c_word.map(F::from_canonical_u8)); + cols.is_real = F::one(); + cols.is_mul = F::from_bool(event.opcode == Opcode::MUL); + cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); + cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); + cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); + cols.shard = F::from_canonical_u32(event.shard); + + // Range check. + { + record.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); + record.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); + } + row + }) + .collect::>(); + (rows, record) }) .collect::>(); - output.add_sharded_byte_lookup_events(blu_batches.iter().collect::>()); + // Generate the trace rows for each event. + let mut rows: Vec<[F; NUM_MUL_COLS]> = vec![]; + for mut row_and_record in rows_and_records { + rows.extend(row_and_record.0); + output.append(&mut row_and_record.1); + } + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_MUL_COLS], + input.fixed_log2_rows::(self), + ); + + // Convert the trace to a row major matrix. + let mut trace = + RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_MUL_COLS); + + // Write the nonces to the trace. + for i in 0..trace.height() { + let cols: &mut MulCols = + trace.values[i * NUM_MUL_COLS..(i + 1) * NUM_MUL_COLS].borrow_mut(); + cols.nonce = F::from_canonical_usize(i); + } + + trace } fn included(&self, shard: &Self::Record) -> bool { @@ -195,100 +284,6 @@ impl MachineAir for MulChip { } } -impl MulChip { - /// Create a row from an event. - fn event_to_row( - &self, - event: &AluEvent, - cols: &mut MulCols, - blu: &mut impl ByteRecord, - ) { - let a_word = event.a.to_le_bytes(); - let b_word = event.b.to_le_bytes(); - let c_word = event.c.to_le_bytes(); - - let mut b = b_word.to_vec(); - let mut c = c_word.to_vec(); - - // Handle b and c's signs. - { - let b_msb = get_msb(b_word); - cols.b_msb = F::from_canonical_u8(b_msb); - let c_msb = get_msb(c_word); - cols.c_msb = F::from_canonical_u8(c_msb); - - // If b is signed and it is negative, sign extend b. - if (event.opcode == Opcode::MULH || event.opcode == Opcode::MULHSU) && b_msb == 1 { - cols.b_sign_extend = F::one(); - b.resize(PRODUCT_SIZE, BYTE_MASK); - } - - // If c is signed and it is negative, sign extend c. - if event.opcode == Opcode::MULH && c_msb == 1 { - cols.c_sign_extend = F::one(); - c.resize(PRODUCT_SIZE, BYTE_MASK); - } - - // Insert the MSB lookup events. - { - let words = [b_word, c_word]; - let mut blu_events: Vec = vec![]; - for word in words.iter() { - let most_significant_byte = word[WORD_SIZE - 1]; - blu_events.push(ByteLookupEvent { - shard: event.shard, - opcode: ByteOpcode::MSB, - a1: get_msb(*word) as u16, - a2: 0, - b: most_significant_byte, - c: 0, - }); - } - blu.add_byte_lookup_events(blu_events); - } - } - - let mut product = [0u32; PRODUCT_SIZE]; - for i in 0..b.len() { - for j in 0..c.len() { - if i + j < PRODUCT_SIZE { - product[i + j] += (b[i] as u32) * (c[j] as u32); - } - } - } - - // Calculate the correct product using the `product` array. We store the - // correct carry value for verification. - let base = (1 << BYTE_SIZE) as u32; - let mut carry = [0u32; PRODUCT_SIZE]; - for i in 0..PRODUCT_SIZE { - carry[i] = product[i] / base; - product[i] %= base; - if i + 1 < PRODUCT_SIZE { - product[i + 1] += carry[i]; - } - cols.carry[i] = F::from_canonical_u32(carry[i]); - } - - cols.product = product.map(F::from_canonical_u32); - cols.a = Word(a_word.map(F::from_canonical_u8)); - cols.b = Word(b_word.map(F::from_canonical_u8)); - cols.c = Word(c_word.map(F::from_canonical_u8)); - cols.is_real = F::one(); - cols.is_mul = F::from_bool(event.opcode == Opcode::MUL); - cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); - cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); - cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); - cols.shard = F::from_canonical_u32(event.shard); - - // Range check. - { - blu.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); - blu.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); - } - } -} - impl BaseAir for MulChip { fn width(&self) -> usize { NUM_MUL_COLS diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index b26c949945..9c19b4491c 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -52,7 +52,7 @@ use itertools::Itertools; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; use sp1_core_executor::{ events::{AluEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, @@ -65,7 +65,7 @@ use crate::{ air::SP1CoreAirBuilder, alu::sr::utils::{nb_bits_to_shift, nb_bytes_to_shift}, bytes::utils::shr_carry, - utils::{next_power_of_two, zeroed_f_vec}, + utils::pad_rows_fixed, }; /// The number of main trace columns for `ShiftRightChip`. @@ -149,33 +149,54 @@ impl MachineAir for ShiftRightChip { _: &mut ExecutionRecord, ) -> RowMajorMatrix { // Generate the trace rows for each event. - let nb_rows = input.shift_right_events.len(); - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_SHIFT_RIGHT_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values.chunks_mut(chunk_size * NUM_SHIFT_RIGHT_COLS).enumerate().par_bridge().for_each( - |(i, rows)| { - rows.chunks_mut(NUM_SHIFT_RIGHT_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - let cols: &mut ShiftRightCols = row.borrow_mut(); - - if idx < nb_rows { - let mut byte_lookup_events = Vec::new(); - let event = &input.shift_right_events[idx]; - self.event_to_row(event, cols, &mut byte_lookup_events); - } else { - cols.shift_by_n_bits[0] = F::one(); - cols.shift_by_n_bytes[0] = F::one(); - } - cols.nonce = F::from_canonical_usize(idx); - }); - }, + let mut rows: Vec<[F; NUM_SHIFT_RIGHT_COLS]> = Vec::new(); + let sr_events = input.shift_right_events.clone(); + for event in sr_events.iter() { + assert!(event.opcode == Opcode::SRL || event.opcode == Opcode::SRA); + let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; + let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); + let mut blu = Vec::new(); + self.event_to_row(event, cols, &mut blu); + rows.push(row); + } + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_SHIFT_RIGHT_COLS], + input.fixed_log2_rows::(self), ); // Convert the trace to a row major matrix. - RowMajorMatrix::new(values, NUM_SHIFT_RIGHT_COLS) + let mut trace = RowMajorMatrix::new( + rows.into_iter().flatten().collect::>(), + NUM_SHIFT_RIGHT_COLS, + ); + + // Create the template for the padded rows. These are fake rows that don't fail on some + // sanity checks. + let padded_row_template = { + let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; + let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); + // Shift 0 by 0 bits and 0 bytes. + // cols.is_srl = F::one(); + cols.shift_by_n_bits[0] = F::one(); + cols.shift_by_n_bytes[0] = F::one(); + row + }; + debug_assert!(padded_row_template.len() == NUM_SHIFT_RIGHT_COLS); + for i in input.shift_right_events.len() * NUM_SHIFT_RIGHT_COLS..trace.values.len() { + trace.values[i] = padded_row_template[i % NUM_SHIFT_RIGHT_COLS]; + } + + // Write the nonces to the trace. + for i in 0..trace.height() { + let cols: &mut ShiftRightCols = + trace.values[i * NUM_SHIFT_RIGHT_COLS..(i + 1) * NUM_SHIFT_RIGHT_COLS].borrow_mut(); + cols.nonce = F::from_canonical_usize(i); + } + + trace } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/cpu/columns/instruction.rs b/crates/core/machine/src/cpu/columns/instruction.rs index 27dd1f6a91..a16de4fb08 100644 --- a/crates/core/machine/src/cpu/columns/instruction.rs +++ b/crates/core/machine/src/cpu/columns/instruction.rs @@ -27,13 +27,13 @@ pub struct InstructionCols { } impl InstructionCols { - pub fn populate(&mut self, instruction: &Instruction) { + pub fn populate(&mut self, instruction: Instruction) { self.opcode = instruction.opcode.as_field::(); - self.op_a = (instruction.op_a as u32).into(); + self.op_a = instruction.op_a.into(); self.op_b = instruction.op_b.into(); self.op_c = instruction.op_c.into(); - self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u8); + self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u32); } } diff --git a/crates/core/machine/src/cpu/columns/opcode.rs b/crates/core/machine/src/cpu/columns/opcode.rs index 4de8f11ba7..9b4344d036 100644 --- a/crates/core/machine/src/cpu/columns/opcode.rs +++ b/crates/core/machine/src/cpu/columns/opcode.rs @@ -63,7 +63,7 @@ pub struct OpcodeSelectorCols { } impl OpcodeSelectorCols { - pub fn populate(&mut self, instruction: &Instruction) { + pub fn populate(&mut self, instruction: Instruction) { self.imm_b = F::from_bool(instruction.imm_b); self.imm_c = F::from_bool(instruction.imm_c); diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index c9831c66c0..01b1489127 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -1,10 +1,10 @@ use hashbrown::HashMap; use itertools::Itertools; use sp1_core_executor::{ - events::{ByteLookupEvent, ByteRecord, CpuEvent, MemoryRecordEnum}, + events::{ByteLookupEvent, ByteRecord, CpuEvent, LookupId, MemoryRecordEnum}, syscalls::SyscallCode, ByteOpcode::{self, U16Range}, - ExecutionRecord, Instruction, Opcode, Program, + CoreShape, ExecutionRecord, Opcode, Program, Register::X0, }; use sp1_primitives::consts::WORD_SIZE; @@ -13,10 +13,15 @@ use std::{array, borrow::BorrowMut}; use p3_field::{PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ + IntoParallelRefMutIterator, ParallelBridge, ParallelIterator, ParallelSlice, +}; use tracing::instrument; -use super::{columns::NUM_CPU_COLS, CpuChip}; +use super::{ + columns::{CPU_COL_MAP, NUM_CPU_COLS}, + CpuChip, +}; use crate::{cpu::columns::CpuCols, memory::MemoryCols, utils::zeroed_f_vec}; impl MachineAir for CpuChip { @@ -33,16 +38,7 @@ impl MachineAir for CpuChip { input: &ExecutionRecord, _: &mut ExecutionRecord, ) -> RowMajorMatrix { - let n_real_rows = input.cpu_events.len(); - let padded_nb_rows = if let Some(shape) = &input.shape { - 1 << shape.inner[&MachineAir::::name(self)] - } else if n_real_rows < 16 { - 16 - } else { - n_real_rows.next_power_of_two() - }; - let mut values = zeroed_f_vec(padded_nb_rows * NUM_CPU_COLS); - let shard = input.public_values.shard; + let mut values = zeroed_f_vec(input.cpu_events.len() * NUM_CPU_COLS); let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); values.chunks_mut(chunk_size * NUM_CPU_COLS).enumerate().par_bridge().for_each( @@ -50,36 +46,30 @@ impl MachineAir for CpuChip { rows.chunks_mut(NUM_CPU_COLS).enumerate().for_each(|(j, row)| { let idx = i * chunk_size + j; let cols: &mut CpuCols = row.borrow_mut(); - - if idx >= input.cpu_events.len() { - cols.selectors.imm_b = F::one(); - cols.selectors.imm_c = F::one(); - } else { - let mut byte_lookup_events = Vec::new(); - let event = &input.cpu_events[idx]; - let instruction = &input.program.fetch(event.pc); - self.event_to_row( - event, - &input.nonce_lookup, - cols, - &mut byte_lookup_events, - shard, - instruction, - ); - } + let mut byte_lookup_events = Vec::new(); + self.event_to_row( + &input.cpu_events[idx], + &input.nonce_lookup, + cols, + &mut byte_lookup_events, + ); }); }, ); // Convert the trace to a row major matrix. - RowMajorMatrix::new(values, NUM_CPU_COLS) + let mut trace = RowMajorMatrix::new(values, NUM_CPU_COLS); + + // Pad the trace to a power of two. + Self::pad_to_power_of_two::(self, &input.shape, &mut trace.values); + + trace } #[instrument(name = "generate cpu dependencies", level = "debug", skip_all)] fn generate_dependencies(&self, input: &ExecutionRecord, output: &mut ExecutionRecord) { // Generate the trace rows for each event. let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); - let shard = input.public_values.shard; let blu_events: Vec<_> = input .cpu_events @@ -90,15 +80,7 @@ impl MachineAir for CpuChip { ops.iter().for_each(|op| { let mut row = [F::zero(); NUM_CPU_COLS]; let cols: &mut CpuCols = row.as_mut_slice().borrow_mut(); - let instruction = &input.program.fetch(op.pc); - self.event_to_row::( - op, - &input.nonce_lookup, - cols, - &mut blu, - shard, - instruction, - ); + self.event_to_row::(op, &HashMap::new(), cols, &mut blu); }); blu }) @@ -121,25 +103,23 @@ impl CpuChip { fn event_to_row( &self, event: &CpuEvent, - nonce_lookup: &[u32], + nonce_lookup: &HashMap, cols: &mut CpuCols, blu_events: &mut impl ByteRecord, - shard: u32, - instruction: &Instruction, ) { // Populate shard and clk columns. - self.populate_shard_clk(cols, event, blu_events, shard); + self.populate_shard_clk(cols, event, blu_events); // Populate the nonce. cols.nonce = F::from_canonical_u32( - nonce_lookup.get(event.alu_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.alu_lookup_id).copied().unwrap_or_default(), ); // Populate basic fields. cols.pc = F::from_canonical_u32(event.pc); cols.next_pc = F::from_canonical_u32(event.next_pc); - cols.instruction.populate(instruction); - cols.selectors.populate(instruction); + cols.instruction.populate(event.instruction); + cols.selectors.populate(event.instruction); *cols.op_a_access.value_mut() = event.a.into(); *cols.op_b_access.value_mut() = event.b.into(); *cols.op_c_access.value_mut() = event.c.into(); @@ -165,7 +145,7 @@ impl CpuChip { .map(|x| x.as_canonical_u32()) .collect::>(); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, + shard: event.shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -173,7 +153,7 @@ impl CpuChip { c: a_bytes[1] as u8, }); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, + shard: event.shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -182,20 +162,23 @@ impl CpuChip { }); // Populate memory accesses for reading from memory. + assert_eq!(event.memory_record.is_some(), event.memory.is_some()); let memory_columns = cols.opcode_specific_columns.memory_mut(); if let Some(record) = event.memory_record { memory_columns.memory_access.populate(record, blu_events) } // Populate memory, branch, jump, and auipc specific fields. - self.populate_memory(cols, event, blu_events, nonce_lookup, shard, instruction); - self.populate_branch(cols, event, nonce_lookup, instruction); - self.populate_jump(cols, event, nonce_lookup, instruction); - self.populate_auipc(cols, event, nonce_lookup, instruction); + self.populate_memory(cols, event, blu_events, nonce_lookup); + self.populate_branch(cols, event, nonce_lookup); + self.populate_jump(cols, event, nonce_lookup); + self.populate_auipc(cols, event, nonce_lookup); let is_halt = self.populate_ecall(cols, event, nonce_lookup); cols.is_sequential_instr = F::from_bool( - !instruction.is_branch_instruction() && !instruction.is_jump_instruction() && !is_halt, + !event.instruction.is_branch_instruction() + && !event.instruction.is_jump_instruction() + && !is_halt, ); // Assert that the instruction is not a no-op. @@ -208,9 +191,8 @@ impl CpuChip { cols: &mut CpuCols, event: &CpuEvent, blu_events: &mut impl ByteRecord, - shard: u32, ) { - cols.shard = F::from_canonical_u32(shard); + cols.shard = F::from_canonical_u32(event.shard); cols.clk = F::from_canonical_u32(event.clk); let clk_16bit_limb = (event.clk & 0xffff) as u16; @@ -219,15 +201,15 @@ impl CpuChip { cols.clk_8bit_limb = F::from_canonical_u8(clk_8bit_limb); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, + event.shard, U16Range, - shard as u16, + event.shard as u16, 0, 0, 0, )); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, + event.shard, U16Range, clk_16bit_limb, 0, @@ -235,7 +217,7 @@ impl CpuChip { 0, )); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - shard, + event.shard, ByteOpcode::U8Range, 0, 0, @@ -250,12 +232,10 @@ impl CpuChip { cols: &mut CpuCols, event: &CpuEvent, blu_events: &mut impl ByteRecord, - nonce_lookup: &[u32], - shard: u32, - instruction: &Instruction, + nonce_lookup: &HashMap, ) { if !matches!( - instruction.opcode, + event.instruction.opcode, Opcode::LB | Opcode::LH | Opcode::LW @@ -282,7 +262,7 @@ impl CpuChip { let bits: [bool; 8] = array::from_fn(|i| aligned_addr_ls_byte & (1 << i) != 0); memory_columns.aa_least_sig_byte_decomp = array::from_fn(|i| F::from_bool(bits[i + 2])); memory_columns.addr_word_nonce = F::from_canonical_u32( - nonce_lookup.get(event.memory_add_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.memory_add_lookup_id).copied().unwrap_or_default(), ); // Populate memory offsets. @@ -295,10 +275,10 @@ impl CpuChip { // If it is a load instruction, set the unsigned_mem_val column. let mem_value = event.memory_record.unwrap().value(); if matches!( - instruction.opcode, + event.instruction.opcode, Opcode::LB | Opcode::LBU | Opcode::LH | Opcode::LHU | Opcode::LW ) { - match instruction.opcode { + match event.instruction.opcode { Opcode::LB | Opcode::LBU => { cols.unsigned_mem_val = (mem_value.to_le_bytes()[addr_offset as usize] as u32).into(); @@ -318,8 +298,8 @@ impl CpuChip { } // For the signed load instructions, we need to check if the loaded value is negative. - if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { - let most_sig_mem_value_byte = if matches!(instruction.opcode, Opcode::LB) { + if matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) { + let most_sig_mem_value_byte = if matches!(event.instruction.opcode, Opcode::LB) { cols.unsigned_mem_val.to_u32().to_le_bytes()[0] } else { cols.unsigned_mem_val.to_u32().to_le_bytes()[1] @@ -330,22 +310,20 @@ impl CpuChip { F::from_canonical_u8(most_sig_mem_value_byte >> i & 0x01); } if memory_columns.most_sig_byte_decomp[7] == F::one() { - cols.mem_value_is_neg_not_x0 = F::from_bool(instruction.op_a != (X0 as u8)); + cols.mem_value_is_neg_not_x0 = + F::from_bool(event.instruction.op_a != (X0 as u32)); cols.unsigned_mem_val_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.memory_sub_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), + nonce_lookup.get(&event.memory_sub_lookup_id).copied().unwrap_or_default(), ); } } // Set the `mem_value_is_pos_not_x0` composite flag. cols.mem_value_is_pos_not_x0 = F::from_bool( - ((matches!(instruction.opcode, Opcode::LB | Opcode::LH) + ((matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) && (memory_columns.most_sig_byte_decomp[7] == F::zero())) - || matches!(instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) - && instruction.op_a != (X0 as u8), + || matches!(event.instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) + && event.instruction.op_a != (X0 as u32), ); } @@ -353,7 +331,7 @@ impl CpuChip { let addr_bytes = memory_addr.to_le_bytes(); for byte_pair in addr_bytes.chunks_exact(2) { blu_events.add_byte_lookup_event(ByteLookupEvent { - shard, + shard: event.shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -368,15 +346,15 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &[u32], - instruction: &Instruction, + nonce_lookup: &HashMap, ) { - if instruction.is_branch_instruction() { + if event.instruction.is_branch_instruction() { let branch_columns = cols.opcode_specific_columns.branch_mut(); let a_eq_b = event.a == event.b; - let use_signed_comparison = matches!(instruction.opcode, Opcode::BLT | Opcode::BGE); + let use_signed_comparison = + matches!(event.instruction.opcode, Opcode::BLT | Opcode::BGE); let a_lt_b = if use_signed_comparison { (event.a as i32) < (event.b as i32) @@ -390,18 +368,18 @@ impl CpuChip { }; branch_columns.a_lt_b_nonce = F::from_canonical_u32( - nonce_lookup.get(event.branch_lt_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.branch_lt_lookup_id).copied().unwrap_or_default(), ); branch_columns.a_gt_b_nonce = F::from_canonical_u32( - nonce_lookup.get(event.branch_gt_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.branch_gt_lookup_id).copied().unwrap_or_default(), ); branch_columns.a_eq_b = F::from_bool(a_eq_b); branch_columns.a_lt_b = F::from_bool(a_lt_b); branch_columns.a_gt_b = F::from_bool(a_gt_b); - let branching = match instruction.opcode { + let branching = match event.instruction.opcode { Opcode::BEQ => a_eq_b, Opcode::BNE => !a_eq_b, Opcode::BLT | Opcode::BLTU => a_lt_b, @@ -418,10 +396,7 @@ impl CpuChip { if branching { cols.branching = F::one(); branch_columns.next_pc_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.branch_add_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), + nonce_lookup.get(&event.branch_add_lookup_id).copied().unwrap_or_default(), ); } else { cols.not_branching = F::one(); @@ -434,13 +409,12 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &[u32], - instruction: &Instruction, + nonce_lookup: &HashMap, ) { - if instruction.is_jump_instruction() { + if event.instruction.is_jump_instruction() { let jump_columns = cols.opcode_specific_columns.jump_mut(); - match instruction.opcode { + match event.instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); jump_columns.op_a_range_checker.populate(event.a); @@ -449,10 +423,7 @@ impl CpuChip { jump_columns.next_pc = Word::from(next_pc); jump_columns.next_pc_range_checker.populate(next_pc); jump_columns.jal_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.jump_jal_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), + nonce_lookup.get(&event.jump_jal_lookup_id).copied().unwrap_or_default(), ); } Opcode::JALR => { @@ -461,10 +432,7 @@ impl CpuChip { jump_columns.next_pc = Word::from(next_pc); jump_columns.next_pc_range_checker.populate(next_pc); jump_columns.jalr_nonce = F::from_canonical_u32( - nonce_lookup - .get(event.jump_jalr_lookup_id.0 as usize) - .copied() - .unwrap_or_default(), + nonce_lookup.get(&event.jump_jalr_lookup_id).copied().unwrap_or_default(), ); } _ => unreachable!(), @@ -477,16 +445,15 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &[u32], - instruction: &Instruction, + nonce_lookup: &HashMap, ) { - if matches!(instruction.opcode, Opcode::AUIPC) { + if matches!(event.instruction.opcode, Opcode::AUIPC) { let auipc_columns = cols.opcode_specific_columns.auipc_mut(); auipc_columns.pc = Word::from(event.pc); auipc_columns.pc_range_checker.populate(event.pc); auipc_columns.auipc_nonce = F::from_canonical_u32( - nonce_lookup.get(event.auipc_lookup_id.0 as usize).copied().unwrap_or_default(), + nonce_lookup.get(&event.auipc_lookup_id).copied().unwrap_or_default(), ); } } @@ -496,7 +463,7 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &[u32], + nonce_lookup: &HashMap, ) -> bool { let mut is_halt = false; @@ -549,8 +516,9 @@ impl CpuChip { } // Write the syscall nonce. - ecall_cols.syscall_nonce = - F::from_canonical_u32(nonce_lookup[event.syscall_lookup_id.0 as usize]); + ecall_cols.syscall_nonce = F::from_canonical_u32( + nonce_lookup.get(&event.syscall_lookup_id).copied().unwrap_or_default(), + ); is_halt = syscall_id == F::from_canonical_u32(SyscallCode::HALT.syscall_id()); @@ -572,4 +540,29 @@ impl CpuChip { is_halt } + + fn pad_to_power_of_two(&self, shape: &Option, values: &mut Vec) { + let n_real_rows = values.len() / NUM_CPU_COLS; + let padded_nb_rows = if let Some(shape) = shape { + 1 << shape.inner[&MachineAir::::name(self)] + } else if n_real_rows < 16 { + 16 + } else { + n_real_rows.next_power_of_two() + }; + values.resize(padded_nb_rows * NUM_CPU_COLS, F::zero()); + + // Interpret values as a slice of arrays of length `NUM_CPU_COLS` + let rows = unsafe { + core::slice::from_raw_parts_mut( + values.as_mut_ptr() as *mut [F; NUM_CPU_COLS], + values.len() / NUM_CPU_COLS, + ) + }; + + rows[n_real_rows..].par_iter_mut().for_each(|padded_row| { + padded_row[CPU_COL_MAP.selectors.imm_b] = F::one(); + padded_row[CPU_COL_MAP.selectors.imm_c] = F::one(); + }); + } } diff --git a/crates/core/machine/src/memory/local.rs b/crates/core/machine/src/memory/local.rs index 8be4377031..bf109d028e 100644 --- a/crates/core/machine/src/memory/local.rs +++ b/crates/core/machine/src/memory/local.rs @@ -3,11 +3,11 @@ use std::{ mem::size_of, }; -use crate::utils::{next_power_of_two, zeroed_f_vec}; +use crate::utils::pad_rows_fixed; +use itertools::Itertools; use p3_air::{Air, BaseAir}; use p3_field::PrimeField32; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -86,45 +86,39 @@ impl MachineAir for MemoryLocalChip { input: &ExecutionRecord, _output: &mut ExecutionRecord, ) -> RowMajorMatrix { - // Generate the trace rows for each event. - let events = input.get_local_mem_events().collect::>(); - let nb_rows = (events.len() + 3) / 4; - let size_log2 = input.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_MEMORY_LOCAL_INIT_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values - .chunks_mut(chunk_size * NUM_MEMORY_LOCAL_INIT_COLS) - .enumerate() - .par_bridge() - .for_each(|(i, rows)| { - rows.chunks_mut(NUM_MEMORY_LOCAL_INIT_COLS).enumerate().for_each(|(j, row)| { - let idx = (i * chunk_size + j) * NUM_LOCAL_MEMORY_ENTRIES_PER_ROW; - - let cols: &mut MemoryLocalCols = row.borrow_mut(); - for k in 0..NUM_LOCAL_MEMORY_ENTRIES_PER_ROW { - let cols = &mut cols.memory_local_entries[k]; - if idx + k < events.len() { - let event = &events[idx + k]; - cols.addr = F::from_canonical_u32(event.addr); - cols.initial_shard = - F::from_canonical_u32(event.initial_mem_access.shard); - cols.final_shard = F::from_canonical_u32(event.final_mem_access.shard); - cols.initial_clk = - F::from_canonical_u32(event.initial_mem_access.timestamp); - cols.final_clk = - F::from_canonical_u32(event.final_mem_access.timestamp); - cols.initial_value = event.initial_mem_access.value.into(); - cols.final_value = event.final_mem_access.value.into(); - cols.is_real = F::one(); - } - } - }); - }); - - // Convert the trace to a row major matrix. - RowMajorMatrix::new(values, NUM_MEMORY_LOCAL_INIT_COLS) + let mut rows = Vec::<[F; NUM_MEMORY_LOCAL_INIT_COLS]>::new(); + + for local_mem_events in + &input.get_local_mem_events().chunks(NUM_LOCAL_MEMORY_ENTRIES_PER_ROW) + { + let mut row = [F::zero(); NUM_MEMORY_LOCAL_INIT_COLS]; + let cols: &mut MemoryLocalCols = row.as_mut_slice().borrow_mut(); + + for (cols, event) in cols.memory_local_entries.iter_mut().zip(local_mem_events) { + cols.addr = F::from_canonical_u32(event.addr); + cols.initial_shard = F::from_canonical_u32(event.initial_mem_access.shard); + cols.final_shard = F::from_canonical_u32(event.final_mem_access.shard); + cols.initial_clk = F::from_canonical_u32(event.initial_mem_access.timestamp); + cols.final_clk = F::from_canonical_u32(event.final_mem_access.timestamp); + cols.initial_value = event.initial_mem_access.value.into(); + cols.final_value = event.final_mem_access.value.into(); + cols.is_real = F::one(); + } + + rows.push(row); + } + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_MEMORY_LOCAL_INIT_COLS], + input.fixed_log2_rows::(self), + ); + + RowMajorMatrix::new( + rows.into_iter().flatten().collect::>(), + NUM_MEMORY_LOCAL_INIT_COLS, + ) } fn included(&self, shard: &Self::Record) -> bool { diff --git a/crates/core/machine/src/memory/program.rs b/crates/core/machine/src/memory/program.rs index 699e052c0d..7b68661624 100644 --- a/crates/core/machine/src/memory/program.rs +++ b/crates/core/machine/src/memory/program.rs @@ -7,7 +7,6 @@ use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, PairBuilder}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -18,10 +17,7 @@ use sp1_stark::{ InteractionKind, Word, }; -use crate::{ - operations::IsZeroOperation, - utils::{next_power_of_two, pad_rows_fixed, zeroed_f_vec}, -}; +use crate::{operations::IsZeroOperation, utils::pad_rows_fixed}; pub const NUM_MEMORY_PROGRAM_PREPROCESSED_COLS: usize = size_of::>(); @@ -75,36 +71,35 @@ impl MachineAir for MemoryProgramChip { } fn generate_preprocessed_trace(&self, program: &Self::Program) -> Option> { - // Generate the trace rows for each event. - let nb_rows = program.memory_image.len(); - let size_log2 = program.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_MEMORY_PROGRAM_PREPROCESSED_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - let memory = program.memory_image.iter().collect::>(); - values - .chunks_mut(chunk_size * NUM_MEMORY_PROGRAM_PREPROCESSED_COLS) - .enumerate() - .par_bridge() - .for_each(|(i, rows)| { - rows.chunks_mut(NUM_MEMORY_PROGRAM_PREPROCESSED_COLS).enumerate().for_each( - |(j, row)| { - let idx = i * chunk_size + j; - - if idx < nb_rows { - let (addr, word) = memory[idx]; - let cols: &mut MemoryProgramPreprocessedCols = row.borrow_mut(); - cols.addr = F::from_canonical_u32(*addr); - cols.value = Word::from(*word); - cols.is_real = F::one(); - } - }, - ); - }); + let program_memory = &program.memory_image; + // Note that BTreeMap is guaranteed to be sorted by key. This makes the row order + // deterministic. + let mut rows = program_memory + .iter() + .sorted() + .map(|(&addr, &word)| { + let mut row = [F::zero(); NUM_MEMORY_PROGRAM_PREPROCESSED_COLS]; + let cols: &mut MemoryProgramPreprocessedCols = row.as_mut_slice().borrow_mut(); + cols.addr = F::from_canonical_u32(addr); + cols.value = Word::from(word); + cols.is_real = F::one(); + row + }) + .collect::>(); + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_MEMORY_PROGRAM_PREPROCESSED_COLS], + program.fixed_log2_rows::(self), + ); // Convert the trace to a row major matrix. - Some(RowMajorMatrix::new(values, NUM_MEMORY_PROGRAM_PREPROCESSED_COLS)) + let trace = RowMajorMatrix::new( + rows.into_iter().flatten().collect::>(), + NUM_MEMORY_PROGRAM_PREPROCESSED_COLS, + ); + Some(trace) } fn generate_dependencies(&self, _input: &ExecutionRecord, _output: &mut ExecutionRecord) { diff --git a/crates/core/machine/src/program/mod.rs b/crates/core/machine/src/program/mod.rs index f6c1f3bc0c..39dfb6a765 100644 --- a/crates/core/machine/src/program/mod.rs +++ b/crates/core/machine/src/program/mod.rs @@ -4,14 +4,10 @@ use core::{ }; use std::collections::HashMap; -use crate::{ - air::ProgramAirBuilder, - utils::{next_power_of_two, pad_rows_fixed, zeroed_f_vec}, -}; +use crate::{air::ProgramAirBuilder, utils::pad_rows_fixed}; use p3_air::{Air, BaseAir, PairBuilder}; use p3_field::PrimeField; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::air::{MachineAir, SP1AirBuilder}; @@ -69,34 +65,36 @@ impl MachineAir for ProgramChip { !program.instructions.is_empty() || program.preprocessed_shape.is_some(), "empty program" ); - // Generate the trace rows for each event. - let nb_rows = program.instructions.len(); - let size_log2 = program.fixed_log2_rows::(self); - let padded_nb_rows = next_power_of_two(nb_rows, size_log2); - let mut values = zeroed_f_vec(padded_nb_rows * NUM_PROGRAM_PREPROCESSED_COLS); - let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); - - values - .chunks_mut(chunk_size * NUM_PROGRAM_PREPROCESSED_COLS) + let mut rows = program + .instructions + .iter() .enumerate() - .par_bridge() - .for_each(|(i, rows)| { - rows.chunks_mut(NUM_PROGRAM_PREPROCESSED_COLS).enumerate().for_each(|(j, row)| { - let idx = i * chunk_size + j; - - if idx < nb_rows { - let cols: &mut ProgramPreprocessedCols = row.borrow_mut(); - let instruction = &program.instructions[idx]; - let pc = program.pc_base + (idx as u32 * 4); - cols.pc = F::from_canonical_u32(pc); - cols.instruction.populate(instruction); - cols.selectors.populate(instruction); - } - }); - }); + .map(|(i, &instruction)| { + let pc = program.pc_base + (i as u32 * 4); + let mut row = [F::zero(); NUM_PROGRAM_PREPROCESSED_COLS]; + let cols: &mut ProgramPreprocessedCols = row.as_mut_slice().borrow_mut(); + cols.pc = F::from_canonical_u32(pc); + cols.instruction.populate(instruction); + cols.selectors.populate(instruction); + + row + }) + .collect::>(); + + // Pad the trace to a power of two depending on the proof shape in `input`. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_PROGRAM_PREPROCESSED_COLS], + program.fixed_log2_rows::(self), + ); // Convert the trace to a row major matrix. - Some(RowMajorMatrix::new(values, NUM_PROGRAM_PREPROCESSED_COLS)) + let trace = RowMajorMatrix::new( + rows.into_iter().flatten().collect::>(), + NUM_PROGRAM_PREPROCESSED_COLS, + ); + + Some(trace) } fn generate_dependencies(&self, _input: &ExecutionRecord, _output: &mut ExecutionRecord) { diff --git a/crates/core/machine/src/runtime/utils.rs b/crates/core/machine/src/runtime/utils.rs index 483400e294..7c0ad541e7 100644 --- a/crates/core/machine/src/runtime/utils.rs +++ b/crates/core/machine/src/runtime/utils.rs @@ -19,7 +19,7 @@ macro_rules! assert_valid_memory_access { assert!($addr > 40); } _ => { - Register::from_u8($addr); + Register::from_u32($addr); } }; } @@ -69,7 +69,11 @@ impl<'a> Runtime<'a> { ); if !self.unconstrained && self.state.global_clk % 10_000_000 == 0 { - log::info!("clk = {} pc = 0x{:x?}", self.state.global_clk, self.state.pc); + log::info!( + "clk = {} pc = 0x{:x?}", + self.state.global_clk, + self.state.pc + ); } } } diff --git a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs index 97d0e526fe..c9c5ae93c8 100644 --- a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs +++ b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs @@ -72,7 +72,7 @@ impl EdDecompressCols { self.clk = F::from_canonical_u32(event.clk); self.ptr = F::from_canonical_u32(event.ptr); self.nonce = F::from_canonical_u32( - record.nonce_lookup.get(event.lookup_id.0 as usize).copied().unwrap_or_default(), + record.nonce_lookup.get(&event.lookup_id).copied().unwrap_or_default(), ); self.sign = F::from_bool(event.sign); for i in 0..8 { diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index fb46afd4ed..be4d816264 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -33,7 +33,11 @@ use std::{ }; use lru::LruCache; + +use tracing::instrument; + use p3_baby_bear::BabyBear; + use p3_challenger::CanObserve; use p3_field::{AbstractField, PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; @@ -76,7 +80,6 @@ use sp1_stark::{ MachineProver, SP1CoreOpts, SP1ProverOpts, ShardProof, StarkGenericConfig, StarkVerifyingKey, Val, Word, DIGEST_SIZE, }; -use tracing::instrument; pub use types::*; use utils::{sp1_committed_values_digest_bn254, sp1_vkey_digest_bn254, words_to_bytes}; @@ -353,9 +356,8 @@ impl SP1Prover { input: &SP1CompressWithVKeyWitnessValues, ) -> Arc> { let mut cache = self.compress_programs.lock().unwrap_or_else(|e| e.into_inner()); - let shape = input.shape(); cache - .get_or_insert(shape.clone(), || { + .get_or_insert(input.shape(), || { let misses = self.compress_cache_misses.fetch_add(1, Ordering::Relaxed); tracing::debug!("compress cache miss, misses: {}", misses); // Get the operations. diff --git a/crates/prover/src/shapes.rs b/crates/prover/src/shapes.rs index 74f7ba177e..b7adddc0e5 100644 --- a/crates/prover/src/shapes.rs +++ b/crates/prover/src/shapes.rs @@ -1,13 +1,11 @@ use std::{ collections::{BTreeMap, BTreeSet, HashSet}, fs::File, - hash::{DefaultHasher, Hash, Hasher}, panic::{catch_unwind, AssertUnwindSafe}, path::PathBuf, sync::{Arc, Mutex}, }; -use eyre::Result; use thiserror::Error; use p3_baby_bear::BabyBear; @@ -31,7 +29,7 @@ pub enum SP1ProofShape { Shrink(ProofShape), } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub enum SP1CompressProgramShape { Recursion(SP1RecursionShape), Compress(SP1CompressWithVkeyShape), @@ -39,14 +37,6 @@ pub enum SP1CompressProgramShape { Shrink(SP1CompressWithVkeyShape), } -impl SP1CompressProgramShape { - pub fn hash_u64(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - Hash::hash(&self, &mut hasher); - hasher.finish() - } -} - #[derive(Debug, Error)] pub enum VkBuildError { #[error("IO error: {0}")] @@ -241,15 +231,6 @@ impl SP1ProofShape { ) } - pub fn generate_compress_shapes( - recursion_shape_config: &'_ RecursionShapeConfig>, - reduce_batch_size: usize, - ) -> impl Iterator + '_ { - (1..=reduce_batch_size).flat_map(|batch_size| { - recursion_shape_config.get_all_shape_combinations(batch_size).map(Self::Compress) - }) - } - pub fn dummy_vk_map<'a>( core_shape_config: &'a CoreShapeConfig, recursion_shape_config: &'a RecursionShapeConfig>, diff --git a/crates/recursion/circuit/src/machine/deferred.rs b/crates/recursion/circuit/src/machine/deferred.rs index d5ab720973..0f38620a7d 100644 --- a/crates/recursion/circuit/src/machine/deferred.rs +++ b/crates/recursion/circuit/src/machine/deferred.rs @@ -43,7 +43,7 @@ pub struct SP1DeferredVerifier { _phantom: std::marker::PhantomData<(C, SC, A)>, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone)] pub struct SP1DeferredShape { inner: SP1CompressShape, height: usize, diff --git a/crates/recursion/compiler/src/circuit/compiler.rs b/crates/recursion/compiler/src/circuit/compiler.rs index b44b38a1dd..d75c0d3d6e 100644 --- a/crates/recursion/compiler/src/circuit/compiler.rs +++ b/crates/recursion/compiler/src/circuit/compiler.rs @@ -17,9 +17,6 @@ use sp1_recursion_core::*; use crate::prelude::*; -/// The number of instructions to preallocate in a recursion program -const PREALLOC_INSTRUCTIONS: usize = 10000000; - /// The backend for the circuit compiler. #[derive(Debug, Clone, Default)] pub struct AsmCompiler { @@ -514,7 +511,7 @@ where // Compile each IR instruction into a list of ASM instructions, then combine them. // This step also counts the number of times each address is read from. let (mut instrs, traces) = tracing::debug_span!("compile_one loop").in_scope(|| { - let mut instrs = Vec::with_capacity(PREALLOC_INSTRUCTIONS); + let mut instrs = Vec::with_capacity(operations.vec.len()); let mut traces = vec![]; if debug_mode { let mut span_builder = diff --git a/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs b/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs index 7e67f54362..ecd9c57550 100644 --- a/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs @@ -41,10 +41,6 @@ impl MachineAir for Poseidon2SkinnyChip format!("Poseidon2SkinnyDeg{}", DEGREE) } - fn generate_dependencies(&self, _: &Self::Record, _: &mut Self::Record) { - // This is a no-op. - } - #[instrument(name = "generate poseidon2 skinny trace", level = "debug", skip_all, fields(rows = input.poseidon2_events.len()))] fn generate_trace( &self, diff --git a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs index 19a3b6f287..0d5c666265 100644 --- a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs @@ -37,10 +37,6 @@ impl MachineAir for Poseidon2WideChip, const DEGREE: u #[derive(Debug, Clone, Copy, Default)] pub struct RecursionAirEventCount { - pub mem_const_events: usize, - pub mem_var_events: usize, - pub base_alu_events: usize, - pub ext_alu_events: usize, - pub poseidon2_wide_events: usize, - pub fri_fold_events: usize, - pub select_events: usize, - pub exp_reverse_bits_len_events: usize, + mem_const_events: usize, + mem_var_events: usize, + base_alu_events: usize, + ext_alu_events: usize, + poseidon2_wide_events: usize, + fri_fold_events: usize, + select_events: usize, + exp_reverse_bits_len_events: usize, } impl, const DEGREE: usize> RecursionAir { diff --git a/crates/recursion/core/src/runtime/memory.rs b/crates/recursion/core/src/runtime/memory.rs index d0b7f0f229..a82337b684 100644 --- a/crates/recursion/core/src/runtime/memory.rs +++ b/crates/recursion/core/src/runtime/memory.rs @@ -5,7 +5,7 @@ use vec_map::{Entry, VecMap}; use crate::{air::Block, Address}; -#[derive(Debug, Clone, Default, Copy)] +#[derive(Debug, Clone, Default)] pub struct MemoryEntry { pub val: Block, pub mult: F, diff --git a/crates/recursion/core/src/runtime/mod.rs b/crates/recursion/core/src/runtime/mod.rs index 2478a45ddb..f95ef87a14 100644 --- a/crates/recursion/core/src/runtime/mod.rs +++ b/crates/recursion/core/src/runtime/mod.rs @@ -8,7 +8,6 @@ mod record; use backtrace::Backtrace as Trace; pub use instruction::Instruction; use instruction::{FieldEltType, HintBitsInstr, HintExt2FeltsInstr, HintInstr, PrintInstr}; -use machine::RecursionAirEventCount; use memory::*; pub use opcode::*; pub use program::*; @@ -250,7 +249,6 @@ where pub fn run(&mut self) -> Result<(), RuntimeError> { let early_exit_ts = std::env::var("RECURSION_EARLY_EXIT_TS") .map_or(usize::MAX, |ts: String| ts.parse().unwrap()); - self.preallocate_record(); while self.pc < F::from_canonical_u32(self.program.instructions.len() as u32) { let idx = self.pc.as_canonical_u32() as usize; let instruction = self.program.instructions[idx].clone(); @@ -546,18 +544,4 @@ where } Ok(()) } - - pub fn preallocate_record(&mut self) { - let event_counts = self - .program - .instructions - .iter() - .fold(RecursionAirEventCount::default(), |heights, instruction| heights + instruction); - self.record.poseidon2_events.reserve(event_counts.poseidon2_wide_events); - self.record.mem_var_events.reserve(event_counts.mem_var_events); - self.record.base_alu_events.reserve(event_counts.base_alu_events); - self.record.ext_alu_events.reserve(event_counts.ext_alu_events); - self.record.exp_reverse_bits_len_events.reserve(event_counts.exp_reverse_bits_len_events); - self.record.select_events.reserve(event_counts.select_events); - } } From 76a568b1db359a2af4c091f4e8f732b8bab7ceed Mon Sep 17 00:00:00 2001 From: Eugene Rabinovich Date: Thu, 31 Oct 2024 16:42:15 -0700 Subject: [PATCH 06/17] perf: remove redundant last compress (#1724) --- crates/prover/src/lib.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index be4d816264..0ff296bb2a 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -902,12 +902,8 @@ impl SP1Prover { if let Ok((index, height, vk, proof)) = received { batch.push((index, height, vk, proof)); - // Compute whether we've reached the root of the tree. - let is_complete = height == expected_height; - - // If it's not complete, and we haven't reached the batch size, - // continue. - if !is_complete && batch.len() < batch_size { + // If we haven't reached the batch size, continue. + if batch.len() < batch_size { continue; } @@ -922,7 +918,10 @@ impl SP1Prover { let inputs = if is_last { vec![batch[0].clone()] } else { batch.clone() }; - let next_input_index = inputs[0].1 + 1; + let next_input_height = inputs[0].1 + 1; + + let is_complete = next_input_height == expected_height; + let vks_and_proofs = inputs .into_iter() .map(|(_, _, vk, proof)| (vk, proof)) @@ -936,7 +935,7 @@ impl SP1Prover { input_tx .lock() .unwrap() - .send((count, next_input_index, input)) + .send((count, next_input_height, input)) .unwrap(); input_sync.advance_turn(); count += 1; From b8abe3298b92eec38d6f1b7f7e51a1329b272148 Mon Sep 17 00:00:00 2001 From: Tamir Hemo Date: Thu, 31 Oct 2024 18:33:45 -0700 Subject: [PATCH 07/17] fix: empty shape config (#1728) --- crates/core/machine/src/utils/prove.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/crates/core/machine/src/utils/prove.rs b/crates/core/machine/src/utils/prove.rs index 4b18c2e54c..4a17c8f764 100644 --- a/crates/core/machine/src/utils/prove.rs +++ b/crates/core/machine/src/utils/prove.rs @@ -142,11 +142,8 @@ where { // Setup the runtime. let mut runtime = Executor::with_context(program.clone(), opts, context); - let maximal_shapes = match shape_config.as_ref() { - Some(shape_config) => shape_config.maximal_core_shapes(), - None => vec![], - }; - runtime.maximal_shapes = Some(maximal_shapes.into_iter().map(|s| s.inner).collect()); + runtime.maximal_shapes = shape_config + .map(|config| config.maximal_core_shapes().into_iter().map(|s| s.inner).collect()); runtime.write_vecs(&stdin.buffer); for proof in stdin.proofs.iter() { let (proof, vk) = proof.clone(); @@ -618,9 +615,16 @@ where |(record, (global_traces, local_traces))| { let _span = span.enter(); + let global_commit_span = + tracing::debug_span!("commit to global traces").entered(); let global_data = prover.commit(&record, global_traces); + global_commit_span.exit(); + let local_commit_span = + tracing::debug_span!("commit to local traces").entered(); let local_data = prover.commit(&record, local_traces); + local_commit_span.exit(); + let opening_span = tracing::debug_span!("opening").entered(); let proof = prover .open( pk, @@ -630,6 +634,7 @@ where &global_permutation_challenges, ) .unwrap(); + opening_span.exit(); #[cfg(debug_assertions)] { @@ -838,15 +843,12 @@ fn trace_checkpoint( where ::Val: PrimeField32, { - let maximal_shapes = match shape_config { - Some(shape_config) => shape_config.maximal_core_shapes(), - None => vec![], - }; let mut reader = std::io::BufReader::new(file); let state: ExecutionState = bincode::deserialize_from(&mut reader).expect("failed to deserialize state"); let mut runtime = Executor::recover(program.clone(), state.clone(), opts); - runtime.maximal_shapes = Some(maximal_shapes.into_iter().map(|s| s.inner).collect()); + runtime.maximal_shapes = shape_config + .map(|config| config.maximal_core_shapes().into_iter().map(|s| s.inner).collect()); // We already passed the deferred proof verifier when creating checkpoints, so the proofs were // already verified. So here we use a noop verifier to not print any warnings. From 8a62caa0b8893aabe8e9477d4568c20387ae4896 Mon Sep 17 00:00:00 2001 From: "Chris T." Date: Fri, 1 Nov 2024 10:47:29 -0700 Subject: [PATCH 08/17] feat: executor optimizations + separate postprocess (#1727) --- Cargo.lock | 1 + crates/core/executor/src/dependencies.rs | 119 ++-- crates/core/executor/src/disassembler/rrs.rs | 57 +- crates/core/executor/src/events/alu.rs | 4 +- crates/core/executor/src/events/byte.rs | 2 +- crates/core/executor/src/events/cpu.rs | 8 - crates/core/executor/src/events/memory.rs | 8 +- crates/core/executor/src/events/utils.rs | 37 +- crates/core/executor/src/executor.rs | 544 +++++++++--------- crates/core/executor/src/instruction.rs | 4 +- crates/core/executor/src/memory.rs | 27 +- crates/core/executor/src/opcode.rs | 2 +- crates/core/executor/src/program.rs | 7 + crates/core/executor/src/record.rs | 71 ++- crates/core/executor/src/register.rs | 4 +- crates/core/executor/src/syscalls/context.rs | 24 +- .../src/syscalls/precompiles/edwards/add.rs | 6 +- .../precompiles/edwards/decompress.rs | 6 +- .../src/syscalls/precompiles/fptower/fp.rs | 4 +- .../precompiles/fptower/fp2_addsub.rs | 4 +- .../syscalls/precompiles/fptower/fp2_mul.rs | 4 +- .../syscalls/precompiles/keccak256/permute.rs | 2 +- .../syscalls/precompiles/sha256/compress.rs | 2 +- .../src/syscalls/precompiles/sha256/extend.rs | 12 +- .../src/syscalls/precompiles/uint256.rs | 2 +- .../syscalls/precompiles/weierstrass/add.rs | 6 +- .../precompiles/weierstrass/decompress.rs | 4 +- .../precompiles/weierstrass/double.rs | 6 +- crates/core/machine/Cargo.toml | 1 + crates/core/machine/src/alu/add_sub/mod.rs | 66 +-- crates/core/machine/src/alu/divrem/mod.rs | 28 +- crates/core/machine/src/alu/lt/mod.rs | 51 +- crates/core/machine/src/alu/mul/mod.rs | 283 ++++----- crates/core/machine/src/alu/sr/mod.rs | 73 +-- .../machine/src/cpu/columns/instruction.rs | 6 +- crates/core/machine/src/cpu/columns/opcode.rs | 2 +- crates/core/machine/src/cpu/trace.rs | 213 +++---- crates/core/machine/src/memory/local.rs | 76 +-- crates/core/machine/src/memory/program.rs | 61 +- crates/core/machine/src/program/mod.rs | 58 +- crates/core/machine/src/runtime/utils.rs | 8 +- .../precompiles/edwards/ed_decompress.rs | 2 +- crates/core/machine/src/utils/prove.rs | 7 +- crates/prover/src/lib.rs | 8 +- crates/prover/src/shapes.rs | 21 +- .../recursion/circuit/src/machine/deferred.rs | 2 +- .../compiler/src/circuit/compiler.rs | 5 +- .../core/src/chips/poseidon2_skinny/trace.rs | 4 + .../core/src/chips/poseidon2_wide/trace.rs | 4 + crates/recursion/core/src/machine.rs | 16 +- crates/recursion/core/src/runtime/memory.rs | 2 +- crates/recursion/core/src/runtime/mod.rs | 16 + 52 files changed, 1009 insertions(+), 981 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 22a73f10b5..748f845ec7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6215,6 +6215,7 @@ dependencies = [ "tracing-forest", "tracing-subscriber", "typenum", + "vec_map", "web-time", ] diff --git a/crates/core/executor/src/dependencies.rs b/crates/core/executor/src/dependencies.rs index 194d8d0eb2..6b0bbbe33c 100644 --- a/crates/core/executor/src/dependencies.rs +++ b/crates/core/executor/src/dependencies.rs @@ -1,5 +1,5 @@ use crate::{ - events::{create_alu_lookups, AluEvent, CpuEvent}, + events::AluEvent, utils::{get_msb, get_quotient_and_remainder, is_signed_operation}, Executor, Opcode, }; @@ -7,6 +7,7 @@ use crate::{ /// Emits the dependencies for division and remainder operations. #[allow(clippy::too_many_lines)] pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { + let shard = executor.shard(); let (quotient, remainder) = get_quotient_and_remainder(event.b, event.c, event.opcode); let c_msb = get_msb(event.c); let rem_msb = get_msb(remainder); @@ -19,27 +20,29 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { } if c_neg == 1 { + let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(AluEvent { lookup_id: event.sub_lookups[4], - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: 0, b: event.c, c: (event.c as i32).unsigned_abs(), - sub_lookups: create_alu_lookups(), + sub_lookups: ids, }); } if rem_neg == 1 { + let ids = executor.record.create_lookup_ids(); executor.record.add_events.push(AluEvent { lookup_id: event.sub_lookups[5], - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: 0, b: remainder, c: (remainder as i32).unsigned_abs(), - sub_lookups: create_alu_lookups(), + sub_lookups: ids, }); } @@ -55,19 +58,19 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { let lower_multiplication = AluEvent { lookup_id: event.sub_lookups[0], - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::MUL, a: lower_word, c: event.c, b: quotient, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.mul_events.push(lower_multiplication); let upper_multiplication = AluEvent { lookup_id: event.sub_lookups[1], - shard: event.shard, + shard, clk: event.clk, opcode: { if is_signed_operation { @@ -79,31 +82,31 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { a: upper_word, c: event.c, b: quotient, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.mul_events.push(upper_multiplication); let lt_event = if is_signed_operation { AluEvent { lookup_id: event.sub_lookups[2], - shard: event.shard, + shard, opcode: Opcode::SLTU, a: 1, b: (remainder as i32).unsigned_abs(), c: u32::max(1, (event.c as i32).unsigned_abs()), clk: event.clk, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), } } else { AluEvent { lookup_id: event.sub_lookups[3], - shard: event.shard, + shard, opcode: Opcode::SLTU, a: 1, b: remainder, c: u32::max(1, event.c), clk: event.clk, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), } }; @@ -114,9 +117,12 @@ pub fn emit_divrem_dependencies(executor: &mut Executor, event: AluEvent) { /// Emit the dependencies for CPU events. #[allow(clippy::too_many_lines)] -pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { +pub fn emit_cpu_dependencies(executor: &mut Executor, index: usize) { + let event = executor.record.cpu_events[index]; + let shard = executor.shard(); + let instruction = &executor.program.fetch(event.pc); if matches!( - event.instruction.opcode, + instruction.opcode, Opcode::LB | Opcode::LH | Opcode::LW @@ -130,58 +136,57 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { // Add event to ALU check to check that addr == b + c let add_event = AluEvent { lookup_id: event.memory_add_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: memory_addr, b: event.b, c: event.c, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); let addr_offset = (memory_addr % 4_u32) as u8; let mem_value = event.memory_record.unwrap().value(); - if matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) { - let (unsigned_mem_val, most_sig_mem_value_byte, sign_value) = - match event.instruction.opcode { - Opcode::LB => { - let most_sig_mem_value_byte = mem_value.to_le_bytes()[addr_offset as usize]; - let sign_value = 256; - (most_sig_mem_value_byte as u32, most_sig_mem_value_byte, sign_value) - } - Opcode::LH => { - let sign_value = 65536; - let unsigned_mem_val = match (addr_offset >> 1) % 2 { - 0 => mem_value & 0x0000FFFF, - 1 => (mem_value & 0xFFFF0000) >> 16, - _ => unreachable!(), - }; - let most_sig_mem_value_byte = unsigned_mem_val.to_le_bytes()[1]; - (unsigned_mem_val, most_sig_mem_value_byte, sign_value) - } - _ => unreachable!(), - }; + if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { + let (unsigned_mem_val, most_sig_mem_value_byte, sign_value) = match instruction.opcode { + Opcode::LB => { + let most_sig_mem_value_byte = mem_value.to_le_bytes()[addr_offset as usize]; + let sign_value = 256; + (most_sig_mem_value_byte as u32, most_sig_mem_value_byte, sign_value) + } + Opcode::LH => { + let sign_value = 65536; + let unsigned_mem_val = match (addr_offset >> 1) % 2 { + 0 => mem_value & 0x0000FFFF, + 1 => (mem_value & 0xFFFF0000) >> 16, + _ => unreachable!(), + }; + let most_sig_mem_value_byte = unsigned_mem_val.to_le_bytes()[1]; + (unsigned_mem_val, most_sig_mem_value_byte, sign_value) + } + _ => unreachable!(), + }; if most_sig_mem_value_byte >> 7 & 0x01 == 1 { let sub_event = AluEvent { lookup_id: event.memory_sub_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::SUB, a: event.a, b: unsigned_mem_val, c: sign_value, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(sub_event); } } } - if event.instruction.is_branch_instruction() { + if instruction.is_branch_instruction() { let a_eq_b = event.a == event.b; - let use_signed_comparison = matches!(event.instruction.opcode, Opcode::BLT | Opcode::BGE); + let use_signed_comparison = matches!(instruction.opcode, Opcode::BLT | Opcode::BGE); let a_lt_b = if use_signed_comparison { (event.a as i32) < (event.b as i32) } else { @@ -197,27 +202,27 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { // Add the ALU events for the comparisons let lt_comp_event = AluEvent { lookup_id: event.branch_lt_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: alu_op_code, a: a_lt_b as u32, b: event.a, c: event.b, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; let gt_comp_event = AluEvent { lookup_id: event.branch_gt_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: alu_op_code, a: a_gt_b as u32, b: event.b, c: event.a, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.lt_events.push(lt_comp_event); executor.record.lt_events.push(gt_comp_event); - let branching = match event.instruction.opcode { + let branching = match instruction.opcode { Opcode::BEQ => a_eq_b, Opcode::BNE => !a_eq_b, Opcode::BLT | Opcode::BLTU => a_lt_b, @@ -228,31 +233,31 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { let next_pc = event.pc.wrapping_add(event.c); let add_event = AluEvent { lookup_id: event.branch_add_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, c: event.c, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); } } - if event.instruction.is_jump_instruction() { - match event.instruction.opcode { + if instruction.is_jump_instruction() { + match instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); let add_event = AluEvent { lookup_id: event.jump_jal_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.pc, c: event.b, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); } @@ -260,13 +265,13 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { let next_pc = event.b.wrapping_add(event.c); let add_event = AluEvent { lookup_id: event.jump_jalr_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: next_pc, b: event.b, c: event.c, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); } @@ -274,16 +279,16 @@ pub fn emit_cpu_dependencies(executor: &mut Executor, event: &CpuEvent) { } } - if matches!(event.instruction.opcode, Opcode::AUIPC) { + if matches!(instruction.opcode, Opcode::AUIPC) { let add_event = AluEvent { lookup_id: event.auipc_lookup_id, - shard: event.shard, + shard, clk: event.clk, opcode: Opcode::ADD, a: event.a, b: event.pc, c: event.b, - sub_lookups: create_alu_lookups(), + sub_lookups: executor.record.create_lookup_ids(), }; executor.record.add_events.push(add_event); } diff --git a/crates/core/executor/src/disassembler/rrs.rs b/crates/core/executor/src/disassembler/rrs.rs index 711dbe4e4a..a105e10a81 100644 --- a/crates/core/executor/src/disassembler/rrs.rs +++ b/crates/core/executor/src/disassembler/rrs.rs @@ -9,52 +9,31 @@ impl Instruction { /// Create a new [`Instruction`] from an R-type instruction. #[must_use] pub const fn from_r_type(opcode: Opcode, dec_insn: &RType) -> Self { - Self::new( - opcode, - dec_insn.rd as u32, - dec_insn.rs1 as u32, - dec_insn.rs2 as u32, - false, - false, - ) + Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.rs2 as u32, false, false) } /// Create a new [`Instruction`] from an I-type instruction. #[must_use] pub const fn from_i_type(opcode: Opcode, dec_insn: &IType) -> Self { - Self::new(opcode, dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) + Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) } /// Create a new [`Instruction`] from an I-type instruction with a shamt. #[must_use] pub const fn from_i_type_shamt(opcode: Opcode, dec_insn: &ITypeShamt) -> Self { - Self::new(opcode, dec_insn.rd as u32, dec_insn.rs1 as u32, dec_insn.shamt, false, true) + Self::new(opcode, dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.shamt, false, true) } /// Create a new [`Instruction`] from an S-type instruction. #[must_use] pub const fn from_s_type(opcode: Opcode, dec_insn: &SType) -> Self { - Self::new( - opcode, - dec_insn.rs2 as u32, - dec_insn.rs1 as u32, - dec_insn.imm as u32, - false, - true, - ) + Self::new(opcode, dec_insn.rs2 as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, true) } /// Create a new [`Instruction`] from a B-type instruction. #[must_use] pub const fn from_b_type(opcode: Opcode, dec_insn: &BType) -> Self { - Self::new( - opcode, - dec_insn.rs1 as u32, - dec_insn.rs2 as u32, - dec_insn.imm as u32, - false, - true, - ) + Self::new(opcode, dec_insn.rs1 as u8, dec_insn.rs2 as u32, dec_insn.imm as u32, false, true) } /// Create a new [`Instruction`] that is not implemented. @@ -82,9 +61,9 @@ impl Instruction { #[must_use] pub fn r_type(&self) -> (Register, Register, Register) { ( - Register::from_u32(self.op_a), - Register::from_u32(self.op_b), - Register::from_u32(self.op_c), + Register::from_u8(self.op_a), + Register::from_u8(self.op_b as u8), + Register::from_u8(self.op_c as u8), ) } @@ -92,35 +71,35 @@ impl Instruction { #[inline] #[must_use] pub fn i_type(&self) -> (Register, Register, u32) { - (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) + (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) } /// Decode the [`Instruction`] in the S-type format. #[inline] #[must_use] pub fn s_type(&self) -> (Register, Register, u32) { - (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) + (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) } /// Decode the [`Instruction`] in the B-type format. #[inline] #[must_use] pub fn b_type(&self) -> (Register, Register, u32) { - (Register::from_u32(self.op_a), Register::from_u32(self.op_b), self.op_c) + (Register::from_u8(self.op_a), Register::from_u8(self.op_b as u8), self.op_c) } /// Decode the [`Instruction`] in the J-type format. #[inline] #[must_use] pub fn j_type(&self) -> (Register, u32) { - (Register::from_u32(self.op_a), self.op_b) + (Register::from_u8(self.op_a), self.op_b) } /// Decode the [`Instruction`] in the U-type format. #[inline] #[must_use] pub fn u_type(&self) -> (Register, u32) { - (Register::from_u32(self.op_a), self.op_b) + (Register::from_u8(self.op_a), self.op_b) } } @@ -263,13 +242,13 @@ impl InstructionProcessor for InstructionTranspiler { } fn process_jal(&mut self, dec_insn: JType) -> Self::InstructionResult { - Instruction::new(Opcode::JAL, dec_insn.rd as u32, dec_insn.imm as u32, 0, true, true) + Instruction::new(Opcode::JAL, dec_insn.rd as u8, dec_insn.imm as u32, 0, true, true) } fn process_jalr(&mut self, dec_insn: IType) -> Self::InstructionResult { Instruction::new( Opcode::JALR, - dec_insn.rd as u32, + dec_insn.rd as u8, dec_insn.rs1 as u32, dec_insn.imm as u32, false, @@ -282,14 +261,14 @@ impl InstructionProcessor for InstructionTranspiler { // // Notably, LUI instructions are converted to an SLL instruction with `imm_b` and `imm_c` // turned on. Additionally the `op_c` should be set to 12. - Instruction::new(Opcode::ADD, dec_insn.rd as u32, 0, dec_insn.imm as u32, true, true) + Instruction::new(Opcode::ADD, dec_insn.rd as u8, 0, dec_insn.imm as u32, true, true) } /// AUIPC instructions have the third operand set to imm << 12. fn process_auipc(&mut self, dec_insn: UType) -> Self::InstructionResult { Instruction::new( Opcode::AUIPC, - dec_insn.rd as u32, + dec_insn.rd as u8, dec_insn.imm as u32, dec_insn.imm as u32, true, @@ -300,7 +279,7 @@ impl InstructionProcessor for InstructionTranspiler { fn process_ecall(&mut self) -> Self::InstructionResult { Instruction::new( Opcode::ECALL, - Register::X5 as u32, + Register::X5 as u8, Register::X10 as u32, Register::X11 as u32, false, diff --git a/crates/core/executor/src/events/alu.rs b/crates/core/executor/src/events/alu.rs index bf79a65e4c..2d2b14fe03 100644 --- a/crates/core/executor/src/events/alu.rs +++ b/crates/core/executor/src/events/alu.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::Opcode; -use super::{create_alu_lookups, LookupId}; +use super::{create_random_lookup_ids, LookupId}; /// Arithmetic Logic Unit (ALU) Event. /// @@ -40,7 +40,7 @@ impl AluEvent { a, b, c, - sub_lookups: create_alu_lookups(), + sub_lookups: create_random_lookup_ids(), } } } diff --git a/crates/core/executor/src/events/byte.rs b/crates/core/executor/src/events/byte.rs index 4e5f254373..3db5c7647b 100644 --- a/crates/core/executor/src/events/byte.rs +++ b/crates/core/executor/src/events/byte.rs @@ -233,7 +233,7 @@ impl ByteOpcode { ByteOpcode::MSB, ByteOpcode::U16Range, ]; - assert_eq!(opcodes.len(), NUM_BYTE_OPS); + debug_assert_eq!(opcodes.len(), NUM_BYTE_OPS); opcodes } diff --git a/crates/core/executor/src/events/cpu.rs b/crates/core/executor/src/events/cpu.rs index b2d775cf12..f609e941c0 100644 --- a/crates/core/executor/src/events/cpu.rs +++ b/crates/core/executor/src/events/cpu.rs @@ -1,7 +1,5 @@ use serde::{Deserialize, Serialize}; -use crate::Instruction; - use super::{memory::MemoryRecordEnum, LookupId}; /// CPU Event. @@ -10,16 +8,12 @@ use super::{memory::MemoryRecordEnum, LookupId}; /// shard, opcode, operands, and other relevant information. #[derive(Debug, Copy, Clone, Serialize, Deserialize)] pub struct CpuEvent { - /// The shard number. - pub shard: u32, /// The clock cycle. pub clk: u32, /// The program counter. pub pc: u32, /// The next program counter. pub next_pc: u32, - /// The instruction. - pub instruction: Instruction, /// The first operand. pub a: u32, /// The first operand memory record. @@ -32,8 +26,6 @@ pub struct CpuEvent { pub c: u32, /// The third operand memory record. pub c_record: Option, - /// The memory value. - pub memory: Option, /// The memory record. pub memory_record: Option, /// The exit code. diff --git a/crates/core/executor/src/events/memory.rs b/crates/core/executor/src/events/memory.rs index 4372f21267..655e0fc21d 100644 --- a/crates/core/executor/src/events/memory.rs +++ b/crates/core/executor/src/events/memory.rs @@ -150,7 +150,9 @@ impl MemoryReadRecord { prev_shard: u32, prev_timestamp: u32, ) -> Self { - assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp))); + debug_assert!( + shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)) + ); Self { value, shard, timestamp, prev_shard, prev_timestamp } } } @@ -166,7 +168,9 @@ impl MemoryWriteRecord { prev_shard: u32, prev_timestamp: u32, ) -> Self { - assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)),); + debug_assert!( + shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)), + ); Self { value, shard, timestamp, prev_value, prev_shard, prev_timestamp } } } diff --git a/crates/core/executor/src/events/utils.rs b/crates/core/executor/src/events/utils.rs index 681bc6cc78..d4b38df745 100644 --- a/crates/core/executor/src/events/utils.rs +++ b/crates/core/executor/src/events/utils.rs @@ -5,43 +5,16 @@ use std::{ iter::{Map, Peekable}, }; -use rand::{thread_rng, Rng}; - /// A unique identifier for lookups. -/// -/// We use 4 u32s instead of a u128 to make it compatible with C. #[derive(Deserialize, Serialize, Debug, Clone, Copy, Default, Eq, Hash, PartialEq)] -pub struct LookupId { - /// First part of the id. - pub a: u32, - /// Second part of the id. - pub b: u32, - /// Third part of the id. - pub c: u32, - /// Fourth part of the id. - pub d: u32, -} - -/// Creates a new ALU lookup id with ``LookupId`` -#[must_use] -pub fn create_alu_lookup_id() -> LookupId { - let mut rng = thread_rng(); - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() } -} +pub struct LookupId(pub u64); -/// Creates a new ALU lookup id with ``LookupId`` +/// Create a random lookup id. This is slower than `record.create_lookup_id()` but is useful for +/// testing. #[must_use] -pub fn create_alu_lookups() -> [LookupId; 6] { - let mut rng = thread_rng(); - [ - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - LookupId { a: rng.gen(), b: rng.gen(), c: rng.gen(), d: rng.gen() }, - ] +pub(crate) fn create_random_lookup_ids() -> [LookupId; 6] { + std::array::from_fn(|_| LookupId(rand::random())) } /// Returns sorted and formatted rows of a table of counts (e.g. `opcode_counts`). diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index cfbc8cacd5..3fc3403fba 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -13,9 +13,8 @@ use crate::{ context::SP1Context, dependencies::{emit_cpu_dependencies, emit_divrem_dependencies}, events::{ - create_alu_lookup_id, create_alu_lookups, AluEvent, CpuEvent, LookupId, - MemoryAccessPosition, MemoryInitializeFinalizeEvent, MemoryLocalEvent, MemoryReadRecord, - MemoryRecord, MemoryWriteRecord, SyscallEvent, + AluEvent, CpuEvent, LookupId, MemoryAccessPosition, MemoryInitializeFinalizeEvent, + MemoryLocalEvent, MemoryReadRecord, MemoryRecord, MemoryWriteRecord, SyscallEvent, }, hook::{HookEnv, HookRegistry}, memory::{Entry, PagedMemory}, @@ -31,7 +30,6 @@ use crate::{ /// /// The exeuctor is responsible for executing a user program and tracing important events which /// occur during execution (i.e., memory reads, alu operations, etc). -#[repr(C)] pub struct Executor<'a> { /// The program. pub program: Arc, @@ -49,6 +47,10 @@ pub struct Executor<'a> { /// Whether we should write to the report. pub print_report: bool, + /// Whether we should emit global memory init and finalize events. This can be enabled in + /// Checkpoint mode and disabled in Trace mode. + pub emit_global_memory_events: bool, + /// The maximum size of each shard. pub shard_size: u32, @@ -221,6 +223,7 @@ impl<'a> Executor<'a> { unconstrained_state: ForkState::default(), syscall_map, executor_mode: ExecutorMode::Trace, + emit_global_memory_events: true, max_syscall_cycles, report: ExecutionReport::default(), print_report: false, @@ -269,7 +272,7 @@ impl<'a> Executor<'a> { pub fn registers(&mut self) -> [u32; 32] { let mut registers = [0; 32]; for i in 0..32 { - let addr = Register::from_u32(i as u32) as u32; + let addr = Register::from_u8(i as u8) as u32; let record = self.state.memory.get(addr); // Only add the previous memory state to checkpoint map if we're in checkpoint mode, @@ -407,7 +410,7 @@ impl<'a> Executor<'a> { record.shard = shard; record.timestamp = timestamp; - if !self.unconstrained { + if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { let local_memory_access = if let Some(local_memory_access) = local_memory_access { local_memory_access } else { @@ -486,7 +489,7 @@ impl<'a> Executor<'a> { record.shard = shard; record.timestamp = timestamp; - if !self.unconstrained { + if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { let local_memory_access = if let Some(local_memory_access) = local_memory_access { local_memory_access } else { @@ -553,19 +556,19 @@ impl<'a> Executor<'a> { if !self.unconstrained && self.executor_mode == ExecutorMode::Trace { match position { MemoryAccessPosition::A => { - assert!(self.memory_accesses.a.is_none()); + debug_assert!(self.memory_accesses.a.is_none()); self.memory_accesses.a = Some(record.into()); } MemoryAccessPosition::B => { - assert!(self.memory_accesses.b.is_none()); + debug_assert!(self.memory_accesses.b.is_none()); self.memory_accesses.b = Some(record.into()); } MemoryAccessPosition::C => { - assert!(self.memory_accesses.c.is_none()); + debug_assert!(self.memory_accesses.c.is_none()); self.memory_accesses.c = Some(record.into()); } MemoryAccessPosition::Memory => { - assert!(self.memory_accesses.memory.is_none()); + debug_assert!(self.memory_accesses.memory.is_none()); self.memory_accesses.memory = Some(record.into()); } } @@ -593,49 +596,50 @@ impl<'a> Executor<'a> { #[allow(clippy::too_many_arguments)] fn emit_cpu( &mut self, - shard: u32, clk: u32, pc: u32, next_pc: u32, - instruction: Instruction, a: u32, b: u32, c: u32, - memory_store_value: Option, record: MemoryAccessRecord, exit_code: u32, lookup_id: LookupId, syscall_lookup_id: LookupId, ) { - let cpu_event = CpuEvent { - shard, + let memory_add_lookup_id = self.record.create_lookup_id(); + let memory_sub_lookup_id = self.record.create_lookup_id(); + let branch_lt_lookup_id = self.record.create_lookup_id(); + let branch_gt_lookup_id = self.record.create_lookup_id(); + let branch_add_lookup_id = self.record.create_lookup_id(); + let jump_jal_lookup_id = self.record.create_lookup_id(); + let jump_jalr_lookup_id = self.record.create_lookup_id(); + let auipc_lookup_id = self.record.create_lookup_id(); + self.record.cpu_events.push(CpuEvent { clk, pc, next_pc, - instruction, a, a_record: record.a, b, b_record: record.b, c, c_record: record.c, - memory: memory_store_value, memory_record: record.memory, exit_code, alu_lookup_id: lookup_id, syscall_lookup_id, - memory_add_lookup_id: create_alu_lookup_id(), - memory_sub_lookup_id: create_alu_lookup_id(), - branch_lt_lookup_id: create_alu_lookup_id(), - branch_gt_lookup_id: create_alu_lookup_id(), - branch_add_lookup_id: create_alu_lookup_id(), - jump_jal_lookup_id: create_alu_lookup_id(), - jump_jalr_lookup_id: create_alu_lookup_id(), - auipc_lookup_id: create_alu_lookup_id(), - }; + memory_add_lookup_id, + memory_sub_lookup_id, + branch_lt_lookup_id, + branch_gt_lookup_id, + branch_add_lookup_id, + jump_jal_lookup_id, + jump_jalr_lookup_id, + auipc_lookup_id, + }); - self.record.cpu_events.push(cpu_event); - emit_cpu_dependencies(self, &cpu_event); + emit_cpu_dependencies(self, self.record.cpu_events.len() - 1); } /// Emit an ALU event. @@ -648,7 +652,7 @@ impl<'a> Executor<'a> { a, b, c, - sub_lookups: create_alu_lookups(), + sub_lookups: self.record.create_lookup_ids(), }; match opcode { Opcode::ADD => { @@ -696,7 +700,7 @@ impl<'a> Executor<'a> { arg1, arg2, lookup_id, - nonce: self.record.nonce_lookup[&lookup_id], + nonce: self.record.nonce_lookup[lookup_id.0 as usize], } } @@ -725,9 +729,9 @@ impl<'a> Executor<'a> { let (rd, b, c) = (rd, self.rr(rs1, MemoryAccessPosition::B), imm); (rd, b, c) } else { - assert!(instruction.imm_b && instruction.imm_c); + debug_assert!(instruction.imm_b && instruction.imm_c); let (rd, b, c) = - (Register::from_u32(instruction.op_a), instruction.op_b, instruction.op_c); + (Register::from_u8(instruction.op_a), instruction.op_b, instruction.op_c); (rd, b, c) } } @@ -780,8 +784,7 @@ impl<'a> Executor<'a> { /// Fetch the instruction at the current program counter. #[inline] fn fetch(&self) -> Instruction { - let idx = ((self.state.pc - self.program.pc_base) / 4) as usize; - self.program.instructions[idx] + *self.program.fetch(self.state.pc) } /// Execute the given instruction over the current state of the runtime. @@ -793,21 +796,18 @@ impl<'a> Executor<'a> { let mut next_pc = self.state.pc.wrapping_add(4); - let rd: Register; let (a, b, c): (u32, u32, u32); - let (addr, memory_read_value): (u32, u32); - let mut memory_store_value: Option = None; if self.executor_mode == ExecutorMode::Trace { self.memory_accesses = MemoryAccessRecord::default(); } let lookup_id = if self.executor_mode == ExecutorMode::Trace { - create_alu_lookup_id() + self.record.create_lookup_id() } else { LookupId::default() }; let syscall_lookup_id = if self.executor_mode == ExecutorMode::Trace { - create_alu_lookup_id() + self.record.create_lookup_id() } else { LookupId::default() }; @@ -842,182 +842,40 @@ impl<'a> Executor<'a> { match instruction.opcode { // Arithmetic instructions. - Opcode::ADD => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_add(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SUB => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_sub(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::XOR => { - (rd, b, c) = self.alu_rr(instruction); - a = b ^ c; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::OR => { - (rd, b, c) = self.alu_rr(instruction); - a = b | c; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::AND => { - (rd, b, c) = self.alu_rr(instruction); - a = b & c; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SLL => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_shl(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SRL => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_shr(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SRA => { - (rd, b, c) = self.alu_rr(instruction); - a = (b as i32).wrapping_shr(c) as u32; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SLT => { - (rd, b, c) = self.alu_rr(instruction); - a = if (b as i32) < (c as i32) { 1 } else { 0 }; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::SLTU => { - (rd, b, c) = self.alu_rr(instruction); - a = if b < c { 1 } else { 0 }; - self.alu_rw(instruction, rd, a, b, c, lookup_id); + Opcode::ADD + | Opcode::SUB + | Opcode::XOR + | Opcode::OR + | Opcode::AND + | Opcode::SLL + | Opcode::SRL + | Opcode::SRA + | Opcode::SLT + | Opcode::SLTU + | Opcode::MUL + | Opcode::MULH + | Opcode::MULHU + | Opcode::MULHSU + | Opcode::DIV + | Opcode::DIVU + | Opcode::REM + | Opcode::REMU => { + (a, b, c) = self.execute_alu(instruction, lookup_id); } // Load instructions. - Opcode::LB => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - 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); - self.rw(rd, a); - } - Opcode::LH => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LH, addr)); - } - let value = match (addr >> 1) % 2 { - 0 => memory_read_value & 0x0000_FFFF, - 1 => (memory_read_value & 0xFFFF_0000) >> 16, - _ => unreachable!(), - }; - a = ((value as i16) as i32) as u32; - memory_store_value = Some(memory_read_value); - self.rw(rd, a); - } - Opcode::LW => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - if addr % 4 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LW, addr)); - } - a = memory_read_value; - memory_store_value = Some(memory_read_value); - self.rw(rd, a); - } - Opcode::LBU => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - let value = (memory_read_value).to_le_bytes()[(addr % 4) as usize]; - a = value as u32; - memory_store_value = Some(memory_read_value); - self.rw(rd, a); - } - Opcode::LHU => { - (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::LHU, addr)); - } - let value = match (addr >> 1) % 2 { - 0 => memory_read_value & 0x0000_FFFF, - 1 => (memory_read_value & 0xFFFF_0000) >> 16, - _ => unreachable!(), - }; - a = (value as u16) as u32; - memory_store_value = Some(memory_read_value); - self.rw(rd, a); + Opcode::LB | Opcode::LH | Opcode::LW | Opcode::LBU | Opcode::LHU => { + (a, b, c) = self.execute_load(instruction)?; } // Store instructions. - Opcode::SB => { - (a, b, c, addr, memory_read_value) = self.store_rr(instruction); - let value = match addr % 4 { - 0 => (a & 0x0000_00FF) + (memory_read_value & 0xFFFF_FF00), - 1 => ((a & 0x0000_00FF) << 8) + (memory_read_value & 0xFFFF_00FF), - 2 => ((a & 0x0000_00FF) << 16) + (memory_read_value & 0xFF00_FFFF), - 3 => ((a & 0x0000_00FF) << 24) + (memory_read_value & 0x00FF_FFFF), - _ => unreachable!(), - }; - memory_store_value = Some(value); - self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); - } - Opcode::SH => { - (a, b, c, addr, memory_read_value) = self.store_rr(instruction); - if addr % 2 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::SH, addr)); - } - let value = match (addr >> 1) % 2 { - 0 => (a & 0x0000_FFFF) + (memory_read_value & 0xFFFF_0000), - 1 => ((a & 0x0000_FFFF) << 16) + (memory_read_value & 0x0000_FFFF), - _ => unreachable!(), - }; - memory_store_value = Some(value); - self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); - } - Opcode::SW => { - (a, b, c, addr, _) = self.store_rr(instruction); - if addr % 4 != 0 { - return Err(ExecutionError::InvalidMemoryAccess(Opcode::SW, addr)); - } - let value = a; - memory_store_value = Some(value); - self.mw_cpu(align(addr), value, MemoryAccessPosition::Memory); + Opcode::SB | Opcode::SH | Opcode::SW => { + (a, b, c) = self.execute_store(instruction)?; } - // B-type instructions. - Opcode::BEQ => { - (a, b, c) = self.branch_rr(instruction); - if a == b { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BNE => { - (a, b, c) = self.branch_rr(instruction); - if a != b { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BLT => { - (a, b, c) = self.branch_rr(instruction); - if (a as i32) < (b as i32) { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BGE => { - (a, b, c) = self.branch_rr(instruction); - if (a as i32) >= (b as i32) { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BLTU => { - (a, b, c) = self.branch_rr(instruction); - if a < b { - next_pc = self.state.pc.wrapping_add(c); - } - } - Opcode::BGEU => { - (a, b, c) = self.branch_rr(instruction); - if a >= b { - next_pc = self.state.pc.wrapping_add(c); - } + // Branch instructions. + Opcode::BEQ | Opcode::BNE | Opcode::BLT | Opcode::BGE | Opcode::BLTU | Opcode::BGEU => { + (a, b, c, next_pc) = self.execute_branch(instruction, next_pc); } // Jump instructions. @@ -1080,11 +938,11 @@ impl<'a> Executor<'a> { _ => (self.opts.split_opts.deferred, 1), }; let nonce = (((*syscall_count as usize) % threshold) * multiplier) as u32; - self.record.nonce_lookup.insert(syscall_lookup_id, nonce); + self.record.nonce_lookup[syscall_lookup_id.0 as usize] = nonce; *syscall_count += 1; let syscall_impl = self.get_syscall(syscall).cloned(); - if syscall.should_send() != 0 { + if syscall.should_send() != 0 && self.executor_mode == ExecutorMode::Trace { self.emit_syscall(clk, syscall.syscall_id(), b, c, syscall_lookup_id); } let mut precompile_rt = SyscallContext::new(self); @@ -1130,64 +988,6 @@ impl<'a> Executor<'a> { return Err(ExecutionError::Breakpoint()); } - // Multiply instructions. - Opcode::MUL => { - (rd, b, c) = self.alu_rr(instruction); - a = b.wrapping_mul(c); - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::MULH => { - (rd, b, c) = self.alu_rr(instruction); - a = (((b as i32) as i64).wrapping_mul((c as i32) as i64) >> 32) as u32; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::MULHU => { - (rd, b, c) = self.alu_rr(instruction); - a = ((b as u64).wrapping_mul(c as u64) >> 32) as u32; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::MULHSU => { - (rd, b, c) = self.alu_rr(instruction); - a = (((b as i32) as i64).wrapping_mul(c as i64) >> 32) as u32; - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::DIV => { - (rd, b, c) = self.alu_rr(instruction); - if c == 0 { - a = u32::MAX; - } else { - a = (b as i32).wrapping_div(c as i32) as u32; - } - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::DIVU => { - (rd, b, c) = self.alu_rr(instruction); - if c == 0 { - a = u32::MAX; - } else { - a = b.wrapping_div(c); - } - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::REM => { - (rd, b, c) = self.alu_rr(instruction); - if c == 0 { - a = b; - } else { - a = (b as i32).wrapping_rem(c as i32) as u32; - } - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - Opcode::REMU => { - (rd, b, c) = self.alu_rr(instruction); - if c == 0 { - a = b; - } else { - a = b.wrapping_rem(c); - } - self.alu_rw(instruction, rd, a, b, c, lookup_id); - } - // See https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md#instruction-aliases Opcode::UNIMP => { return Err(ExecutionError::Unimplemented()); @@ -1203,15 +1003,12 @@ impl<'a> Executor<'a> { // Emit the CPU event for this cycle. if self.executor_mode == ExecutorMode::Trace { self.emit_cpu( - self.shard(), clk, pc, next_pc, - *instruction, a, b, c, - memory_store_value, self.memory_accesses, exit_code, lookup_id, @@ -1221,6 +1018,153 @@ impl<'a> Executor<'a> { Ok(()) } + fn execute_alu(&mut self, instruction: &Instruction, lookup_id: LookupId) -> (u32, u32, u32) { + let (rd, b, c) = self.alu_rr(instruction); + let a = match instruction.opcode { + Opcode::ADD => b.wrapping_add(c), + Opcode::SUB => b.wrapping_sub(c), + Opcode::XOR => b ^ c, + Opcode::OR => b | c, + Opcode::AND => b & c, + Opcode::SLL => b.wrapping_shl(c), + Opcode::SRL => b.wrapping_shr(c), + Opcode::SRA => (b as i32).wrapping_shr(c) as u32, + Opcode::SLT => { + if (b as i32) < (c as i32) { + 1 + } else { + 0 + } + } + Opcode::SLTU => { + if b < c { + 1 + } else { + 0 + } + } + Opcode::MUL => b.wrapping_mul(c), + Opcode::MULH => (((b as i32) as i64).wrapping_mul((c as i32) as i64) >> 32) as u32, + Opcode::MULHU => ((b as u64).wrapping_mul(c as u64) >> 32) as u32, + Opcode::MULHSU => (((b as i32) as i64).wrapping_mul(c as i64) >> 32) as u32, + Opcode::DIV => { + if c == 0 { + u32::MAX + } else { + (b as i32).wrapping_div(c as i32) as u32 + } + } + Opcode::DIVU => { + if c == 0 { + u32::MAX + } else { + b.wrapping_div(c) + } + } + Opcode::REM => { + if c == 0 { + b + } else { + (b as i32).wrapping_rem(c as i32) as u32 + } + } + Opcode::REMU => { + if c == 0 { + b + } else { + b.wrapping_rem(c) + } + } + _ => unreachable!(), + }; + self.alu_rw(instruction, rd, a, b, c, lookup_id); + (a, b, c) + } + + fn execute_load( + &mut self, + instruction: &Instruction, + ) -> Result<(u32, u32, u32), ExecutionError> { + let (rd, b, c, addr, memory_read_value) = self.load_rr(instruction); + let a = match instruction.opcode { + Opcode::LB => ((memory_read_value >> ((addr % 4) * 8)) & 0xFF) as i8 as i32 as u32, + Opcode::LH => { + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LH, addr)); + } + ((memory_read_value >> (((addr / 2) % 2) * 16)) & 0xFFFF) as i16 as i32 as u32 + } + Opcode::LW => { + if addr % 4 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LW, addr)); + } + memory_read_value + } + Opcode::LBU => (memory_read_value >> ((addr % 4) * 8)) & 0xFF, + Opcode::LHU => { + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::LHU, addr)); + } + (memory_read_value >> (((addr / 2) % 2) * 16)) & 0xFFFF + } + _ => unreachable!(), + }; + self.rw(rd, a); + Ok((a, b, c)) + } + + fn execute_store( + &mut self, + instruction: &Instruction, + ) -> Result<(u32, u32, u32), ExecutionError> { + let (a, b, c, addr, memory_read_value) = self.store_rr(instruction); + let memory_store_value = match instruction.opcode { + Opcode::SB => { + let shift = (addr % 4) * 8; + ((a & 0xFF) << shift) | (memory_read_value & !(0xFF << shift)) + } + Opcode::SH => { + if addr % 2 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::SH, addr)); + } + let shift = ((addr / 2) % 2) * 16; + ((a & 0xFFFF) << shift) | (memory_read_value & !(0xFFFF << shift)) + } + Opcode::SW => { + if addr % 4 != 0 { + return Err(ExecutionError::InvalidMemoryAccess(Opcode::SW, addr)); + } + a + } + _ => unreachable!(), + }; + self.mw_cpu(align(addr), memory_store_value, MemoryAccessPosition::Memory); + Ok((a, b, c)) + } + + fn execute_branch( + &mut self, + instruction: &Instruction, + mut next_pc: u32, + ) -> (u32, u32, u32, u32) { + let (a, b, c) = self.branch_rr(instruction); + let branch = match instruction.opcode { + Opcode::BEQ => a == b, + Opcode::BNE => a != b, + Opcode::BLT => (a as i32) < (b as i32), + Opcode::BGE => (a as i32) >= (b as i32), + Opcode::BLTU => a < b, + Opcode::BGEU => a >= b, + _ => { + unreachable!() + } + }; + if branch { + next_pc = self.state.pc.wrapping_add(c); + } + (a, b, c, next_pc) + } + /// Executes one cycle of the program, returning whether the program has finished. #[inline] #[allow(clippy::too_many_lines)] @@ -1389,14 +1333,17 @@ impl<'a> Executor<'a> { /// Bump the record. pub fn bump_record(&mut self) { // Copy all of the existing local memory accesses to the record's local_memory_access vec. - for (_, event) in self.local_memory_access.drain() { - self.record.cpu_local_memory_access.push(event); + if self.executor_mode == ExecutorMode::Trace { + for (_, event) in self.local_memory_access.drain() { + self.record.cpu_local_memory_access.push(event); + } } let removed_record = std::mem::replace(&mut self.record, ExecutionRecord::new(self.program.clone())); let public_values = removed_record.public_values; self.record.public_values = public_values; + self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; self.records.push(removed_record); } @@ -1406,8 +1353,12 @@ impl<'a> Executor<'a> { /// # Errors /// /// This function will return an error if the program execution fails. - pub fn execute_record(&mut self) -> Result<(Vec, bool), ExecutionError> { + pub fn execute_record( + &mut self, + emit_global_memory_events: bool, + ) -> Result<(Vec, bool), ExecutionError> { self.executor_mode = ExecutorMode::Trace; + self.emit_global_memory_events = emit_global_memory_events; self.print_report = true; let done = self.execute()?; Ok((std::mem::take(&mut self.records), done)) @@ -1419,27 +1370,32 @@ impl<'a> Executor<'a> { /// # Errors /// /// This function will return an error if the program execution fails. - pub fn execute_state(&mut self) -> Result<(ExecutionState, bool), ExecutionError> { + pub fn execute_state( + &mut self, + emit_global_memory_events: bool, + ) -> Result<(ExecutionState, bool), ExecutionError> { self.memory_checkpoint.clear(); self.executor_mode = ExecutorMode::Checkpoint; + self.emit_global_memory_events = emit_global_memory_events; // Clone self.state without memory and uninitialized_memory in it so it's faster. let memory = std::mem::take(&mut self.state.memory); let uninitialized_memory = std::mem::take(&mut self.state.uninitialized_memory); - let mut checkpoint = tracing::info_span!("clone").in_scope(|| self.state.clone()); + let mut checkpoint = tracing::debug_span!("clone").in_scope(|| self.state.clone()); self.state.memory = memory; self.state.uninitialized_memory = uninitialized_memory; - let done = tracing::info_span!("execute").in_scope(|| self.execute())?; + let done = tracing::debug_span!("execute").in_scope(|| self.execute())?; // Create a checkpoint using `memory_checkpoint`. Just include all memory if `done` since we // need it all for MemoryFinalize. - tracing::info_span!("create memory checkpoint").in_scope(|| { + tracing::debug_span!("create memory checkpoint").in_scope(|| { let memory_checkpoint = std::mem::take(&mut self.memory_checkpoint); let uninitialized_memory_checkpoint = std::mem::take(&mut self.uninitialized_memory_checkpoint); - if done { - // If we're done, we need to include all memory. But we need to reset any modified - // memory to as it was before the execution. + if done && !self.emit_global_memory_events { + // If it's the last shard, and we're not emitting memory events, we need to include + // all memory so that memory events can be emitted from the checkpoint. But we need + // to first reset any modified memory to as it was before the execution. checkpoint.memory.clone_from(&self.state.memory); memory_checkpoint.into_iter().for_each(|(addr, record)| { if let Some(record) = record { @@ -1467,10 +1423,15 @@ impl<'a> Executor<'a> { .collect(); } }); + if !done { + self.records.clear(); + } Ok((checkpoint, done)) } fn initialize(&mut self) { + self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; + self.state.clk = 0; tracing::debug!("loading memory image"); @@ -1506,6 +1467,11 @@ impl<'a> Executor<'a> { /// Executes up to `self.shard_batch_size` cycles of the program, returning whether the program /// has finished. pub fn execute(&mut self) -> Result { + // Initialize the nonce lookup table if it's uninitialized. + if self.record.nonce_lookup.len() <= 2 { + self.record.nonce_lookup = vec![0; self.opts.shard_size * 32]; + } + // Get the program. let program = self.program.clone(); @@ -1599,16 +1565,20 @@ impl<'a> Executor<'a> { } // Ensure that all proofs and input bytes were read, otherwise warn the user. - // if self.state.proof_stream_ptr != self.state.proof_stream.len() { - // panic!( - // "Not all proofs were read. Proving will fail during recursion. Did you pass too - // many proofs in or forget to call verify_sp1_proof?" ); - // } + if self.state.proof_stream_ptr != self.state.proof_stream.len() { + tracing::warn!( + "Not all proofs were read. Proving will fail during recursion. Did you pass too + many proofs in or forget to call verify_sp1_proof?" + ); + } if self.state.input_stream_ptr != self.state.input_stream.len() { tracing::warn!("Not all input bytes were read."); } - if self.executor_mode == ExecutorMode::Trace { + if self.emit_global_memory_events + && (self.executor_mode == ExecutorMode::Trace + || self.executor_mode == ExecutorMode::Checkpoint) + { // SECTION: Set up all MemoryInitializeFinalizeEvents needed for memory argument. let memory_finalize_events = &mut self.record.global_memory_finalize_events; diff --git a/crates/core/executor/src/instruction.rs b/crates/core/executor/src/instruction.rs index bc1df27ba0..10dfa5476d 100644 --- a/crates/core/executor/src/instruction.rs +++ b/crates/core/executor/src/instruction.rs @@ -15,7 +15,7 @@ pub struct Instruction { /// The operation to execute. pub opcode: Opcode, /// The first operand. - pub op_a: u32, + pub op_a: u8, /// The second operand. pub op_b: u32, /// The third operand. @@ -31,7 +31,7 @@ impl Instruction { #[must_use] pub const fn new( opcode: Opcode, - op_a: u32, + op_a: u8, op_b: u32, op_c: u32, imm_b: bool, diff --git a/crates/core/executor/src/memory.rs b/crates/core/executor/src/memory.rs index 6e375753d4..a036bbf5ca 100644 --- a/crates/core/executor/src/memory.rs +++ b/crates/core/executor/src/memory.rs @@ -11,10 +11,10 @@ impl Default for Page { } } -const LOG_PAGE_LEN: usize = 15; +const LOG_PAGE_LEN: usize = 14; const PAGE_LEN: usize = 1 << LOG_PAGE_LEN; const MAX_PAGE_COUNT: usize = ((1 << 31) - (1 << 27)) / 4 / PAGE_LEN + 1; -const NO_PAGE: usize = usize::MAX; +const NO_PAGE: u16 = u16::MAX; const PAGE_MASK: usize = PAGE_LEN - 1; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -41,7 +41,7 @@ impl Default for NewPage { pub struct PagedMemory { /// The internal page table. pub page_table: Vec>, - pub index: Vec, + pub index: Vec, } impl PagedMemory { @@ -50,8 +50,7 @@ impl PagedMemory { /// The number of registers in the virtual machine. const NUM_REGISTERS: usize = 32; /// The offset subtracted from the main address space to make it contiguous. - const ADDR_COMPRESS_OFFSET: usize = - Self::NUM_REGISTERS - (Self::NUM_REGISTERS >> Self::NUM_IGNORED_LOWER_BITS); + const ADDR_COMPRESS_OFFSET: usize = Self::NUM_REGISTERS; /// Create a `PagedMemory` with capacity `MAX_PAGE_COUNT`. pub fn new_preallocated() -> Self { @@ -65,7 +64,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index].0[lower].as_ref() + self.page_table[index as usize].0[lower].as_ref() } } @@ -76,7 +75,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index].0[lower].as_mut() + self.page_table[index as usize].0[lower].as_mut() } } @@ -85,11 +84,11 @@ impl PagedMemory { let (upper, lower) = Self::indices(addr); let mut index = self.index[upper]; if index == NO_PAGE { - index = self.page_table.len(); + index = self.page_table.len() as u16; self.index[upper] = index; self.page_table.push(NewPage::new()); } - self.page_table[index].0[lower].replace(value) + self.page_table[index as usize].0[lower].replace(value) } /// Remove the value at the given address if it exists, returning it. @@ -99,7 +98,7 @@ impl PagedMemory { if index == NO_PAGE { None } else { - self.page_table[index].0[lower].take() + self.page_table[index as usize].0[lower].take() } } @@ -109,11 +108,11 @@ impl PagedMemory { let index = self.index[upper]; if index == NO_PAGE { let index = self.page_table.len(); - self.index[upper] = index; + self.index[upper] = index as u16; self.page_table.push(NewPage::new()); Entry::Vacant(VacantEntry { entry: &mut self.page_table[index].0[lower] }) } else { - let option = &mut self.page_table[index].0[lower]; + let option = &mut self.page_table[index as usize].0[lower]; match option { Some(_) => Entry::Occupied(OccupiedEntry { entry: option }), None => Entry::Vacant(VacantEntry { entry: option }), @@ -125,7 +124,7 @@ impl PagedMemory { pub fn keys(&self) -> impl Iterator + '_ { self.index.iter().enumerate().filter(|(_, &i)| i != NO_PAGE).flat_map(|(i, index)| { let upper = i << LOG_PAGE_LEN; - self.page_table[*index] + self.page_table[*index as usize] .0 .iter() .enumerate() @@ -275,7 +274,7 @@ impl IntoIterator for PagedMemory { move |(i, index)| { let upper = i << LOG_PAGE_LEN; let replacement = NewPage::new(); - std::mem::replace(&mut self.page_table[index], replacement) + std::mem::replace(&mut self.page_table[index as usize], replacement) .0 .into_iter() .enumerate() diff --git a/crates/core/executor/src/opcode.rs b/crates/core/executor/src/opcode.rs index 6d0589ca91..818b5b1f2b 100644 --- a/crates/core/executor/src/opcode.rs +++ b/crates/core/executor/src/opcode.rs @@ -100,7 +100,7 @@ pub enum Opcode { /// rd ← rs1 % rs2 (unsigned), pc ← pc + 4 REMU = 37, /// Unimplemented instruction. - UNIMP = 39, + UNIMP = 38, } /// Byte Opcode. diff --git a/crates/core/executor/src/program.rs b/crates/core/executor/src/program.rs index 29743a4c8f..09bb70cac4 100644 --- a/crates/core/executor/src/program.rs +++ b/crates/core/executor/src/program.rs @@ -89,6 +89,13 @@ impl Program { }) .copied() } + + #[must_use] + /// Fetch the instruction at the given program counter. + pub fn fetch(&self, pc: u32) -> &Instruction { + let idx = ((pc - self.pc_base) / 4) as usize; + &self.instructions[idx] + } } impl MachineProgram for Program { diff --git a/crates/core/executor/src/record.rs b/crates/core/executor/src/record.rs index b6c23c45f8..f9e89acb4c 100644 --- a/crates/core/executor/src/record.rs +++ b/crates/core/executor/src/record.rs @@ -23,7 +23,7 @@ use crate::{ /// A record of the execution of a program. /// /// The trace of the execution is represented as a list of "events" that occur every cycle. -#[derive(Default, Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize)] pub struct ExecutionRecord { /// The program. pub program: Arc, @@ -60,16 +60,63 @@ pub struct ExecutionRecord { /// The public values. pub public_values: PublicValues, /// The nonce lookup. - pub nonce_lookup: HashMap, + pub nonce_lookup: Vec, + /// The next nonce to use for a new lookup. + pub next_nonce: u64, /// The shape of the proof. pub shape: Option, } +impl Default for ExecutionRecord { + fn default() -> Self { + let mut res = Self { + program: Arc::default(), + cpu_events: Vec::default(), + add_events: Vec::default(), + mul_events: Vec::default(), + sub_events: Vec::default(), + bitwise_events: Vec::default(), + shift_left_events: Vec::default(), + shift_right_events: Vec::default(), + divrem_events: Vec::default(), + lt_events: Vec::default(), + byte_lookups: HashMap::default(), + precompile_events: PrecompileEvents::default(), + global_memory_initialize_events: Vec::default(), + global_memory_finalize_events: Vec::default(), + cpu_local_memory_access: Vec::default(), + syscall_events: Vec::default(), + public_values: PublicValues::default(), + nonce_lookup: Vec::default(), + next_nonce: 0, + shape: None, + }; + res.nonce_lookup.insert(0, 0); + res + } +} + impl ExecutionRecord { /// Create a new [`ExecutionRecord`]. #[must_use] pub fn new(program: Arc) -> Self { - Self { program, ..Default::default() } + let mut res = Self { program, ..Default::default() }; + res.nonce_lookup.insert(0, 0); + res + } + + /// Create a lookup id for an event. + pub fn create_lookup_id(&mut self) -> LookupId { + // let id = self.nonce_lookup.len() as u64; + let id = self.next_nonce; + self.next_nonce += 1; + // self.nonce_lookup.insert(id as usize, 0); + LookupId(id) + } + + /// Create 6 lookup ids for an ALU event. + pub fn create_lookup_ids(&mut self) -> [LookupId; 6] { + std::array::from_fn(|_| self.create_lookup_id()) } /// Add a mul event to the execution record. @@ -299,7 +346,7 @@ impl MachineRecord for ExecutionRecord { ); stats.insert("local_memory_access_events".to_string(), self.cpu_local_memory_access.len()); if !self.cpu_events.is_empty() { - let shard = self.cpu_events[0].shard; + let shard = self.public_values.shard; stats.insert( "byte_lookups".to_string(), self.byte_lookups.get(&shard).map_or(0, hashbrown::HashMap::len), @@ -337,35 +384,35 @@ impl MachineRecord for ExecutionRecord { fn register_nonces(&mut self, _opts: &Self::Config) { self.add_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.sub_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, (self.add_events.len() + i) as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = (self.add_events.len() + i) as u32; }); self.mul_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.bitwise_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.shift_left_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.shift_right_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.divrem_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); self.lt_events.iter().enumerate().for_each(|(i, event)| { - self.nonce_lookup.insert(event.lookup_id, i as u32); + self.nonce_lookup[event.lookup_id.0 as usize] = i as u32; }); } diff --git a/crates/core/executor/src/register.rs b/crates/core/executor/src/register.rs index 176ef1c951..c24b75decc 100644 --- a/crates/core/executor/src/register.rs +++ b/crates/core/executor/src/register.rs @@ -70,14 +70,14 @@ pub enum Register { } impl Register { - /// Create a new register from a u32. + /// Create a new register from a u8. /// /// # Panics /// /// This function will panic if the register is invalid. #[inline] #[must_use] - pub fn from_u32(value: u32) -> Self { + pub fn from_u8(value: u8) -> Self { match value { 0 => Register::X0, 1 => Register::X1, diff --git a/crates/core/executor/src/syscalls/context.rs b/crates/core/executor/src/syscalls/context.rs index 9db49c5cae..74dfafb279 100644 --- a/crates/core/executor/src/syscalls/context.rs +++ b/crates/core/executor/src/syscalls/context.rs @@ -1,11 +1,16 @@ use hashbrown::HashMap; use crate::{ - events::{LookupId, MemoryLocalEvent, MemoryReadRecord, MemoryWriteRecord}, + events::{ + LookupId, MemoryLocalEvent, MemoryReadRecord, MemoryWriteRecord, PrecompileEvent, + SyscallEvent, + }, record::ExecutionRecord, - Executor, Register, + Executor, ExecutorMode, Register, }; +use super::SyscallCode; + /// A runtime for syscalls that is protected so that developers cannot arbitrarily modify the /// runtime. #[allow(dead_code)] @@ -47,6 +52,19 @@ impl<'a, 'b> SyscallContext<'a, 'b> { &mut self.rt.record } + #[inline] + /// Add a precompile event to the execution record. + pub fn add_precompile_event( + &mut self, + syscall_code: SyscallCode, + syscall_event: SyscallEvent, + event: PrecompileEvent, + ) { + if self.rt.executor_mode == ExecutorMode::Trace { + self.record_mut().precompile_events.add_event(syscall_code, syscall_event, event); + } + } + /// Get the current shard. #[must_use] pub fn current_shard(&self) -> u32 { @@ -91,7 +109,7 @@ impl<'a, 'b> SyscallContext<'a, 'b> { pub fn postprocess(&mut self) -> Vec { let mut syscall_local_mem_events = Vec::new(); - if !self.rt.unconstrained { + if !self.rt.unconstrained && self.rt.executor_mode == ExecutorMode::Trace { // Will need to transfer the existing memory local events in the executor to it's record, // and return all the syscall memory local events. This is similar to what // `bump_record` does. diff --git a/crates/core/executor/src/syscalls/precompiles/edwards/add.rs b/crates/core/executor/src/syscalls/precompiles/edwards/add.rs index 935c580cc8..af446163dd 100644 --- a/crates/core/executor/src/syscalls/precompiles/edwards/add.rs +++ b/crates/core/executor/src/syscalls/precompiles/edwards/add.rs @@ -33,11 +33,7 @@ impl Syscall for EdwardsAddAssignSyscall(rt, arg1, arg2); let syscall_event = rt.rt.syscall_event(event.clk, syscall_code.syscall_id(), arg1, arg2, event.lookup_id); - rt.record_mut().add_precompile_event( - syscall_code, - syscall_event, - PrecompileEvent::EdAdd(event), - ); + rt.add_precompile_event(syscall_code, syscall_event, PrecompileEvent::EdAdd(event)); None } } diff --git a/crates/core/executor/src/syscalls/precompiles/edwards/decompress.rs b/crates/core/executor/src/syscalls/precompiles/edwards/decompress.rs index 287101fbfd..6e790ab133 100644 --- a/crates/core/executor/src/syscalls/precompiles/edwards/decompress.rs +++ b/crates/core/executor/src/syscalls/precompiles/edwards/decompress.rs @@ -80,11 +80,7 @@ impl Syscall for EdwardsDecompressSyscall { }; let syscall_event = rt.rt.syscall_event(start_clk, syscall_code.syscall_id(), arg1, sign, event.lookup_id); - rt.record_mut().add_precompile_event( - syscall_code, - syscall_event, - PrecompileEvent::EdDecompress(event), - ); + rt.add_precompile_event(syscall_code, syscall_event, PrecompileEvent::EdDecompress(event)); None } diff --git a/crates/core/executor/src/syscalls/precompiles/fptower/fp.rs b/crates/core/executor/src/syscalls/precompiles/fptower/fp.rs index 3ce04230ec..ddba0892c6 100644 --- a/crates/core/executor/src/syscalls/precompiles/fptower/fp.rs +++ b/crates/core/executor/src/syscalls/precompiles/fptower/fp.rs @@ -98,7 +98,7 @@ impl Syscall for FpOpSyscall

{ arg2, event.lookup_id, ); - rt.record_mut().add_precompile_event( + rt.add_precompile_event( syscall_code_key, syscall_event, PrecompileEvent::Bn254Fp(event), @@ -119,7 +119,7 @@ impl Syscall for FpOpSyscall

{ arg2, event.lookup_id, ); - rt.record_mut().add_precompile_event( + rt.add_precompile_event( syscall_code_key, syscall_event, PrecompileEvent::Bls12381Fp(event), diff --git a/crates/core/executor/src/syscalls/precompiles/fptower/fp2_addsub.rs b/crates/core/executor/src/syscalls/precompiles/fptower/fp2_addsub.rs index e2563a6bce..f583432310 100644 --- a/crates/core/executor/src/syscalls/precompiles/fptower/fp2_addsub.rs +++ b/crates/core/executor/src/syscalls/precompiles/fptower/fp2_addsub.rs @@ -104,7 +104,7 @@ impl Syscall for Fp2AddSubSyscall

{ arg2, event.lookup_id, ); - rt.record_mut().add_precompile_event( + rt.add_precompile_event( syscall_code_key, syscall_event, PrecompileEvent::Bn254Fp2AddSub(event), @@ -125,7 +125,7 @@ impl Syscall for Fp2AddSubSyscall

{ arg2, event.lookup_id, ); - rt.record_mut().add_precompile_event( + rt.add_precompile_event( syscall_code_key, syscall_event, PrecompileEvent::Bls12381Fp2AddSub(event), diff --git a/crates/core/executor/src/syscalls/precompiles/fptower/fp2_mul.rs b/crates/core/executor/src/syscalls/precompiles/fptower/fp2_mul.rs index 46598ef2b2..5089c00726 100644 --- a/crates/core/executor/src/syscalls/precompiles/fptower/fp2_mul.rs +++ b/crates/core/executor/src/syscalls/precompiles/fptower/fp2_mul.rs @@ -85,12 +85,12 @@ impl Syscall for Fp2MulSyscall

{ let syscall_event = rt.rt.syscall_event(clk, syscall_code.syscall_id(), arg1, arg2, event.lookup_id); match P::FIELD_TYPE { - FieldType::Bn254 => rt.record_mut().add_precompile_event( + FieldType::Bn254 => rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Bn254Fp2Mul(event), ), - FieldType::Bls12381 => rt.record_mut().add_precompile_event( + FieldType::Bls12381 => rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Bls12381Fp2Mul(event), diff --git a/crates/core/executor/src/syscalls/precompiles/keccak256/permute.rs b/crates/core/executor/src/syscalls/precompiles/keccak256/permute.rs index f33019f8b2..be3743e1f0 100644 --- a/crates/core/executor/src/syscalls/precompiles/keccak256/permute.rs +++ b/crates/core/executor/src/syscalls/precompiles/keccak256/permute.rs @@ -78,7 +78,7 @@ impl Syscall for Keccak256PermuteSyscall { }); let syscall_event = rt.rt.syscall_event(start_clk, syscall_code.syscall_id(), arg1, arg2, lookup_id); - rt.record_mut().add_precompile_event(syscall_code, syscall_event, event); + rt.add_precompile_event(syscall_code, syscall_event, event); None } diff --git a/crates/core/executor/src/syscalls/precompiles/sha256/compress.rs b/crates/core/executor/src/syscalls/precompiles/sha256/compress.rs index 8d87fe7376..db1e9c42ec 100644 --- a/crates/core/executor/src/syscalls/precompiles/sha256/compress.rs +++ b/crates/core/executor/src/syscalls/precompiles/sha256/compress.rs @@ -110,7 +110,7 @@ impl Syscall for Sha256CompressSyscall { }); let syscall_event = rt.rt.syscall_event(start_clk, syscall_code.syscall_id(), arg1, arg2, lookup_id); - rt.record_mut().add_precompile_event(syscall_code, syscall_event, event); + rt.add_precompile_event(syscall_code, syscall_event, event); None } diff --git a/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs b/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs index 36f1b56542..cc5e288fb6 100644 --- a/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs +++ b/crates/core/executor/src/syscalls/precompiles/sha256/extend.rs @@ -22,11 +22,11 @@ impl Syscall for Sha256ExtendSyscall { assert!(arg2 == 0, "arg2 must be 0"); let w_ptr_init = w_ptr; - let mut w_i_minus_15_reads = Vec::new(); - let mut w_i_minus_2_reads = Vec::new(); - let mut w_i_minus_16_reads = Vec::new(); - let mut w_i_minus_7_reads = Vec::new(); - let mut w_i_writes = Vec::new(); + let mut w_i_minus_15_reads = Vec::with_capacity(48); + let mut w_i_minus_2_reads = Vec::with_capacity(48); + let mut w_i_minus_16_reads = Vec::with_capacity(48); + let mut w_i_minus_7_reads = Vec::with_capacity(48); + let mut w_i_writes = Vec::with_capacity(48); for i in 16..64 { // Read w[i-15]. let (record, w_i_minus_15) = rt.mr(w_ptr + (i - 15) * 4); @@ -77,7 +77,7 @@ impl Syscall for Sha256ExtendSyscall { }); let syscall_event = rt.rt.syscall_event(clk_init, syscall_code.syscall_id(), arg1, arg2, lookup_id); - rt.record_mut().add_precompile_event(syscall_code, syscall_event, event); + rt.add_precompile_event(syscall_code, syscall_event, event); None } diff --git a/crates/core/executor/src/syscalls/precompiles/uint256.rs b/crates/core/executor/src/syscalls/precompiles/uint256.rs index a8d5c54fdc..769ad0beb8 100644 --- a/crates/core/executor/src/syscalls/precompiles/uint256.rs +++ b/crates/core/executor/src/syscalls/precompiles/uint256.rs @@ -82,7 +82,7 @@ impl Syscall for Uint256MulSyscall { }); let sycall_event = rt.rt.syscall_event(clk, syscall_code.syscall_id(), arg1, arg2, lookup_id); - rt.record_mut().add_precompile_event(syscall_code, sycall_event, event); + rt.add_precompile_event(syscall_code, sycall_event, event); None } diff --git a/crates/core/executor/src/syscalls/precompiles/weierstrass/add.rs b/crates/core/executor/src/syscalls/precompiles/weierstrass/add.rs index 1456b9870f..f643196a77 100644 --- a/crates/core/executor/src/syscalls/precompiles/weierstrass/add.rs +++ b/crates/core/executor/src/syscalls/precompiles/weierstrass/add.rs @@ -30,19 +30,19 @@ impl Syscall for WeierstrassAddAssignSyscall { let syscall_event = rt.rt.syscall_event(event.clk, syscall_code.syscall_id(), arg1, arg2, event.lookup_id); match E::CURVE_TYPE { - CurveType::Secp256k1 => rt.record_mut().add_precompile_event( + CurveType::Secp256k1 => rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Secp256k1Add(event), ), CurveType::Bn254 => { - rt.record_mut().add_precompile_event( + rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Bn254Add(event), ); } - CurveType::Bls12381 => rt.record_mut().add_precompile_event( + CurveType::Bls12381 => rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Bls12381Add(event), diff --git a/crates/core/executor/src/syscalls/precompiles/weierstrass/decompress.rs b/crates/core/executor/src/syscalls/precompiles/weierstrass/decompress.rs index df056337a1..3c2069e118 100644 --- a/crates/core/executor/src/syscalls/precompiles/weierstrass/decompress.rs +++ b/crates/core/executor/src/syscalls/precompiles/weierstrass/decompress.rs @@ -30,12 +30,12 @@ impl Syscall for WeierstrassDecompressSyscall { let syscall_event = rt.rt.syscall_event(event.clk, syscall_code.syscall_id(), arg1, arg2, event.lookup_id); match E::CURVE_TYPE { - CurveType::Secp256k1 => rt.record_mut().add_precompile_event( + CurveType::Secp256k1 => rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Secp256k1Decompress(event), ), - CurveType::Bls12381 => rt.record_mut().add_precompile_event( + CurveType::Bls12381 => rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Bls12381Decompress(event), diff --git a/crates/core/executor/src/syscalls/precompiles/weierstrass/double.rs b/crates/core/executor/src/syscalls/precompiles/weierstrass/double.rs index 70e7074853..26d3090310 100644 --- a/crates/core/executor/src/syscalls/precompiles/weierstrass/double.rs +++ b/crates/core/executor/src/syscalls/precompiles/weierstrass/double.rs @@ -31,21 +31,21 @@ impl Syscall for WeierstrassDoubleAssignSyscall { rt.rt.syscall_event(event.clk, syscall_code.syscall_id(), arg1, arg2, event.lookup_id); match E::CURVE_TYPE { CurveType::Secp256k1 => { - rt.record_mut().add_precompile_event( + rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Secp256k1Double(event), ); } CurveType::Bn254 => { - rt.record_mut().add_precompile_event( + rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Bn254Double(event), ); } CurveType::Bls12381 => { - rt.record_mut().add_precompile_event( + rt.add_precompile_event( syscall_code, syscall_event, PrecompileEvent::Bls12381Double(event), diff --git a/crates/core/machine/Cargo.toml b/crates/core/machine/Cargo.toml index 7e2bd5a50a..3b0b0f34f9 100644 --- a/crates/core/machine/Cargo.toml +++ b/crates/core/machine/Cargo.toml @@ -54,6 +54,7 @@ static_assertions = "1.1.0" sp1-stark = { workspace = true } sp1-core-executor = { workspace = true } sp1-curves = { workspace = true } +vec_map = "0.8.2" [dev-dependencies] tiny-keccak = { version = "2.0.2", features = ["keccak"] } diff --git a/crates/core/machine/src/alu/add_sub/mod.rs b/crates/core/machine/src/alu/add_sub/mod.rs index bf6dabef42..d276820755 100644 --- a/crates/core/machine/src/alu/add_sub/mod.rs +++ b/crates/core/machine/src/alu/add_sub/mod.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ events::{AluEvent, ByteLookupEvent, ByteRecord}, ExecutionRecord, Opcode, Program, @@ -19,7 +19,10 @@ use sp1_stark::{ Word, }; -use crate::{operations::AddOperation, utils::pad_rows_fixed}; +use crate::{ + operations::AddOperation, + utils::{next_power_of_two, zeroed_f_vec}, +}; /// The number of main trace columns for `AddSubChip`. pub const NUM_ADD_SUB_COLS: usize = size_of::>(); @@ -79,46 +82,29 @@ impl MachineAir for AddSubChip { std::cmp::max((input.add_events.len() + input.sub_events.len()) / num_cpus::get(), 1); let merged_events = input.add_events.iter().chain(input.sub_events.iter()).collect::>(); - - let row_batches = merged_events - .par_chunks(chunk_size) - .map(|events| { - let rows = events - .iter() - .map(|event| { - let mut row = [F::zero(); NUM_ADD_SUB_COLS]; - let cols: &mut AddSubCols = row.as_mut_slice().borrow_mut(); - let mut blu = Vec::new(); - self.event_to_row(event, cols, &mut blu); - row - }) - .collect::>(); - rows - }) - .collect::>(); - - let mut rows: Vec<[F; NUM_ADD_SUB_COLS]> = vec![]; - for row_batch in row_batches { - rows.extend(row_batch); - } - - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_ADD_SUB_COLS], - input.fixed_log2_rows::(self), + let nb_rows = merged_events.len(); + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_ADD_SUB_COLS); + + values.chunks_mut(chunk_size * NUM_ADD_SUB_COLS).enumerate().par_bridge().for_each( + |(i, rows)| { + rows.chunks_mut(NUM_ADD_SUB_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + let cols: &mut AddSubCols = row.borrow_mut(); + + if idx < merged_events.len() { + let mut byte_lookup_events = Vec::new(); + let event = &merged_events[idx]; + self.event_to_row(event, cols, &mut byte_lookup_events); + } + cols.nonce = F::from_canonical_usize(idx); + }); + }, ); - // Convert the trace to a row major matrix. - let mut trace = - RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_ADD_SUB_COLS); - - // Write the nonces to the trace. - for i in 0..trace.height() { - let cols: &mut AddSubCols = - trace.values[i * NUM_ADD_SUB_COLS..(i + 1) * NUM_ADD_SUB_COLS].borrow_mut(); - cols.nonce = F::from_canonical_usize(i); - } - trace + // Convert the trace to a row major matrix. + RowMajorMatrix::new(values, NUM_ADD_SUB_COLS) } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/alu/divrem/mod.rs b/crates/core/machine/src/alu/divrem/mod.rs index 9170b87b5f..1d4d539fc4 100644 --- a/crates/core/machine/src/alu/divrem/mod.rs +++ b/crates/core/machine/src/alu/divrem/mod.rs @@ -279,11 +279,19 @@ impl MachineAir for DivRemChip { // Set the `alu_event` flags. cols.abs_c_alu_event = cols.c_neg * cols.is_real; cols.abs_c_alu_event_nonce = F::from_canonical_u32( - input.nonce_lookup.get(&event.sub_lookups[4]).copied().unwrap_or_default(), + input + .nonce_lookup + .get(event.sub_lookups[4].0 as usize) + .copied() + .unwrap_or_default(), ); cols.abs_rem_alu_event = cols.rem_neg * cols.is_real; cols.abs_rem_alu_event_nonce = F::from_canonical_u32( - input.nonce_lookup.get(&event.sub_lookups[5]).copied().unwrap_or_default(), + input + .nonce_lookup + .get(event.sub_lookups[5].0 as usize) + .copied() + .unwrap_or_default(), ); // Insert the MSB lookup events. @@ -344,16 +352,24 @@ impl MachineAir for DivRemChip { // Insert the necessary multiplication & LT events. { cols.lower_nonce = F::from_canonical_u32( - input.nonce_lookup.get(&event.sub_lookups[0]).copied().unwrap_or_default(), + input + .nonce_lookup + .get(event.sub_lookups[0].0 as usize) + .copied() + .unwrap_or_default(), ); cols.upper_nonce = F::from_canonical_u32( - input.nonce_lookup.get(&event.sub_lookups[1]).copied().unwrap_or_default(), + input + .nonce_lookup + .get(event.sub_lookups[1].0 as usize) + .copied() + .unwrap_or_default(), ); if is_signed_operation(event.opcode) { cols.abs_nonce = F::from_canonical_u32( input .nonce_lookup - .get(&event.sub_lookups[2]) + .get(event.sub_lookups[2].0 as usize) .copied() .unwrap_or_default(), ); @@ -361,7 +377,7 @@ impl MachineAir for DivRemChip { cols.abs_nonce = F::from_canonical_u32( input .nonce_lookup - .get(&event.sub_lookups[3]) + .get(event.sub_lookups[3].0 as usize) .copied() .unwrap_or_default(), ); diff --git a/crates/core/machine/src/alu/lt/mod.rs b/crates/core/machine/src/alu/lt/mod.rs index 211cf5d912..876fdaaf8f 100644 --- a/crates/core/machine/src/alu/lt/mod.rs +++ b/crates/core/machine/src/alu/lt/mod.rs @@ -19,7 +19,7 @@ use sp1_stark::{ Word, }; -use crate::utils::pad_rows_fixed; +use crate::utils::{next_power_of_two, zeroed_f_vec}; /// The number of main trace columns for `LtChip`. pub const NUM_LT_COLS: usize = size_of::>(); @@ -107,38 +107,31 @@ impl MachineAir for LtChip { _: &mut ExecutionRecord, ) -> RowMajorMatrix { // Generate the trace rows for each event. - let mut rows = input - .lt_events - .par_iter() - .map(|event| { - let mut row = [F::zero(); NUM_LT_COLS]; - let mut new_byte_lookup_events: Vec = Vec::new(); - let cols: &mut LtCols = row.as_mut_slice().borrow_mut(); - self.event_to_row(event, cols, &mut new_byte_lookup_events); - - row - }) - .collect::>(); - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_LT_COLS], - input.fixed_log2_rows::(self), + let nb_rows = input.lt_events.len(); + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_LT_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values.chunks_mut(chunk_size * NUM_LT_COLS).enumerate().par_bridge().for_each( + |(i, rows)| { + rows.chunks_mut(NUM_LT_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + let cols: &mut LtCols = row.borrow_mut(); + + if idx < nb_rows { + let mut byte_lookup_events = Vec::new(); + let event = &input.lt_events[idx]; + self.event_to_row(event, cols, &mut byte_lookup_events); + } + cols.nonce = F::from_canonical_usize(idx); + }); + }, ); // Convert the trace to a row major matrix. - let mut trace = - RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_LT_COLS); - - // Write the nonces to the trace. - for i in 0..trace.height() { - let cols: &mut LtCols = - trace.values[i * NUM_LT_COLS..(i + 1) * NUM_LT_COLS].borrow_mut(); - cols.nonce = F::from_canonical_usize(i); - } - trace + RowMajorMatrix::new(values, NUM_LT_COLS) } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/alu/mul/mod.rs b/crates/core/machine/src/alu/mul/mod.rs index 0453cb5f87..6a1ce272fe 100644 --- a/crates/core/machine/src/alu/mul/mod.rs +++ b/crates/core/machine/src/alu/mul/mod.rs @@ -35,19 +35,24 @@ use core::{ mem::size_of, }; +use hashbrown::HashMap; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ - events::{ByteLookupEvent, ByteRecord}, + events::{AluEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, }; use sp1_derive::AlignedBorrow; use sp1_primitives::consts::WORD_SIZE; -use sp1_stark::{air::MachineAir, MachineRecord, Word}; +use sp1_stark::{air::MachineAir, Word}; -use crate::{air::SP1CoreAirBuilder, alu::mul::utils::get_msb, utils::pad_rows_fixed}; +use crate::{ + air::SP1CoreAirBuilder, + alu::mul::utils::get_msb, + utils::{next_power_of_two, zeroed_f_vec}, +}; /// The number of main trace columns for `MulChip`. pub const NUM_MUL_COLS: usize = size_of::>(); @@ -131,148 +136,54 @@ impl MachineAir for MulChip { fn generate_trace( &self, input: &ExecutionRecord, - output: &mut ExecutionRecord, + _: &mut ExecutionRecord, ) -> RowMajorMatrix { - let mul_events = input.mul_events.clone(); - // Compute the chunk size based on the number of events and the number of CPUs. - let chunk_size = std::cmp::max(mul_events.len() / num_cpus::get(), 1); + // Generate the trace rows for each event. + let nb_rows = input.mul_events.len(); + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_MUL_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values.chunks_mut(chunk_size * NUM_MUL_COLS).enumerate().par_bridge().for_each( + |(i, rows)| { + rows.chunks_mut(NUM_MUL_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + let cols: &mut MulCols = row.borrow_mut(); + + if idx < nb_rows { + let mut byte_lookup_events = Vec::new(); + let event = &input.mul_events[idx]; + self.event_to_row(event, cols, &mut byte_lookup_events); + } + cols.nonce = F::from_canonical_usize(idx); + }); + }, + ); - // Generate the trace rows & corresponding records for each chunk of events in parallel. - let rows_and_records = mul_events + // Convert the trace to a row major matrix. + + RowMajorMatrix::new(values, NUM_MUL_COLS) + } + + fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { + let chunk_size = std::cmp::max(input.mul_events.len() / num_cpus::get(), 1); + + let blu_batches = input + .mul_events .par_chunks(chunk_size) .map(|events| { - let mut record = ExecutionRecord::default(); - let rows = events - .iter() - .map(|event| { - // Ensure that the opcode is MUL, MULHU, MULH, or MULHSU. - assert!( - event.opcode == Opcode::MUL - || event.opcode == Opcode::MULHU - || event.opcode == Opcode::MULH - || event.opcode == Opcode::MULHSU - ); - let mut row = [F::zero(); NUM_MUL_COLS]; - let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); - - let a_word = event.a.to_le_bytes(); - let b_word = event.b.to_le_bytes(); - let c_word = event.c.to_le_bytes(); - - let mut b = b_word.to_vec(); - let mut c = c_word.to_vec(); - - // Handle b and c's signs. - { - let b_msb = get_msb(b_word); - cols.b_msb = F::from_canonical_u8(b_msb); - let c_msb = get_msb(c_word); - cols.c_msb = F::from_canonical_u8(c_msb); - - // If b is signed and it is negative, sign extend b. - if (event.opcode == Opcode::MULH || event.opcode == Opcode::MULHSU) - && b_msb == 1 - { - cols.b_sign_extend = F::one(); - b.resize(PRODUCT_SIZE, BYTE_MASK); - } - - // If c is signed and it is negative, sign extend c. - if event.opcode == Opcode::MULH && c_msb == 1 { - cols.c_sign_extend = F::one(); - c.resize(PRODUCT_SIZE, BYTE_MASK); - } - - // Insert the MSB lookup events. - { - let words = [b_word, c_word]; - let mut blu_events: Vec = vec![]; - for word in words.iter() { - let most_significant_byte = word[WORD_SIZE - 1]; - blu_events.push(ByteLookupEvent { - shard: event.shard, - opcode: ByteOpcode::MSB, - a1: get_msb(*word) as u16, - a2: 0, - b: most_significant_byte, - c: 0, - }); - } - record.add_byte_lookup_events(blu_events); - } - } - - let mut product = [0u32; PRODUCT_SIZE]; - for i in 0..b.len() { - for j in 0..c.len() { - if i + j < PRODUCT_SIZE { - product[i + j] += (b[i] as u32) * (c[j] as u32); - } - } - } - - // Calculate the correct product using the `product` array. We store the - // correct carry value for verification. - let base = (1 << BYTE_SIZE) as u32; - let mut carry = [0u32; PRODUCT_SIZE]; - for i in 0..PRODUCT_SIZE { - carry[i] = product[i] / base; - product[i] %= base; - if i + 1 < PRODUCT_SIZE { - product[i + 1] += carry[i]; - } - cols.carry[i] = F::from_canonical_u32(carry[i]); - } - - cols.product = product.map(F::from_canonical_u32); - cols.a = Word(a_word.map(F::from_canonical_u8)); - cols.b = Word(b_word.map(F::from_canonical_u8)); - cols.c = Word(c_word.map(F::from_canonical_u8)); - cols.is_real = F::one(); - cols.is_mul = F::from_bool(event.opcode == Opcode::MUL); - cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); - cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); - cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); - cols.shard = F::from_canonical_u32(event.shard); - - // Range check. - { - record.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); - record.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); - } - row - }) - .collect::>(); - (rows, record) + let mut blu: HashMap> = HashMap::new(); + events.iter().for_each(|event| { + let mut row = [F::zero(); NUM_MUL_COLS]; + let cols: &mut MulCols = row.as_mut_slice().borrow_mut(); + self.event_to_row(event, cols, &mut blu); + }); + blu }) .collect::>(); - // Generate the trace rows for each event. - let mut rows: Vec<[F; NUM_MUL_COLS]> = vec![]; - for mut row_and_record in rows_and_records { - rows.extend(row_and_record.0); - output.append(&mut row_and_record.1); - } - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_MUL_COLS], - input.fixed_log2_rows::(self), - ); - - // Convert the trace to a row major matrix. - let mut trace = - RowMajorMatrix::new(rows.into_iter().flatten().collect::>(), NUM_MUL_COLS); - - // Write the nonces to the trace. - for i in 0..trace.height() { - let cols: &mut MulCols = - trace.values[i * NUM_MUL_COLS..(i + 1) * NUM_MUL_COLS].borrow_mut(); - cols.nonce = F::from_canonical_usize(i); - } - - trace + output.add_sharded_byte_lookup_events(blu_batches.iter().collect::>()); } fn included(&self, shard: &Self::Record) -> bool { @@ -284,6 +195,100 @@ impl MachineAir for MulChip { } } +impl MulChip { + /// Create a row from an event. + fn event_to_row( + &self, + event: &AluEvent, + cols: &mut MulCols, + blu: &mut impl ByteRecord, + ) { + let a_word = event.a.to_le_bytes(); + let b_word = event.b.to_le_bytes(); + let c_word = event.c.to_le_bytes(); + + let mut b = b_word.to_vec(); + let mut c = c_word.to_vec(); + + // Handle b and c's signs. + { + let b_msb = get_msb(b_word); + cols.b_msb = F::from_canonical_u8(b_msb); + let c_msb = get_msb(c_word); + cols.c_msb = F::from_canonical_u8(c_msb); + + // If b is signed and it is negative, sign extend b. + if (event.opcode == Opcode::MULH || event.opcode == Opcode::MULHSU) && b_msb == 1 { + cols.b_sign_extend = F::one(); + b.resize(PRODUCT_SIZE, BYTE_MASK); + } + + // If c is signed and it is negative, sign extend c. + if event.opcode == Opcode::MULH && c_msb == 1 { + cols.c_sign_extend = F::one(); + c.resize(PRODUCT_SIZE, BYTE_MASK); + } + + // Insert the MSB lookup events. + { + let words = [b_word, c_word]; + let mut blu_events: Vec = vec![]; + for word in words.iter() { + let most_significant_byte = word[WORD_SIZE - 1]; + blu_events.push(ByteLookupEvent { + shard: event.shard, + opcode: ByteOpcode::MSB, + a1: get_msb(*word) as u16, + a2: 0, + b: most_significant_byte, + c: 0, + }); + } + blu.add_byte_lookup_events(blu_events); + } + } + + let mut product = [0u32; PRODUCT_SIZE]; + for i in 0..b.len() { + for j in 0..c.len() { + if i + j < PRODUCT_SIZE { + product[i + j] += (b[i] as u32) * (c[j] as u32); + } + } + } + + // Calculate the correct product using the `product` array. We store the + // correct carry value for verification. + let base = (1 << BYTE_SIZE) as u32; + let mut carry = [0u32; PRODUCT_SIZE]; + for i in 0..PRODUCT_SIZE { + carry[i] = product[i] / base; + product[i] %= base; + if i + 1 < PRODUCT_SIZE { + product[i + 1] += carry[i]; + } + cols.carry[i] = F::from_canonical_u32(carry[i]); + } + + cols.product = product.map(F::from_canonical_u32); + cols.a = Word(a_word.map(F::from_canonical_u8)); + cols.b = Word(b_word.map(F::from_canonical_u8)); + cols.c = Word(c_word.map(F::from_canonical_u8)); + cols.is_real = F::one(); + cols.is_mul = F::from_bool(event.opcode == Opcode::MUL); + cols.is_mulh = F::from_bool(event.opcode == Opcode::MULH); + cols.is_mulhu = F::from_bool(event.opcode == Opcode::MULHU); + cols.is_mulhsu = F::from_bool(event.opcode == Opcode::MULHSU); + cols.shard = F::from_canonical_u32(event.shard); + + // Range check. + { + blu.add_u16_range_checks(event.shard, &carry.map(|x| x as u16)); + blu.add_u8_range_checks(event.shard, &product.map(|x| x as u8)); + } + } +} + impl BaseAir for MulChip { fn width(&self) -> usize { NUM_MUL_COLS diff --git a/crates/core/machine/src/alu/sr/mod.rs b/crates/core/machine/src/alu/sr/mod.rs index 9c19b4491c..b26c949945 100644 --- a/crates/core/machine/src/alu/sr/mod.rs +++ b/crates/core/machine/src/alu/sr/mod.rs @@ -52,7 +52,7 @@ use itertools::Itertools; use p3_air::{Air, AirBuilder, BaseAir}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; -use p3_maybe_rayon::prelude::{ParallelIterator, ParallelSlice}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use sp1_core_executor::{ events::{AluEvent, ByteLookupEvent, ByteRecord}, ByteOpcode, ExecutionRecord, Opcode, Program, @@ -65,7 +65,7 @@ use crate::{ air::SP1CoreAirBuilder, alu::sr::utils::{nb_bits_to_shift, nb_bytes_to_shift}, bytes::utils::shr_carry, - utils::pad_rows_fixed, + utils::{next_power_of_two, zeroed_f_vec}, }; /// The number of main trace columns for `ShiftRightChip`. @@ -149,54 +149,33 @@ impl MachineAir for ShiftRightChip { _: &mut ExecutionRecord, ) -> RowMajorMatrix { // Generate the trace rows for each event. - let mut rows: Vec<[F; NUM_SHIFT_RIGHT_COLS]> = Vec::new(); - let sr_events = input.shift_right_events.clone(); - for event in sr_events.iter() { - assert!(event.opcode == Opcode::SRL || event.opcode == Opcode::SRA); - let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; - let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); - let mut blu = Vec::new(); - self.event_to_row(event, cols, &mut blu); - rows.push(row); - } - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_SHIFT_RIGHT_COLS], - input.fixed_log2_rows::(self), + let nb_rows = input.shift_right_events.len(); + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_SHIFT_RIGHT_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values.chunks_mut(chunk_size * NUM_SHIFT_RIGHT_COLS).enumerate().par_bridge().for_each( + |(i, rows)| { + rows.chunks_mut(NUM_SHIFT_RIGHT_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + let cols: &mut ShiftRightCols = row.borrow_mut(); + + if idx < nb_rows { + let mut byte_lookup_events = Vec::new(); + let event = &input.shift_right_events[idx]; + self.event_to_row(event, cols, &mut byte_lookup_events); + } else { + cols.shift_by_n_bits[0] = F::one(); + cols.shift_by_n_bytes[0] = F::one(); + } + cols.nonce = F::from_canonical_usize(idx); + }); + }, ); // Convert the trace to a row major matrix. - let mut trace = RowMajorMatrix::new( - rows.into_iter().flatten().collect::>(), - NUM_SHIFT_RIGHT_COLS, - ); - - // Create the template for the padded rows. These are fake rows that don't fail on some - // sanity checks. - let padded_row_template = { - let mut row = [F::zero(); NUM_SHIFT_RIGHT_COLS]; - let cols: &mut ShiftRightCols = row.as_mut_slice().borrow_mut(); - // Shift 0 by 0 bits and 0 bytes. - // cols.is_srl = F::one(); - cols.shift_by_n_bits[0] = F::one(); - cols.shift_by_n_bytes[0] = F::one(); - row - }; - debug_assert!(padded_row_template.len() == NUM_SHIFT_RIGHT_COLS); - for i in input.shift_right_events.len() * NUM_SHIFT_RIGHT_COLS..trace.values.len() { - trace.values[i] = padded_row_template[i % NUM_SHIFT_RIGHT_COLS]; - } - - // Write the nonces to the trace. - for i in 0..trace.height() { - let cols: &mut ShiftRightCols = - trace.values[i * NUM_SHIFT_RIGHT_COLS..(i + 1) * NUM_SHIFT_RIGHT_COLS].borrow_mut(); - cols.nonce = F::from_canonical_usize(i); - } - - trace + RowMajorMatrix::new(values, NUM_SHIFT_RIGHT_COLS) } fn generate_dependencies(&self, input: &Self::Record, output: &mut Self::Record) { diff --git a/crates/core/machine/src/cpu/columns/instruction.rs b/crates/core/machine/src/cpu/columns/instruction.rs index a16de4fb08..27dd1f6a91 100644 --- a/crates/core/machine/src/cpu/columns/instruction.rs +++ b/crates/core/machine/src/cpu/columns/instruction.rs @@ -27,13 +27,13 @@ pub struct InstructionCols { } impl InstructionCols { - pub fn populate(&mut self, instruction: Instruction) { + pub fn populate(&mut self, instruction: &Instruction) { self.opcode = instruction.opcode.as_field::(); - self.op_a = instruction.op_a.into(); + self.op_a = (instruction.op_a as u32).into(); self.op_b = instruction.op_b.into(); self.op_c = instruction.op_c.into(); - self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u32); + self.op_a_0 = F::from_bool(instruction.op_a == Register::X0 as u8); } } diff --git a/crates/core/machine/src/cpu/columns/opcode.rs b/crates/core/machine/src/cpu/columns/opcode.rs index 9b4344d036..4de8f11ba7 100644 --- a/crates/core/machine/src/cpu/columns/opcode.rs +++ b/crates/core/machine/src/cpu/columns/opcode.rs @@ -63,7 +63,7 @@ pub struct OpcodeSelectorCols { } impl OpcodeSelectorCols { - pub fn populate(&mut self, instruction: Instruction) { + pub fn populate(&mut self, instruction: &Instruction) { self.imm_b = F::from_bool(instruction.imm_b); self.imm_c = F::from_bool(instruction.imm_c); diff --git a/crates/core/machine/src/cpu/trace.rs b/crates/core/machine/src/cpu/trace.rs index 01b1489127..5a43202608 100644 --- a/crates/core/machine/src/cpu/trace.rs +++ b/crates/core/machine/src/cpu/trace.rs @@ -1,10 +1,10 @@ use hashbrown::HashMap; use itertools::Itertools; use sp1_core_executor::{ - events::{ByteLookupEvent, ByteRecord, CpuEvent, LookupId, MemoryRecordEnum}, + events::{ByteLookupEvent, ByteRecord, CpuEvent, MemoryRecordEnum}, syscalls::SyscallCode, ByteOpcode::{self, U16Range}, - CoreShape, ExecutionRecord, Opcode, Program, + ExecutionRecord, Instruction, Opcode, Program, Register::X0, }; use sp1_primitives::consts::WORD_SIZE; @@ -13,15 +13,10 @@ use std::{array, borrow::BorrowMut}; use p3_field::{PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; -use p3_maybe_rayon::prelude::{ - IntoParallelRefMutIterator, ParallelBridge, ParallelIterator, ParallelSlice, -}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator, ParallelSlice}; use tracing::instrument; -use super::{ - columns::{CPU_COL_MAP, NUM_CPU_COLS}, - CpuChip, -}; +use super::{columns::NUM_CPU_COLS, CpuChip}; use crate::{cpu::columns::CpuCols, memory::MemoryCols, utils::zeroed_f_vec}; impl MachineAir for CpuChip { @@ -38,7 +33,16 @@ impl MachineAir for CpuChip { input: &ExecutionRecord, _: &mut ExecutionRecord, ) -> RowMajorMatrix { - let mut values = zeroed_f_vec(input.cpu_events.len() * NUM_CPU_COLS); + let n_real_rows = input.cpu_events.len(); + let padded_nb_rows = if let Some(shape) = &input.shape { + 1 << shape.inner[&MachineAir::::name(self)] + } else if n_real_rows < 16 { + 16 + } else { + n_real_rows.next_power_of_two() + }; + let mut values = zeroed_f_vec(padded_nb_rows * NUM_CPU_COLS); + let shard = input.public_values.execution_shard; let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); values.chunks_mut(chunk_size * NUM_CPU_COLS).enumerate().par_bridge().for_each( @@ -46,30 +50,36 @@ impl MachineAir for CpuChip { rows.chunks_mut(NUM_CPU_COLS).enumerate().for_each(|(j, row)| { let idx = i * chunk_size + j; let cols: &mut CpuCols = row.borrow_mut(); - let mut byte_lookup_events = Vec::new(); - self.event_to_row( - &input.cpu_events[idx], - &input.nonce_lookup, - cols, - &mut byte_lookup_events, - ); + + if idx >= input.cpu_events.len() { + cols.selectors.imm_b = F::one(); + cols.selectors.imm_c = F::one(); + } else { + let mut byte_lookup_events = Vec::new(); + let event = &input.cpu_events[idx]; + let instruction = &input.program.fetch(event.pc); + self.event_to_row( + event, + &input.nonce_lookup, + cols, + &mut byte_lookup_events, + shard, + instruction, + ); + } }); }, ); // Convert the trace to a row major matrix. - let mut trace = RowMajorMatrix::new(values, NUM_CPU_COLS); - - // Pad the trace to a power of two. - Self::pad_to_power_of_two::(self, &input.shape, &mut trace.values); - - trace + RowMajorMatrix::new(values, NUM_CPU_COLS) } #[instrument(name = "generate cpu dependencies", level = "debug", skip_all)] fn generate_dependencies(&self, input: &ExecutionRecord, output: &mut ExecutionRecord) { // Generate the trace rows for each event. let chunk_size = std::cmp::max(input.cpu_events.len() / num_cpus::get(), 1); + let shard = input.public_values.execution_shard; let blu_events: Vec<_> = input .cpu_events @@ -80,7 +90,15 @@ impl MachineAir for CpuChip { ops.iter().for_each(|op| { let mut row = [F::zero(); NUM_CPU_COLS]; let cols: &mut CpuCols = row.as_mut_slice().borrow_mut(); - self.event_to_row::(op, &HashMap::new(), cols, &mut blu); + let instruction = &input.program.fetch(op.pc); + self.event_to_row::( + op, + &input.nonce_lookup, + cols, + &mut blu, + shard, + instruction, + ); }); blu }) @@ -103,23 +121,25 @@ impl CpuChip { fn event_to_row( &self, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], cols: &mut CpuCols, blu_events: &mut impl ByteRecord, + shard: u32, + instruction: &Instruction, ) { // Populate shard and clk columns. - self.populate_shard_clk(cols, event, blu_events); + self.populate_shard_clk(cols, event, blu_events, shard); // Populate the nonce. cols.nonce = F::from_canonical_u32( - nonce_lookup.get(&event.alu_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.alu_lookup_id.0 as usize).copied().unwrap_or_default(), ); // Populate basic fields. cols.pc = F::from_canonical_u32(event.pc); cols.next_pc = F::from_canonical_u32(event.next_pc); - cols.instruction.populate(event.instruction); - cols.selectors.populate(event.instruction); + cols.instruction.populate(instruction); + cols.selectors.populate(instruction); *cols.op_a_access.value_mut() = event.a.into(); *cols.op_b_access.value_mut() = event.b.into(); *cols.op_c_access.value_mut() = event.c.into(); @@ -145,7 +165,7 @@ impl CpuChip { .map(|x| x.as_canonical_u32()) .collect::>(); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, + shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -153,7 +173,7 @@ impl CpuChip { c: a_bytes[1] as u8, }); blu_events.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, + shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -162,23 +182,20 @@ impl CpuChip { }); // Populate memory accesses for reading from memory. - assert_eq!(event.memory_record.is_some(), event.memory.is_some()); let memory_columns = cols.opcode_specific_columns.memory_mut(); if let Some(record) = event.memory_record { memory_columns.memory_access.populate(record, blu_events) } // Populate memory, branch, jump, and auipc specific fields. - self.populate_memory(cols, event, blu_events, nonce_lookup); - self.populate_branch(cols, event, nonce_lookup); - self.populate_jump(cols, event, nonce_lookup); - self.populate_auipc(cols, event, nonce_lookup); + self.populate_memory(cols, event, blu_events, nonce_lookup, shard, instruction); + self.populate_branch(cols, event, nonce_lookup, instruction); + self.populate_jump(cols, event, nonce_lookup, instruction); + self.populate_auipc(cols, event, nonce_lookup, instruction); let is_halt = self.populate_ecall(cols, event, nonce_lookup); cols.is_sequential_instr = F::from_bool( - !event.instruction.is_branch_instruction() - && !event.instruction.is_jump_instruction() - && !is_halt, + !instruction.is_branch_instruction() && !instruction.is_jump_instruction() && !is_halt, ); // Assert that the instruction is not a no-op. @@ -191,8 +208,9 @@ impl CpuChip { cols: &mut CpuCols, event: &CpuEvent, blu_events: &mut impl ByteRecord, + shard: u32, ) { - cols.shard = F::from_canonical_u32(event.shard); + cols.shard = F::from_canonical_u32(shard); cols.clk = F::from_canonical_u32(event.clk); let clk_16bit_limb = (event.clk & 0xffff) as u16; @@ -201,15 +219,15 @@ impl CpuChip { cols.clk_8bit_limb = F::from_canonical_u8(clk_8bit_limb); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - event.shard, + shard, U16Range, - event.shard as u16, + shard as u16, 0, 0, 0, )); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - event.shard, + shard, U16Range, clk_16bit_limb, 0, @@ -217,7 +235,7 @@ impl CpuChip { 0, )); blu_events.add_byte_lookup_event(ByteLookupEvent::new( - event.shard, + shard, ByteOpcode::U8Range, 0, 0, @@ -232,10 +250,12 @@ impl CpuChip { cols: &mut CpuCols, event: &CpuEvent, blu_events: &mut impl ByteRecord, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], + shard: u32, + instruction: &Instruction, ) { if !matches!( - event.instruction.opcode, + instruction.opcode, Opcode::LB | Opcode::LH | Opcode::LW @@ -262,7 +282,7 @@ impl CpuChip { let bits: [bool; 8] = array::from_fn(|i| aligned_addr_ls_byte & (1 << i) != 0); memory_columns.aa_least_sig_byte_decomp = array::from_fn(|i| F::from_bool(bits[i + 2])); memory_columns.addr_word_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.memory_add_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.memory_add_lookup_id.0 as usize).copied().unwrap_or_default(), ); // Populate memory offsets. @@ -275,10 +295,10 @@ impl CpuChip { // If it is a load instruction, set the unsigned_mem_val column. let mem_value = event.memory_record.unwrap().value(); if matches!( - event.instruction.opcode, + instruction.opcode, Opcode::LB | Opcode::LBU | Opcode::LH | Opcode::LHU | Opcode::LW ) { - match event.instruction.opcode { + match instruction.opcode { Opcode::LB | Opcode::LBU => { cols.unsigned_mem_val = (mem_value.to_le_bytes()[addr_offset as usize] as u32).into(); @@ -298,8 +318,8 @@ impl CpuChip { } // For the signed load instructions, we need to check if the loaded value is negative. - if matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) { - let most_sig_mem_value_byte = if matches!(event.instruction.opcode, Opcode::LB) { + if matches!(instruction.opcode, Opcode::LB | Opcode::LH) { + let most_sig_mem_value_byte = if matches!(instruction.opcode, Opcode::LB) { cols.unsigned_mem_val.to_u32().to_le_bytes()[0] } else { cols.unsigned_mem_val.to_u32().to_le_bytes()[1] @@ -310,20 +330,22 @@ impl CpuChip { F::from_canonical_u8(most_sig_mem_value_byte >> i & 0x01); } if memory_columns.most_sig_byte_decomp[7] == F::one() { - cols.mem_value_is_neg_not_x0 = - F::from_bool(event.instruction.op_a != (X0 as u32)); + cols.mem_value_is_neg_not_x0 = F::from_bool(instruction.op_a != (X0 as u8)); cols.unsigned_mem_val_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.memory_sub_lookup_id).copied().unwrap_or_default(), + nonce_lookup + .get(event.memory_sub_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), ); } } // Set the `mem_value_is_pos_not_x0` composite flag. cols.mem_value_is_pos_not_x0 = F::from_bool( - ((matches!(event.instruction.opcode, Opcode::LB | Opcode::LH) + ((matches!(instruction.opcode, Opcode::LB | Opcode::LH) && (memory_columns.most_sig_byte_decomp[7] == F::zero())) - || matches!(event.instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) - && event.instruction.op_a != (X0 as u32), + || matches!(instruction.opcode, Opcode::LBU | Opcode::LHU | Opcode::LW)) + && instruction.op_a != (X0 as u8), ); } @@ -331,7 +353,7 @@ impl CpuChip { let addr_bytes = memory_addr.to_le_bytes(); for byte_pair in addr_bytes.chunks_exact(2) { blu_events.add_byte_lookup_event(ByteLookupEvent { - shard: event.shard, + shard, opcode: ByteOpcode::U8Range, a1: 0, a2: 0, @@ -346,15 +368,15 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], + instruction: &Instruction, ) { - if event.instruction.is_branch_instruction() { + if instruction.is_branch_instruction() { let branch_columns = cols.opcode_specific_columns.branch_mut(); let a_eq_b = event.a == event.b; - let use_signed_comparison = - matches!(event.instruction.opcode, Opcode::BLT | Opcode::BGE); + let use_signed_comparison = matches!(instruction.opcode, Opcode::BLT | Opcode::BGE); let a_lt_b = if use_signed_comparison { (event.a as i32) < (event.b as i32) @@ -368,18 +390,18 @@ impl CpuChip { }; branch_columns.a_lt_b_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.branch_lt_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.branch_lt_lookup_id.0 as usize).copied().unwrap_or_default(), ); branch_columns.a_gt_b_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.branch_gt_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.branch_gt_lookup_id.0 as usize).copied().unwrap_or_default(), ); branch_columns.a_eq_b = F::from_bool(a_eq_b); branch_columns.a_lt_b = F::from_bool(a_lt_b); branch_columns.a_gt_b = F::from_bool(a_gt_b); - let branching = match event.instruction.opcode { + let branching = match instruction.opcode { Opcode::BEQ => a_eq_b, Opcode::BNE => !a_eq_b, Opcode::BLT | Opcode::BLTU => a_lt_b, @@ -396,7 +418,10 @@ impl CpuChip { if branching { cols.branching = F::one(); branch_columns.next_pc_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.branch_add_lookup_id).copied().unwrap_or_default(), + nonce_lookup + .get(event.branch_add_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), ); } else { cols.not_branching = F::one(); @@ -409,12 +434,13 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], + instruction: &Instruction, ) { - if event.instruction.is_jump_instruction() { + if instruction.is_jump_instruction() { let jump_columns = cols.opcode_specific_columns.jump_mut(); - match event.instruction.opcode { + match instruction.opcode { Opcode::JAL => { let next_pc = event.pc.wrapping_add(event.b); jump_columns.op_a_range_checker.populate(event.a); @@ -423,7 +449,10 @@ impl CpuChip { jump_columns.next_pc = Word::from(next_pc); jump_columns.next_pc_range_checker.populate(next_pc); jump_columns.jal_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.jump_jal_lookup_id).copied().unwrap_or_default(), + nonce_lookup + .get(event.jump_jal_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), ); } Opcode::JALR => { @@ -432,7 +461,10 @@ impl CpuChip { jump_columns.next_pc = Word::from(next_pc); jump_columns.next_pc_range_checker.populate(next_pc); jump_columns.jalr_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.jump_jalr_lookup_id).copied().unwrap_or_default(), + nonce_lookup + .get(event.jump_jalr_lookup_id.0 as usize) + .copied() + .unwrap_or_default(), ); } _ => unreachable!(), @@ -445,15 +477,16 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], + instruction: &Instruction, ) { - if matches!(event.instruction.opcode, Opcode::AUIPC) { + if matches!(instruction.opcode, Opcode::AUIPC) { let auipc_columns = cols.opcode_specific_columns.auipc_mut(); auipc_columns.pc = Word::from(event.pc); auipc_columns.pc_range_checker.populate(event.pc); auipc_columns.auipc_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.auipc_lookup_id).copied().unwrap_or_default(), + nonce_lookup.get(event.auipc_lookup_id.0 as usize).copied().unwrap_or_default(), ); } } @@ -463,7 +496,7 @@ impl CpuChip { &self, cols: &mut CpuCols, event: &CpuEvent, - nonce_lookup: &HashMap, + nonce_lookup: &[u32], ) -> bool { let mut is_halt = false; @@ -516,9 +549,8 @@ impl CpuChip { } // Write the syscall nonce. - ecall_cols.syscall_nonce = F::from_canonical_u32( - nonce_lookup.get(&event.syscall_lookup_id).copied().unwrap_or_default(), - ); + ecall_cols.syscall_nonce = + F::from_canonical_u32(nonce_lookup[event.syscall_lookup_id.0 as usize]); is_halt = syscall_id == F::from_canonical_u32(SyscallCode::HALT.syscall_id()); @@ -540,29 +572,4 @@ impl CpuChip { is_halt } - - fn pad_to_power_of_two(&self, shape: &Option, values: &mut Vec) { - let n_real_rows = values.len() / NUM_CPU_COLS; - let padded_nb_rows = if let Some(shape) = shape { - 1 << shape.inner[&MachineAir::::name(self)] - } else if n_real_rows < 16 { - 16 - } else { - n_real_rows.next_power_of_two() - }; - values.resize(padded_nb_rows * NUM_CPU_COLS, F::zero()); - - // Interpret values as a slice of arrays of length `NUM_CPU_COLS` - let rows = unsafe { - core::slice::from_raw_parts_mut( - values.as_mut_ptr() as *mut [F; NUM_CPU_COLS], - values.len() / NUM_CPU_COLS, - ) - }; - - rows[n_real_rows..].par_iter_mut().for_each(|padded_row| { - padded_row[CPU_COL_MAP.selectors.imm_b] = F::one(); - padded_row[CPU_COL_MAP.selectors.imm_c] = F::one(); - }); - } } diff --git a/crates/core/machine/src/memory/local.rs b/crates/core/machine/src/memory/local.rs index bf109d028e..8be4377031 100644 --- a/crates/core/machine/src/memory/local.rs +++ b/crates/core/machine/src/memory/local.rs @@ -3,11 +3,11 @@ use std::{ mem::size_of, }; -use crate::utils::pad_rows_fixed; -use itertools::Itertools; +use crate::utils::{next_power_of_two, zeroed_f_vec}; use p3_air::{Air, BaseAir}; use p3_field::PrimeField32; use p3_matrix::{dense::RowMajorMatrix, Matrix}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -86,39 +86,45 @@ impl MachineAir for MemoryLocalChip { input: &ExecutionRecord, _output: &mut ExecutionRecord, ) -> RowMajorMatrix { - let mut rows = Vec::<[F; NUM_MEMORY_LOCAL_INIT_COLS]>::new(); - - for local_mem_events in - &input.get_local_mem_events().chunks(NUM_LOCAL_MEMORY_ENTRIES_PER_ROW) - { - let mut row = [F::zero(); NUM_MEMORY_LOCAL_INIT_COLS]; - let cols: &mut MemoryLocalCols = row.as_mut_slice().borrow_mut(); - - for (cols, event) in cols.memory_local_entries.iter_mut().zip(local_mem_events) { - cols.addr = F::from_canonical_u32(event.addr); - cols.initial_shard = F::from_canonical_u32(event.initial_mem_access.shard); - cols.final_shard = F::from_canonical_u32(event.final_mem_access.shard); - cols.initial_clk = F::from_canonical_u32(event.initial_mem_access.timestamp); - cols.final_clk = F::from_canonical_u32(event.final_mem_access.timestamp); - cols.initial_value = event.initial_mem_access.value.into(); - cols.final_value = event.final_mem_access.value.into(); - cols.is_real = F::one(); - } - - rows.push(row); - } - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_MEMORY_LOCAL_INIT_COLS], - input.fixed_log2_rows::(self), - ); - - RowMajorMatrix::new( - rows.into_iter().flatten().collect::>(), - NUM_MEMORY_LOCAL_INIT_COLS, - ) + // Generate the trace rows for each event. + let events = input.get_local_mem_events().collect::>(); + let nb_rows = (events.len() + 3) / 4; + let size_log2 = input.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_MEMORY_LOCAL_INIT_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values + .chunks_mut(chunk_size * NUM_MEMORY_LOCAL_INIT_COLS) + .enumerate() + .par_bridge() + .for_each(|(i, rows)| { + rows.chunks_mut(NUM_MEMORY_LOCAL_INIT_COLS).enumerate().for_each(|(j, row)| { + let idx = (i * chunk_size + j) * NUM_LOCAL_MEMORY_ENTRIES_PER_ROW; + + let cols: &mut MemoryLocalCols = row.borrow_mut(); + for k in 0..NUM_LOCAL_MEMORY_ENTRIES_PER_ROW { + let cols = &mut cols.memory_local_entries[k]; + if idx + k < events.len() { + let event = &events[idx + k]; + cols.addr = F::from_canonical_u32(event.addr); + cols.initial_shard = + F::from_canonical_u32(event.initial_mem_access.shard); + cols.final_shard = F::from_canonical_u32(event.final_mem_access.shard); + cols.initial_clk = + F::from_canonical_u32(event.initial_mem_access.timestamp); + cols.final_clk = + F::from_canonical_u32(event.final_mem_access.timestamp); + cols.initial_value = event.initial_mem_access.value.into(); + cols.final_value = event.final_mem_access.value.into(); + cols.is_real = F::one(); + } + } + }); + }); + + // Convert the trace to a row major matrix. + RowMajorMatrix::new(values, NUM_MEMORY_LOCAL_INIT_COLS) } fn included(&self, shard: &Self::Record) -> bool { diff --git a/crates/core/machine/src/memory/program.rs b/crates/core/machine/src/memory/program.rs index 7b68661624..699e052c0d 100644 --- a/crates/core/machine/src/memory/program.rs +++ b/crates/core/machine/src/memory/program.rs @@ -7,6 +7,7 @@ use p3_air::{Air, AirBuilder, AirBuilderWithPublicValues, BaseAir, PairBuilder}; use p3_field::{AbstractField, PrimeField}; use p3_matrix::{dense::RowMajorMatrix, Matrix}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::{ @@ -17,7 +18,10 @@ use sp1_stark::{ InteractionKind, Word, }; -use crate::{operations::IsZeroOperation, utils::pad_rows_fixed}; +use crate::{ + operations::IsZeroOperation, + utils::{next_power_of_two, pad_rows_fixed, zeroed_f_vec}, +}; pub const NUM_MEMORY_PROGRAM_PREPROCESSED_COLS: usize = size_of::>(); @@ -71,35 +75,36 @@ impl MachineAir for MemoryProgramChip { } fn generate_preprocessed_trace(&self, program: &Self::Program) -> Option> { - let program_memory = &program.memory_image; - // Note that BTreeMap is guaranteed to be sorted by key. This makes the row order - // deterministic. - let mut rows = program_memory - .iter() - .sorted() - .map(|(&addr, &word)| { - let mut row = [F::zero(); NUM_MEMORY_PROGRAM_PREPROCESSED_COLS]; - let cols: &mut MemoryProgramPreprocessedCols = row.as_mut_slice().borrow_mut(); - cols.addr = F::from_canonical_u32(addr); - cols.value = Word::from(word); - cols.is_real = F::one(); - row - }) - .collect::>(); - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_MEMORY_PROGRAM_PREPROCESSED_COLS], - program.fixed_log2_rows::(self), - ); + // Generate the trace rows for each event. + let nb_rows = program.memory_image.len(); + let size_log2 = program.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_MEMORY_PROGRAM_PREPROCESSED_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + let memory = program.memory_image.iter().collect::>(); + values + .chunks_mut(chunk_size * NUM_MEMORY_PROGRAM_PREPROCESSED_COLS) + .enumerate() + .par_bridge() + .for_each(|(i, rows)| { + rows.chunks_mut(NUM_MEMORY_PROGRAM_PREPROCESSED_COLS).enumerate().for_each( + |(j, row)| { + let idx = i * chunk_size + j; + + if idx < nb_rows { + let (addr, word) = memory[idx]; + let cols: &mut MemoryProgramPreprocessedCols = row.borrow_mut(); + cols.addr = F::from_canonical_u32(*addr); + cols.value = Word::from(*word); + cols.is_real = F::one(); + } + }, + ); + }); // Convert the trace to a row major matrix. - let trace = RowMajorMatrix::new( - rows.into_iter().flatten().collect::>(), - NUM_MEMORY_PROGRAM_PREPROCESSED_COLS, - ); - Some(trace) + Some(RowMajorMatrix::new(values, NUM_MEMORY_PROGRAM_PREPROCESSED_COLS)) } fn generate_dependencies(&self, _input: &ExecutionRecord, _output: &mut ExecutionRecord) { diff --git a/crates/core/machine/src/program/mod.rs b/crates/core/machine/src/program/mod.rs index 39dfb6a765..f6c1f3bc0c 100644 --- a/crates/core/machine/src/program/mod.rs +++ b/crates/core/machine/src/program/mod.rs @@ -4,10 +4,14 @@ use core::{ }; use std::collections::HashMap; -use crate::{air::ProgramAirBuilder, utils::pad_rows_fixed}; +use crate::{ + air::ProgramAirBuilder, + utils::{next_power_of_two, pad_rows_fixed, zeroed_f_vec}, +}; use p3_air::{Air, BaseAir, PairBuilder}; use p3_field::PrimeField; use p3_matrix::{dense::RowMajorMatrix, Matrix}; +use p3_maybe_rayon::prelude::{ParallelBridge, ParallelIterator}; use sp1_core_executor::{ExecutionRecord, Program}; use sp1_derive::AlignedBorrow; use sp1_stark::air::{MachineAir, SP1AirBuilder}; @@ -65,36 +69,34 @@ impl MachineAir for ProgramChip { !program.instructions.is_empty() || program.preprocessed_shape.is_some(), "empty program" ); - let mut rows = program - .instructions - .iter() + // Generate the trace rows for each event. + let nb_rows = program.instructions.len(); + let size_log2 = program.fixed_log2_rows::(self); + let padded_nb_rows = next_power_of_two(nb_rows, size_log2); + let mut values = zeroed_f_vec(padded_nb_rows * NUM_PROGRAM_PREPROCESSED_COLS); + let chunk_size = std::cmp::max((nb_rows + 1) / num_cpus::get(), 1); + + values + .chunks_mut(chunk_size * NUM_PROGRAM_PREPROCESSED_COLS) .enumerate() - .map(|(i, &instruction)| { - let pc = program.pc_base + (i as u32 * 4); - let mut row = [F::zero(); NUM_PROGRAM_PREPROCESSED_COLS]; - let cols: &mut ProgramPreprocessedCols = row.as_mut_slice().borrow_mut(); - cols.pc = F::from_canonical_u32(pc); - cols.instruction.populate(instruction); - cols.selectors.populate(instruction); - - row - }) - .collect::>(); - - // Pad the trace to a power of two depending on the proof shape in `input`. - pad_rows_fixed( - &mut rows, - || [F::zero(); NUM_PROGRAM_PREPROCESSED_COLS], - program.fixed_log2_rows::(self), - ); + .par_bridge() + .for_each(|(i, rows)| { + rows.chunks_mut(NUM_PROGRAM_PREPROCESSED_COLS).enumerate().for_each(|(j, row)| { + let idx = i * chunk_size + j; + + if idx < nb_rows { + let cols: &mut ProgramPreprocessedCols = row.borrow_mut(); + let instruction = &program.instructions[idx]; + let pc = program.pc_base + (idx as u32 * 4); + cols.pc = F::from_canonical_u32(pc); + cols.instruction.populate(instruction); + cols.selectors.populate(instruction); + } + }); + }); // Convert the trace to a row major matrix. - let trace = RowMajorMatrix::new( - rows.into_iter().flatten().collect::>(), - NUM_PROGRAM_PREPROCESSED_COLS, - ); - - Some(trace) + Some(RowMajorMatrix::new(values, NUM_PROGRAM_PREPROCESSED_COLS)) } fn generate_dependencies(&self, _input: &ExecutionRecord, _output: &mut ExecutionRecord) { diff --git a/crates/core/machine/src/runtime/utils.rs b/crates/core/machine/src/runtime/utils.rs index 7c0ad541e7..483400e294 100644 --- a/crates/core/machine/src/runtime/utils.rs +++ b/crates/core/machine/src/runtime/utils.rs @@ -19,7 +19,7 @@ macro_rules! assert_valid_memory_access { assert!($addr > 40); } _ => { - Register::from_u32($addr); + Register::from_u8($addr); } }; } @@ -69,11 +69,7 @@ impl<'a> Runtime<'a> { ); if !self.unconstrained && self.state.global_clk % 10_000_000 == 0 { - log::info!( - "clk = {} pc = 0x{:x?}", - self.state.global_clk, - self.state.pc - ); + log::info!("clk = {} pc = 0x{:x?}", self.state.global_clk, self.state.pc); } } } diff --git a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs index c9c5ae93c8..97d0e526fe 100644 --- a/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs +++ b/crates/core/machine/src/syscall/precompiles/edwards/ed_decompress.rs @@ -72,7 +72,7 @@ impl EdDecompressCols { self.clk = F::from_canonical_u32(event.clk); self.ptr = F::from_canonical_u32(event.ptr); self.nonce = F::from_canonical_u32( - record.nonce_lookup.get(&event.lookup_id).copied().unwrap_or_default(), + record.nonce_lookup.get(event.lookup_id.0 as usize).copied().unwrap_or_default(), ); self.sign = F::from_bool(event.sign); for i in 0..8 { diff --git a/crates/core/machine/src/utils/prove.rs b/crates/core/machine/src/utils/prove.rs index 4a17c8f764..09a39ed049 100644 --- a/crates/core/machine/src/utils/prove.rs +++ b/crates/core/machine/src/utils/prove.rs @@ -174,8 +174,9 @@ where let _span = span.enter(); // Execute the runtime until we reach a checkpoint. - let (checkpoint, done) = - runtime.execute_state().map_err(SP1CoreProverError::ExecutionError)?; + let (checkpoint, done) = runtime + .execute_state(false) + .map_err(SP1CoreProverError::ExecutionError)?; // Save the checkpoint to a temp file. let mut checkpoint_file = @@ -855,7 +856,7 @@ where runtime.subproof_verifier = Arc::new(NoOpSubproofVerifier); // Execute from the checkpoint. - let (records, _) = runtime.execute_record().unwrap(); + let (records, _) = runtime.execute_record(true).unwrap(); (records, runtime.report) } diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index 0ff296bb2a..984e186e53 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -33,11 +33,7 @@ use std::{ }; use lru::LruCache; - -use tracing::instrument; - use p3_baby_bear::BabyBear; - use p3_challenger::CanObserve; use p3_field::{AbstractField, PrimeField, PrimeField32}; use p3_matrix::dense::RowMajorMatrix; @@ -80,6 +76,7 @@ use sp1_stark::{ MachineProver, SP1CoreOpts, SP1ProverOpts, ShardProof, StarkGenericConfig, StarkVerifyingKey, Val, Word, DIGEST_SIZE, }; +use tracing::instrument; pub use types::*; use utils::{sp1_committed_values_digest_bn254, sp1_vkey_digest_bn254, words_to_bytes}; @@ -356,8 +353,9 @@ impl SP1Prover { input: &SP1CompressWithVKeyWitnessValues, ) -> Arc> { let mut cache = self.compress_programs.lock().unwrap_or_else(|e| e.into_inner()); + let shape = input.shape(); cache - .get_or_insert(input.shape(), || { + .get_or_insert(shape.clone(), || { let misses = self.compress_cache_misses.fetch_add(1, Ordering::Relaxed); tracing::debug!("compress cache miss, misses: {}", misses); // Get the operations. diff --git a/crates/prover/src/shapes.rs b/crates/prover/src/shapes.rs index b7adddc0e5..74f7ba177e 100644 --- a/crates/prover/src/shapes.rs +++ b/crates/prover/src/shapes.rs @@ -1,11 +1,13 @@ use std::{ collections::{BTreeMap, BTreeSet, HashSet}, fs::File, + hash::{DefaultHasher, Hash, Hasher}, panic::{catch_unwind, AssertUnwindSafe}, path::PathBuf, sync::{Arc, Mutex}, }; +use eyre::Result; use thiserror::Error; use p3_baby_bear::BabyBear; @@ -29,7 +31,7 @@ pub enum SP1ProofShape { Shrink(ProofShape), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash)] pub enum SP1CompressProgramShape { Recursion(SP1RecursionShape), Compress(SP1CompressWithVkeyShape), @@ -37,6 +39,14 @@ pub enum SP1CompressProgramShape { Shrink(SP1CompressWithVkeyShape), } +impl SP1CompressProgramShape { + pub fn hash_u64(&self) -> u64 { + let mut hasher = DefaultHasher::new(); + Hash::hash(&self, &mut hasher); + hasher.finish() + } +} + #[derive(Debug, Error)] pub enum VkBuildError { #[error("IO error: {0}")] @@ -231,6 +241,15 @@ impl SP1ProofShape { ) } + pub fn generate_compress_shapes( + recursion_shape_config: &'_ RecursionShapeConfig>, + reduce_batch_size: usize, + ) -> impl Iterator + '_ { + (1..=reduce_batch_size).flat_map(|batch_size| { + recursion_shape_config.get_all_shape_combinations(batch_size).map(Self::Compress) + }) + } + pub fn dummy_vk_map<'a>( core_shape_config: &'a CoreShapeConfig, recursion_shape_config: &'a RecursionShapeConfig>, diff --git a/crates/recursion/circuit/src/machine/deferred.rs b/crates/recursion/circuit/src/machine/deferred.rs index 0f38620a7d..d5ab720973 100644 --- a/crates/recursion/circuit/src/machine/deferred.rs +++ b/crates/recursion/circuit/src/machine/deferred.rs @@ -43,7 +43,7 @@ pub struct SP1DeferredVerifier { _phantom: std::marker::PhantomData<(C, SC, A)>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Hash)] pub struct SP1DeferredShape { inner: SP1CompressShape, height: usize, diff --git a/crates/recursion/compiler/src/circuit/compiler.rs b/crates/recursion/compiler/src/circuit/compiler.rs index d75c0d3d6e..b44b38a1dd 100644 --- a/crates/recursion/compiler/src/circuit/compiler.rs +++ b/crates/recursion/compiler/src/circuit/compiler.rs @@ -17,6 +17,9 @@ use sp1_recursion_core::*; use crate::prelude::*; +/// The number of instructions to preallocate in a recursion program +const PREALLOC_INSTRUCTIONS: usize = 10000000; + /// The backend for the circuit compiler. #[derive(Debug, Clone, Default)] pub struct AsmCompiler { @@ -511,7 +514,7 @@ where // Compile each IR instruction into a list of ASM instructions, then combine them. // This step also counts the number of times each address is read from. let (mut instrs, traces) = tracing::debug_span!("compile_one loop").in_scope(|| { - let mut instrs = Vec::with_capacity(operations.vec.len()); + let mut instrs = Vec::with_capacity(PREALLOC_INSTRUCTIONS); let mut traces = vec![]; if debug_mode { let mut span_builder = diff --git a/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs b/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs index ecd9c57550..7e67f54362 100644 --- a/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_skinny/trace.rs @@ -41,6 +41,10 @@ impl MachineAir for Poseidon2SkinnyChip format!("Poseidon2SkinnyDeg{}", DEGREE) } + fn generate_dependencies(&self, _: &Self::Record, _: &mut Self::Record) { + // This is a no-op. + } + #[instrument(name = "generate poseidon2 skinny trace", level = "debug", skip_all, fields(rows = input.poseidon2_events.len()))] fn generate_trace( &self, diff --git a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs index 0d5c666265..19a3b6f287 100644 --- a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs @@ -37,6 +37,10 @@ impl MachineAir for Poseidon2WideChip, const DEGREE: u #[derive(Debug, Clone, Copy, Default)] pub struct RecursionAirEventCount { - mem_const_events: usize, - mem_var_events: usize, - base_alu_events: usize, - ext_alu_events: usize, - poseidon2_wide_events: usize, - fri_fold_events: usize, - select_events: usize, - exp_reverse_bits_len_events: usize, + pub mem_const_events: usize, + pub mem_var_events: usize, + pub base_alu_events: usize, + pub ext_alu_events: usize, + pub poseidon2_wide_events: usize, + pub fri_fold_events: usize, + pub select_events: usize, + pub exp_reverse_bits_len_events: usize, } impl, const DEGREE: usize> RecursionAir { diff --git a/crates/recursion/core/src/runtime/memory.rs b/crates/recursion/core/src/runtime/memory.rs index a82337b684..d0b7f0f229 100644 --- a/crates/recursion/core/src/runtime/memory.rs +++ b/crates/recursion/core/src/runtime/memory.rs @@ -5,7 +5,7 @@ use vec_map::{Entry, VecMap}; use crate::{air::Block, Address}; -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone, Default, Copy)] pub struct MemoryEntry { pub val: Block, pub mult: F, diff --git a/crates/recursion/core/src/runtime/mod.rs b/crates/recursion/core/src/runtime/mod.rs index f95ef87a14..2478a45ddb 100644 --- a/crates/recursion/core/src/runtime/mod.rs +++ b/crates/recursion/core/src/runtime/mod.rs @@ -8,6 +8,7 @@ mod record; use backtrace::Backtrace as Trace; pub use instruction::Instruction; use instruction::{FieldEltType, HintBitsInstr, HintExt2FeltsInstr, HintInstr, PrintInstr}; +use machine::RecursionAirEventCount; use memory::*; pub use opcode::*; pub use program::*; @@ -249,6 +250,7 @@ where pub fn run(&mut self) -> Result<(), RuntimeError> { let early_exit_ts = std::env::var("RECURSION_EARLY_EXIT_TS") .map_or(usize::MAX, |ts: String| ts.parse().unwrap()); + self.preallocate_record(); while self.pc < F::from_canonical_u32(self.program.instructions.len() as u32) { let idx = self.pc.as_canonical_u32() as usize; let instruction = self.program.instructions[idx].clone(); @@ -544,4 +546,18 @@ where } Ok(()) } + + pub fn preallocate_record(&mut self) { + let event_counts = self + .program + .instructions + .iter() + .fold(RecursionAirEventCount::default(), |heights, instruction| heights + instruction); + self.record.poseidon2_events.reserve(event_counts.poseidon2_wide_events); + self.record.mem_var_events.reserve(event_counts.mem_var_events); + self.record.base_alu_events.reserve(event_counts.base_alu_events); + self.record.ext_alu_events.reserve(event_counts.ext_alu_events); + self.record.exp_reverse_bits_len_events.reserve(event_counts.exp_reverse_bits_len_events); + self.record.select_events.reserve(event_counts.select_events); + } } From a298dc2358d0eb094081ac2a9ef84d8d74d67ab4 Mon Sep 17 00:00:00 2001 From: rkm0959 Date: Fri, 1 Nov 2024 13:01:41 -0700 Subject: [PATCH 09/17] perf: add batch FRI precompile (#1730) --- crates/recursion/circuit/src/fri.rs | 30 +-- crates/recursion/circuit/src/lib.rs | 49 +++- .../recursion/compiler/src/circuit/builder.rs | 18 ++ .../compiler/src/circuit/compiler.rs | 30 +++ .../recursion/compiler/src/ir/instructions.rs | 5 + crates/recursion/core/src/chips/batch_fri.rs | 231 ++++++++++++++++++ crates/recursion/core/src/chips/mod.rs | 1 + crates/recursion/core/src/lib.rs | 46 ++++ crates/recursion/core/src/machine.rs | 12 + .../recursion/core/src/runtime/instruction.rs | 22 ++ crates/recursion/core/src/runtime/mod.rs | 45 ++++ crates/recursion/core/src/runtime/record.rs | 7 +- crates/recursion/core/src/shape.rs | 14 ++ crates/zkvm/entrypoint/src/memcpy.s | 2 +- crates/zkvm/entrypoint/src/memset.s | 2 +- 15 files changed, 490 insertions(+), 24 deletions(-) create mode 100644 crates/recursion/core/src/chips/batch_fri.rs diff --git a/crates/recursion/circuit/src/fri.rs b/crates/recursion/circuit/src/fri.rs index 099f8bcfe4..ea343bea4e 100644 --- a/crates/recursion/circuit/src/fri.rs +++ b/crates/recursion/circuit/src/fri.rs @@ -151,10 +151,11 @@ pub fn verify_two_adic_pcs, SC: BabyBearFriConfigV for (z, ps_at_z) in izip!(mat_points, mat_values) { // Unroll the loop calculation to avoid symbolic expression overhead - // let mut acc: Ext = builder.constant(C::EF::zero()); - let mut acc: Ext<_, _> = builder.uninit(); + let len = ps_at_z.len(); + let mut alphas = Vec::with_capacity(len); + let mut p_at_zs = Vec::with_capacity(len); + let mut p_at_xs = Vec::with_capacity(len); - builder.push_op(DslIr::ImmE(acc, C::EF::zero())); for (p_at_x, p_at_z) in izip!(mat_opening.clone(), ps_at_z) { let pow = log_height_pow[log_height]; // Fill in any missing powers of alpha. @@ -170,24 +171,17 @@ pub fn verify_two_adic_pcs, SC: BabyBearFriConfigV builder.reduce_e(new_alpha); alpha_pows.push(new_alpha); } - // Unroll: - // - // acc = builder.eval(acc + (alpha_pows[pow] * (p_at_z - p_at_x[0]))); - - // let temp_1 = p_at_z - p_at_x[0]; - let temp_1: Ext<_, _> = builder.uninit(); - builder.push_op(DslIr::SubEF(temp_1, p_at_z, p_at_x[0])); - // let temp_2 = alpha_pows[pow] * temp_1; - let temp_2: Ext<_, _> = builder.uninit(); - builder.push_op(DslIr::MulE(temp_2, alpha_pows[pow], temp_1)); - // let temp_3 = acc + temp_2; - let temp_3: Ext<_, _> = builder.uninit(); - builder.push_op(DslIr::AddE(temp_3, acc, temp_2)); - // acc = temp_3; - acc = temp_3; + + alphas.push(alpha_pows[pow]); + p_at_zs.push(p_at_z); + p_at_xs.push(p_at_x[0]); log_height_pow[log_height] += 1; } + + // acc = sum(alpha_pows[pow] * (p_at_z - p_at_x[0])); + let acc = C::batch_fri(builder, alphas, p_at_zs, p_at_xs); + // Unroll this calculation to avoid symbolic expression overhead // ro[log_height] = builder.eval(ro[log_height] + acc / (z - x)); diff --git a/crates/recursion/circuit/src/lib.rs b/crates/recursion/circuit/src/lib.rs index eeda3448b8..22247f25ed 100644 --- a/crates/recursion/circuit/src/lib.rs +++ b/crates/recursion/circuit/src/lib.rs @@ -1,12 +1,11 @@ //! Copied from [`sp1_recursion_program`]. -use std::iter::{repeat, zip}; - use challenger::{ CanCopyChallenger, CanObserveVariable, DuplexChallengerVariable, FieldChallengerVariable, MultiField32ChallengerVariable, SpongeChallengerShape, }; use hash::{FieldHasherVariable, Posedion2BabyBearHasherVariable}; +use itertools::izip; use p3_bn254_fr::Bn254Fr; use p3_field::AbstractField; use p3_matrix::dense::RowMajorMatrix; @@ -15,6 +14,7 @@ use sp1_recursion_compiler::{ config::{InnerConfig, OuterConfig}, ir::{Builder, Config, DslIr, Ext, Felt, SymbolicFelt, Var, Variable}, }; +use std::iter::{repeat, zip}; mod types; @@ -137,6 +137,13 @@ pub trait CircuitConfig: Config { two_adic_powers_of_x: &[Felt], ) -> Felt; + fn batch_fri( + builder: &mut Builder, + alpha_pows: Vec>, + p_at_zs: Vec>, + p_at_xs: Vec>, + ) -> Ext; + fn num2bits( builder: &mut Builder, num: Felt<::F>, @@ -210,6 +217,15 @@ impl CircuitConfig for InnerConfig { builder.exp_reverse_bits_v2(input, power_bits) } + fn batch_fri( + builder: &mut Builder, + alpha_pows: Vec::F, ::EF>>, + p_at_zs: Vec::F, ::EF>>, + p_at_xs: Vec::F>>, + ) -> Ext<::F, ::EF> { + builder.batch_fri_v2(alpha_pows, p_at_zs, p_at_xs) + } + fn num2bits( builder: &mut Builder, num: Felt<::F>, @@ -329,6 +345,15 @@ impl CircuitConfig for WrapConfig { result } + fn batch_fri( + builder: &mut Builder, + alpha_pows: Vec::F, ::EF>>, + p_at_zs: Vec::F, ::EF>>, + p_at_xs: Vec::F>>, + ) -> Ext<::F, ::EF> { + builder.batch_fri_v2(alpha_pows, p_at_zs, p_at_xs) + } + fn num2bits( builder: &mut Builder, num: Felt<::F>, @@ -440,6 +465,26 @@ impl CircuitConfig for OuterConfig { result } + fn batch_fri( + builder: &mut Builder, + alpha_pows: Vec::F, ::EF>>, + p_at_zs: Vec::F, ::EF>>, + p_at_xs: Vec::F>>, + ) -> Ext<::F, ::EF> { + let mut acc: Ext<_, _> = builder.uninit(); + builder.push_op(DslIr::ImmE(acc, ::EF::zero())); + for (alpha_pow, p_at_z, p_at_x) in izip!(alpha_pows, p_at_zs, p_at_xs) { + let temp_1: Ext<_, _> = builder.uninit(); + builder.push_op(DslIr::SubEF(temp_1, p_at_z, p_at_x)); + let temp_2: Ext<_, _> = builder.uninit(); + builder.push_op(DslIr::MulE(temp_2, alpha_pow, temp_1)); + let temp_3: Ext<_, _> = builder.uninit(); + builder.push_op(DslIr::AddE(temp_3, acc, temp_2)); + acc = temp_3; + } + acc + } + fn num2bits( builder: &mut Builder, num: Felt<::F>, diff --git a/crates/recursion/compiler/src/circuit/builder.rs b/crates/recursion/compiler/src/circuit/builder.rs index 418aeb4bfb..f78145ad1d 100644 --- a/crates/recursion/compiler/src/circuit/builder.rs +++ b/crates/recursion/compiler/src/circuit/builder.rs @@ -17,6 +17,12 @@ pub trait CircuitV2Builder { fn num2bits_v2_f(&mut self, num: Felt, num_bits: usize) -> Vec>; fn exp_reverse_bits_v2(&mut self, input: Felt, power_bits: Vec>) -> Felt; + fn batch_fri_v2( + &mut self, + alphas: Vec>, + p_at_zs: Vec>, + p_at_xs: Vec>, + ) -> Ext; fn poseidon2_permute_v2(&mut self, state: [Felt; WIDTH]) -> [Felt; WIDTH]; fn poseidon2_hash_v2(&mut self, array: &[Felt]) -> [Felt; DIGEST_SIZE]; fn poseidon2_compress_v2( @@ -106,6 +112,18 @@ impl> CircuitV2Builder for Builder { output } + /// A version of the `batch_fri` that uses the BatchFRI precompile. + fn batch_fri_v2( + &mut self, + alpha_pows: Vec>, + p_at_zs: Vec>, + p_at_xs: Vec>, + ) -> Ext { + let output: Ext<_, _> = self.uninit(); + self.push_op(DslIr::CircuitV2BatchFRI(Box::new((output, alpha_pows, p_at_zs, p_at_xs)))); + output + } + /// Applies the Poseidon2 permutation to the given array. fn poseidon2_permute_v2(&mut self, array: [Felt; WIDTH]) -> [Felt; WIDTH] { let output: [Felt; WIDTH] = core::array::from_fn(|_| self.uninit()); diff --git a/crates/recursion/compiler/src/circuit/compiler.rs b/crates/recursion/compiler/src/circuit/compiler.rs index b44b38a1dd..14aa320c98 100644 --- a/crates/recursion/compiler/src/circuit/compiler.rs +++ b/crates/recursion/compiler/src/circuit/compiler.rs @@ -338,6 +338,26 @@ where })) } + fn batch_fri( + &mut self, + acc: Ext, + alpha_pows: Vec>, + p_at_zs: Vec>, + p_at_xs: Vec>, + ) -> Instruction { + Instruction::BatchFRI(Box::new(BatchFRIInstr { + base_vec_addrs: BatchFRIBaseVecIo { + p_at_x: p_at_xs.into_iter().map(|e| e.read(self)).collect(), + }, + ext_single_addrs: BatchFRIExtSingleIo { acc: acc.write(self) }, + ext_vec_addrs: BatchFRIExtVecIo { + p_at_z: p_at_zs.into_iter().map(|e| e.read(self)).collect(), + alpha_pow: alpha_pows.into_iter().map(|e| e.read(self)).collect(), + }, + acc_mult: C::F::zero(), + })) + } + fn commit_public_values( &mut self, public_values: &RecursionPublicValues>, @@ -483,6 +503,7 @@ where f(self.hint_bit_decomposition(value, output)) } DslIr::CircuitV2FriFold(data) => f(self.fri_fold(data.0, data.1)), + DslIr::CircuitV2BatchFRI(data) => f(self.batch_fri(data.0, data.1, data.2, data.3)), DslIr::CircuitV2CommitPublicValues(public_values) => { f(self.commit_public_values(&public_values)) } @@ -619,6 +640,14 @@ where alpha_pow_mults.iter_mut().zip(alpha_pow_output).for_each(&mut backfill); ro_mults.iter_mut().zip(ro_output).for_each(&mut backfill); } + Instruction::BatchFRI(instr) => { + let BatchFRIInstr { + ext_single_addrs: BatchFRIExtSingleIo { ref acc }, + acc_mult, + .. + } = instr.as_mut(); + backfill((acc_mult, acc)); + } Instruction::HintExt2Felts(HintExt2FeltsInstr { output_addrs_mults, .. }) => { @@ -674,6 +703,7 @@ const fn instr_name(instr: &Instruction) -> &'static str { Instruction::ExpReverseBitsLen(_) => "ExpReverseBitsLen", Instruction::HintBits(_) => "HintBits", Instruction::FriFold(_) => "FriFold", + Instruction::BatchFRI(_) => "BatchFRI", Instruction::Print(_) => "Print", Instruction::HintExt2Felts(_) => "HintExt2Felts", Instruction::Hint(_) => "Hint", diff --git a/crates/recursion/compiler/src/ir/instructions.rs b/crates/recursion/compiler/src/ir/instructions.rs index 3d718e2568..5fbd0fa210 100644 --- a/crates/recursion/compiler/src/ir/instructions.rs +++ b/crates/recursion/compiler/src/ir/instructions.rs @@ -283,6 +283,11 @@ pub enum DslIr { /// Executes a FRI fold operation. Input is the fri fold input array. See [`FriFoldInput`] for /// more details. CircuitV2FriFold(Box<(CircuitV2FriFoldOutput, CircuitV2FriFoldInput)>), + // FRI specific instructions. + /// Executes a Batch FRI loop. Input is the power of alphas, evaluations at z, and evaluations at x. + CircuitV2BatchFRI( + Box<(Ext, Vec>, Vec>, Vec>)>, + ), /// Select's a variable based on a condition. (select(cond, true_val, false_val) => output). /// Should only be used when target is a gnark circuit. CircuitSelectV(Var, Var, Var, Var), diff --git a/crates/recursion/core/src/chips/batch_fri.rs b/crates/recursion/core/src/chips/batch_fri.rs new file mode 100644 index 0000000000..6522a9881d --- /dev/null +++ b/crates/recursion/core/src/chips/batch_fri.rs @@ -0,0 +1,231 @@ +#![allow(clippy::needless_range_loop)] + +use core::borrow::Borrow; +use itertools::Itertools; +use sp1_core_machine::utils::pad_rows_fixed; +use sp1_stark::air::{BaseAirBuilder, BinomialExtension, MachineAir}; +use std::borrow::BorrowMut; +use tracing::instrument; + +use p3_air::{Air, AirBuilder, BaseAir, PairBuilder}; +use p3_field::PrimeField32; +use p3_matrix::{dense::RowMajorMatrix, Matrix}; +use sp1_stark::air::ExtensionAirBuilder; + +use sp1_derive::AlignedBorrow; + +use crate::{ + air::Block, + builder::SP1RecursionAirBuilder, + runtime::{Instruction, RecursionProgram}, + Address, BatchFRIInstr, ExecutionRecord, +}; + +pub const NUM_BATCH_FRI_COLS: usize = core::mem::size_of::>(); +pub const NUM_BATCH_FRI_PREPROCESSED_COLS: usize = + core::mem::size_of::>(); + +#[derive(Clone, Debug, Copy, Default)] +pub struct BatchFRIChip; + +/// The preprocessed columns for a batch FRI invocation. +#[derive(AlignedBorrow, Debug, Clone, Copy)] +#[repr(C)] +pub struct BatchFRIPreprocessedCols { + pub is_real: T, + pub is_end: T, + pub acc_addr: Address, + pub alpha_pow_addr: Address, + pub p_at_z_addr: Address, + pub p_at_x_addr: Address, +} + +/// The main columns for a batch FRI invocation. +#[derive(AlignedBorrow, Debug, Clone, Copy)] +#[repr(C)] +pub struct BatchFRICols { + pub acc: Block, + pub alpha_pow: Block, + pub p_at_z: Block, + pub p_at_x: T, +} + +impl BaseAir for BatchFRIChip { + fn width(&self) -> usize { + NUM_BATCH_FRI_COLS + } +} + +impl MachineAir for BatchFRIChip { + type Record = ExecutionRecord; + + type Program = RecursionProgram; + + fn name(&self) -> String { + "BatchFRI".to_string() + } + + fn generate_dependencies(&self, _: &Self::Record, _: &mut Self::Record) { + // This is a no-op. + } + + fn preprocessed_width(&self) -> usize { + NUM_BATCH_FRI_PREPROCESSED_COLS + } + fn generate_preprocessed_trace(&self, program: &Self::Program) -> Option> { + let mut rows: Vec<[F; NUM_BATCH_FRI_PREPROCESSED_COLS]> = Vec::new(); + program + .instructions + .iter() + .filter_map(|instruction| { + if let Instruction::BatchFRI(instr) = instruction { + Some(instr) + } else { + None + } + }) + .for_each(|instruction| { + let BatchFRIInstr { base_vec_addrs, ext_single_addrs, ext_vec_addrs, acc_mult } = + instruction.as_ref(); + let len = ext_vec_addrs.p_at_z.len(); + let mut row_add = vec![[F::zero(); NUM_BATCH_FRI_PREPROCESSED_COLS]; len]; + debug_assert_eq!(*acc_mult, F::one()); + + row_add.iter_mut().enumerate().for_each(|(i, row)| { + let row: &mut BatchFRIPreprocessedCols = row.as_mut_slice().borrow_mut(); + row.is_real = F::one(); + row.is_end = F::from_bool(i == len - 1); + row.acc_addr = ext_single_addrs.acc; + row.alpha_pow_addr = ext_vec_addrs.alpha_pow[i]; + row.p_at_z_addr = ext_vec_addrs.p_at_z[i]; + row.p_at_x_addr = base_vec_addrs.p_at_x[i]; + }); + rows.extend(row_add); + }); + + // Pad the trace to a power of two. + pad_rows_fixed( + &mut rows, + || [F::zero(); NUM_BATCH_FRI_PREPROCESSED_COLS], + program.fixed_log2_rows(self), + ); + + let trace = RowMajorMatrix::new( + rows.into_iter().flatten().collect(), + NUM_BATCH_FRI_PREPROCESSED_COLS, + ); + Some(trace) + } + + #[instrument(name = "generate batch fri trace", level = "debug", skip_all, fields(rows = input.batch_fri_events.len()))] + fn generate_trace( + &self, + input: &ExecutionRecord, + _: &mut ExecutionRecord, + ) -> RowMajorMatrix { + let mut rows = input + .batch_fri_events + .iter() + .map(|event| { + let mut row = [F::zero(); NUM_BATCH_FRI_COLS]; + let cols: &mut BatchFRICols = row.as_mut_slice().borrow_mut(); + cols.acc = event.ext_single.acc; + cols.alpha_pow = event.ext_vec.alpha_pow; + cols.p_at_z = event.ext_vec.p_at_z; + cols.p_at_x = event.base_vec.p_at_x; + row + }) + .collect_vec(); + + // Pad the trace to a power of two. + pad_rows_fixed(&mut rows, || [F::zero(); NUM_BATCH_FRI_COLS], input.fixed_log2_rows(self)); + + // Convert the trace to a row major matrix. + let trace = RowMajorMatrix::new(rows.into_iter().flatten().collect(), NUM_BATCH_FRI_COLS); + + #[cfg(debug_assertions)] + println!( + "batch fri trace dims is width: {:?}, height: {:?}", + trace.width(), + trace.height() + ); + + trace + } + + fn included(&self, _record: &Self::Record) -> bool { + true + } +} + +impl BatchFRIChip { + pub fn eval_batch_fri( + &self, + builder: &mut AB, + local: &BatchFRICols, + next: &BatchFRICols, + local_prepr: &BatchFRIPreprocessedCols, + _next_prepr: &BatchFRIPreprocessedCols, + ) { + // Constrain memory read for alpha_pow, p_at_z, and p_at_x. + builder.receive_block(local_prepr.alpha_pow_addr, local.alpha_pow, local_prepr.is_real); + builder.receive_block(local_prepr.p_at_z_addr, local.p_at_z, local_prepr.is_real); + builder.receive_single(local_prepr.p_at_x_addr, local.p_at_x, local_prepr.is_real); + + // Constrain memory write for the accumulator. + // Note that we write with multiplicity 1, when `is_end` is true. + builder.send_block(local_prepr.acc_addr, local.acc, local_prepr.is_end); + + // Constrain the accumulator value of the first row. + builder.when_first_row().assert_ext_eq( + local.acc.as_extension::(), + local.alpha_pow.as_extension::() + * (local.p_at_z.as_extension::() + - BinomialExtension::from_base(local.p_at_x.into())), + ); + + // Constrain the accumulator of the next row when the current row is the end of loop. + builder.when_transition().when(local_prepr.is_end).assert_ext_eq( + next.acc.as_extension::(), + next.alpha_pow.as_extension::() + * (next.p_at_z.as_extension::() + - BinomialExtension::from_base(next.p_at_x.into())), + ); + + // Constrain the accumulator of the next row when the current row is not the end of loop. + builder.when_transition().when_not(local_prepr.is_end).assert_ext_eq( + next.acc.as_extension::(), + local.acc.as_extension::() + + next.alpha_pow.as_extension::() + * (next.p_at_z.as_extension::() + - BinomialExtension::from_base(next.p_at_x.into())), + ); + } + + pub const fn do_memory_access(local: &BatchFRIPreprocessedCols) -> T { + local.is_real + } +} + +impl Air for BatchFRIChip +where + AB: SP1RecursionAirBuilder + PairBuilder, +{ + fn eval(&self, builder: &mut AB) { + let main = builder.main(); + let (local, next) = (main.row_slice(0), main.row_slice(1)); + let local: &BatchFRICols = (*local).borrow(); + let next: &BatchFRICols = (*next).borrow(); + let prepr = builder.preprocessed(); + let (prepr_local, prepr_next) = (prepr.row_slice(0), prepr.row_slice(1)); + let prepr_local: &BatchFRIPreprocessedCols = (*prepr_local).borrow(); + let prepr_next: &BatchFRIPreprocessedCols = (*prepr_next).borrow(); + + // Dummy constraints to normalize to DEGREE. + let lhs = (0..DEGREE).map(|_| prepr_local.is_real.into()).product::(); + let rhs = (0..DEGREE).map(|_| prepr_local.is_real.into()).product::(); + builder.assert_eq(lhs, rhs); + + self.eval_batch_fri::(builder, local, next, prepr_local, prepr_next); + } +} diff --git a/crates/recursion/core/src/chips/mod.rs b/crates/recursion/core/src/chips/mod.rs index 61f2be6a5e..ef2d65691a 100644 --- a/crates/recursion/core/src/chips/mod.rs +++ b/crates/recursion/core/src/chips/mod.rs @@ -1,5 +1,6 @@ pub mod alu_base; pub mod alu_ext; +pub mod batch_fri; pub mod exp_reverse_bits; pub mod fri_fold; pub mod mem; diff --git a/crates/recursion/core/src/lib.rs b/crates/recursion/core/src/lib.rs index 8a90a2f593..8f526935c7 100644 --- a/crates/recursion/core/src/lib.rs +++ b/crates/recursion/core/src/lib.rs @@ -217,6 +217,52 @@ pub struct FriFoldEvent { pub ext_vec: FriFoldExtVecIo>, } +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct BatchFRIIo { + pub ext_single: BatchFRIExtSingleIo>, + pub ext_vec: BatchFRIExtVecIo>>, + pub base_vec: BatchFRIBaseVecIo, +} + +/// The extension-field-valued single inputs to the batch FRI operation. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct BatchFRIExtSingleIo { + pub acc: V, +} + +/// The extension-field-valued vector inputs to the batch FRI operation. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct BatchFRIExtVecIo { + pub p_at_z: V, + pub alpha_pow: V, +} + +/// The base-field-valued vector inputs to the batch FRI operation. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct BatchFRIBaseVecIo { + pub p_at_x: V, +} + +/// An instruction invoking the batch FRI operation. Addresses for extension field elements are of +/// the same type as for base field elements. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct BatchFRIInstr { + pub base_vec_addrs: BatchFRIBaseVecIo>>, + pub ext_single_addrs: BatchFRIExtSingleIo>, + pub ext_vec_addrs: BatchFRIExtVecIo>>, + pub acc_mult: F, +} + +/// The event encoding the data of a single iteration within the batch FRI operation. +/// For any given event, we are accessing a single element of the `Vec` inputs, so that the event +/// is not a type alias for `BatchFRIIo` like many of the other events. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct BatchFRIEvent { + pub base_vec: BatchFRIBaseVecIo, + pub ext_single: BatchFRIExtSingleIo>, + pub ext_vec: BatchFRIExtVecIo>, +} + /// An instruction that will save the public values to the execution record and will commit to /// it's digest. #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/crates/recursion/core/src/machine.rs b/crates/recursion/core/src/machine.rs index 4bb7c87888..b143487d1d 100644 --- a/crates/recursion/core/src/machine.rs +++ b/crates/recursion/core/src/machine.rs @@ -11,6 +11,7 @@ use crate::{ chips::{ alu_base::{BaseAluChip, NUM_BASE_ALU_ENTRIES_PER_ROW}, alu_ext::{ExtAluChip, NUM_EXT_ALU_ENTRIES_PER_ROW}, + batch_fri::BatchFRIChip, exp_reverse_bits::ExpReverseBitsLenChip, fri_fold::FriFoldChip, mem::{ @@ -42,6 +43,7 @@ pub enum RecursionAir, const DEGREE: u Poseidon2Wide(Poseidon2WideChip), Select(SelectChip), FriFold(FriFoldChip), + BatchFRI(BatchFRIChip), ExpReverseBitsLen(ExpReverseBitsLenChip), PublicValues(PublicValuesChip), } @@ -54,6 +56,7 @@ pub struct RecursionAirEventCount { pub ext_alu_events: usize, pub poseidon2_wide_events: usize, pub fri_fold_events: usize, + pub batch_fri_events: usize, pub select_events: usize, pub exp_reverse_bits_len_events: usize, } @@ -70,6 +73,7 @@ impl, const DEGREE: usize> RecursionAi RecursionAir::ExtAlu(ExtAluChip), RecursionAir::Poseidon2Wide(Poseidon2WideChip::), RecursionAir::FriFold(FriFoldChip::::default()), + RecursionAir::BatchFRI(BatchFRIChip::), RecursionAir::Select(SelectChip), RecursionAir::ExpReverseBitsLen(ExpReverseBitsLenChip::), RecursionAir::PublicValues(PublicValuesChip), @@ -91,6 +95,7 @@ impl, const DEGREE: usize> RecursionAi RecursionAir::ExtAlu(ExtAluChip), RecursionAir::Poseidon2Skinny(Poseidon2SkinnyChip::::default()), RecursionAir::FriFold(FriFoldChip::::default()), + RecursionAir::BatchFRI(BatchFRIChip::), RecursionAir::Select(SelectChip), RecursionAir::ExpReverseBitsLen(ExpReverseBitsLenChip::), RecursionAir::PublicValues(PublicValuesChip), @@ -109,6 +114,7 @@ impl, const DEGREE: usize> RecursionAi RecursionAir::BaseAlu(BaseAluChip), RecursionAir::ExtAlu(ExtAluChip), RecursionAir::Poseidon2Wide(Poseidon2WideChip::), + RecursionAir::BatchFRI(BatchFRIChip::), RecursionAir::Select(SelectChip), RecursionAir::ExpReverseBitsLen(ExpReverseBitsLenChip::), RecursionAir::PublicValues(PublicValuesChip), @@ -134,6 +140,7 @@ impl, const DEGREE: usize> RecursionAi RecursionAir::BaseAlu(BaseAluChip), RecursionAir::ExtAlu(ExtAluChip), RecursionAir::Poseidon2Skinny(Poseidon2SkinnyChip::::default()), + RecursionAir::BatchFRI(BatchFRIChip::), RecursionAir::Select(SelectChip), // RecursionAir::ExpReverseBitsLen(ExpReverseBitsLenChip::), RecursionAir::PublicValues(PublicValuesChip), @@ -152,6 +159,7 @@ impl, const DEGREE: usize> RecursionAi (Self::BaseAlu(BaseAluChip), 20), (Self::ExtAlu(ExtAluChip), 18), (Self::Poseidon2Wide(Poseidon2WideChip::), 16), + (Self::BatchFRI(BatchFRIChip::), 18), (Self::Select(SelectChip), 18), (Self::ExpReverseBitsLen(ExpReverseBitsLenChip::), 17), (Self::PublicValues(PublicValuesChip), PUB_VALUES_LOG_HEIGHT), @@ -185,6 +193,7 @@ impl, const DEGREE: usize> RecursionAi heights.ext_alu_events.div_ceil(NUM_EXT_ALU_ENTRIES_PER_ROW), ), (Self::Poseidon2Wide(Poseidon2WideChip::), heights.poseidon2_wide_events), + (Self::BatchFRI(BatchFRIChip::), heights.batch_fri_events), (Self::Select(SelectChip), heights.select_events), ( Self::ExpReverseBitsLen(ExpReverseBitsLenChip::), @@ -219,6 +228,9 @@ impl AddAssign<&Instruction> for RecursionAirEventCount { input_addr: _, // No receive interaction for the hint operation }) => self.mem_var_events += output_addrs_mults.len(), Instruction::FriFold(_) => self.fri_fold_events += 1, + Instruction::BatchFRI(instr) => { + self.batch_fri_events += instr.base_vec_addrs.p_at_x.len() + } Instruction::CommitPublicValues(_) => {} Instruction::Print(_) => {} } diff --git a/crates/recursion/core/src/runtime/instruction.rs b/crates/recursion/core/src/runtime/instruction.rs index d18b4ca910..7a74097246 100644 --- a/crates/recursion/core/src/runtime/instruction.rs +++ b/crates/recursion/core/src/runtime/instruction.rs @@ -15,6 +15,7 @@ pub enum Instruction { ExpReverseBitsLen(ExpReverseBitsInstr), HintBits(HintBitsInstr), FriFold(Box>), + BatchFRI(Box>), Print(PrintInstr), HintExt2Felts(HintExt2FeltsInstr), CommitPublicValues(Box>), @@ -227,6 +228,27 @@ pub fn fri_fold( })) } +#[allow(clippy::too_many_arguments)] +pub fn batch_fri( + acc: u32, + alpha_pows: Vec, + p_at_zs: Vec, + p_at_xs: Vec, + acc_mult: u32, +) -> Instruction { + Instruction::BatchFRI(Box::new(BatchFRIInstr { + base_vec_addrs: BatchFRIBaseVecIo { + p_at_x: p_at_xs.iter().map(|elm| Address(F::from_canonical_u32(*elm))).collect(), + }, + ext_single_addrs: BatchFRIExtSingleIo { acc: Address(F::from_canonical_u32(acc)) }, + ext_vec_addrs: BatchFRIExtVecIo { + p_at_z: p_at_zs.iter().map(|elm| Address(F::from_canonical_u32(*elm))).collect(), + alpha_pow: alpha_pows.iter().map(|elm| Address(F::from_canonical_u32(*elm))).collect(), + }, + acc_mult: F::from_canonical_u32(acc_mult), + })) +} + pub fn commit_public_values( public_values_a: &RecursionPublicValues, ) -> Instruction { diff --git a/crates/recursion/core/src/runtime/mod.rs b/crates/recursion/core/src/runtime/mod.rs index 2478a45ddb..e60140a91a 100644 --- a/crates/recursion/core/src/runtime/mod.rs +++ b/crates/recursion/core/src/runtime/mod.rs @@ -91,6 +91,8 @@ pub struct Runtime<'a, F: PrimeField32, EF: ExtensionField, Diffusion> { pub nb_fri_fold: usize, + pub nb_batch_fri: usize, + pub nb_print_f: usize, pub nb_print_e: usize, @@ -197,6 +199,7 @@ where nb_memory_ops: 0, nb_branch_ops: 0, nb_fri_fold: 0, + nb_batch_fri: 0, nb_print_f: 0, nb_print_e: 0, clk: F::zero(), @@ -221,6 +224,7 @@ where tracing::debug!("FriFold Operations: {}", self.nb_fri_fold); tracing::debug!("Field Operations: {}", self.nb_base_ops); tracing::debug!("Extension Operations: {}", self.nb_ext_ops); + tracing::debug!("BatchFRI Operations: {}", self.nb_batch_fri); tracing::debug!("Memory Operations: {}", self.nb_memory_ops); tracing::debug!("Branch Operations: {}", self.nb_branch_ops); for (name, entry) in self.cycle_tracker.iter().sorted_by_key(|(name, _)| *name) { @@ -485,7 +489,48 @@ where }); } } + Instruction::BatchFRI(instr) => { + let BatchFRIInstr { base_vec_addrs, ext_single_addrs, ext_vec_addrs, acc_mult } = + *instr; + + let mut acc = EF::zero(); + let p_at_xs = base_vec_addrs + .p_at_x + .iter() + .map(|addr| self.memory.mr(*addr).val[0]) + .collect_vec(); + let p_at_zs = ext_vec_addrs + .p_at_z + .iter() + .map(|addr| self.memory.mr(*addr).val.ext::()) + .collect_vec(); + let alpha_pows: Vec<_> = ext_vec_addrs + .alpha_pow + .iter() + .map(|addr| self.memory.mr(*addr).val.ext::()) + .collect_vec(); + self.nb_batch_fri += p_at_zs.len(); + for m in 0..p_at_zs.len() { + acc += alpha_pows[m] * (p_at_zs[m] - EF::from_base(p_at_xs[m])); + self.record.batch_fri_events.push(BatchFRIEvent { + base_vec: BatchFRIBaseVecIo { p_at_x: p_at_xs[m] }, + ext_single: BatchFRIExtSingleIo { + acc: Block::from(acc.as_base_slice()), + }, + ext_vec: BatchFRIExtVecIo { + p_at_z: Block::from(p_at_zs[m].as_base_slice()), + alpha_pow: Block::from(alpha_pows[m].as_base_slice()), + }, + }); + } + + let _ = self.memory.mw( + ext_single_addrs.acc, + Block::from(acc.as_base_slice()), + acc_mult, + ); + } Instruction::CommitPublicValues(instr) => { let pv_addrs = instr.pv_addrs.as_array(); let pv_values: [F; RECURSIVE_PROOF_NUM_PV_ELTS] = diff --git a/crates/recursion/core/src/runtime/record.rs b/crates/recursion/core/src/runtime/record.rs index dd645b74af..94f2f4079a 100644 --- a/crates/recursion/core/src/runtime/record.rs +++ b/crates/recursion/core/src/runtime/record.rs @@ -5,8 +5,8 @@ use p3_field::{AbstractField, Field, PrimeField32}; use sp1_stark::{air::MachineAir, MachineRecord, SP1CoreOpts, PROOF_MAX_NUM_PVS}; use super::{ - BaseAluEvent, CommitPublicValuesEvent, ExpReverseBitsEvent, ExtAluEvent, FriFoldEvent, - MemEvent, Poseidon2Event, RecursionProgram, RecursionPublicValues, SelectEvent, + BaseAluEvent, BatchFRIEvent, CommitPublicValuesEvent, ExpReverseBitsEvent, ExtAluEvent, + FriFoldEvent, MemEvent, Poseidon2Event, RecursionProgram, RecursionPublicValues, SelectEvent, }; #[derive(Clone, Default, Debug)] @@ -26,6 +26,7 @@ pub struct ExecutionRecord { pub select_events: Vec>, pub exp_reverse_bits_len_events: Vec>, pub fri_fold_events: Vec>, + pub batch_fri_events: Vec>, pub commit_pv_hash_events: Vec>, } @@ -59,6 +60,7 @@ impl MachineRecord for ExecutionRecord { select_events, exp_reverse_bits_len_events, fri_fold_events, + batch_fri_events, commit_pv_hash_events, } = self; base_alu_events.append(&mut other.base_alu_events); @@ -69,6 +71,7 @@ impl MachineRecord for ExecutionRecord { select_events.append(&mut other.select_events); exp_reverse_bits_len_events.append(&mut other.exp_reverse_bits_len_events); fri_fold_events.append(&mut other.fri_fold_events); + batch_fri_events.append(&mut other.batch_fri_events); commit_pv_hash_events.append(&mut other.commit_pv_hash_events); } diff --git a/crates/recursion/core/src/shape.rs b/crates/recursion/core/src/shape.rs index 64756d3fed..39f47cf72c 100644 --- a/crates/recursion/core/src/shape.rs +++ b/crates/recursion/core/src/shape.rs @@ -11,6 +11,7 @@ use crate::{ chips::{ alu_base::BaseAluChip, alu_ext::ExtAluChip, + batch_fri::BatchFRIChip, exp_reverse_bits::ExpReverseBitsLenChip, mem::{MemoryConstChip, MemoryVarChip}, poseidon2_wide::Poseidon2WideChip, @@ -93,6 +94,7 @@ impl, const DEGREE: usize> Default let ext_alu = RecursionAir::::ExtAlu(ExtAluChip).name(); let poseidon2_wide = RecursionAir::::Poseidon2Wide(Poseidon2WideChip::).name(); + let batch_fri = RecursionAir::::BatchFRI(BatchFRIChip::).name(); let select = RecursionAir::::Select(SelectChip).name(); let exp_reverse_bits_len = RecursionAir::::ExpReverseBitsLen(ExpReverseBitsLenChip::).name(); @@ -107,6 +109,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 17), (mem_const.clone(), 17), (poseidon2_wide.clone(), 16), + (batch_fri.clone(), 18), (select.clone(), 18), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -117,6 +120,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 17), (mem_const.clone(), 16), (poseidon2_wide.clone(), 16), + (batch_fri.clone(), 18), (select.clone(), 18), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -127,6 +131,7 @@ impl, const DEGREE: usize> Default (poseidon2_wide.clone(), 17), (mem_const.clone(), 16), (exp_reverse_bits_len.clone(), 16), + (batch_fri.clone(), 20), (select.clone(), 18), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -137,6 +142,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 17), (mem_const.clone(), 16), (poseidon2_wide.clone(), 16), + (batch_fri.clone(), 18), (select.clone(), 18), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -147,6 +153,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 16), (mem_const.clone(), 16), (poseidon2_wide.clone(), 16), + (batch_fri.clone(), 18), (select.clone(), 18), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -157,6 +164,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 17), (mem_const.clone(), 17), (poseidon2_wide.clone(), 17), + (batch_fri.clone(), 19), (select.clone(), 19), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -167,6 +175,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 18), (mem_const.clone(), 18), (poseidon2_wide.clone(), 17), + (batch_fri.clone(), 19), (select.clone(), 19), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -177,6 +186,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 18), (mem_const.clone(), 17), (poseidon2_wide.clone(), 17), + (batch_fri.clone(), 19), (select.clone(), 19), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -187,6 +197,7 @@ impl, const DEGREE: usize> Default (poseidon2_wide.clone(), 18), (mem_const.clone(), 17), (exp_reverse_bits_len.clone(), 17), + (batch_fri.clone(), 21), (select.clone(), 19), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -197,6 +208,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 18), (mem_const.clone(), 17), (poseidon2_wide.clone(), 17), + (batch_fri.clone(), 19), (select.clone(), 19), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -207,6 +219,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 17), (mem_const.clone(), 17), (poseidon2_wide.clone(), 17), + (batch_fri.clone(), 19), (select.clone(), 19), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], @@ -217,6 +230,7 @@ impl, const DEGREE: usize> Default (exp_reverse_bits_len.clone(), 18), (mem_const.clone(), 18), (poseidon2_wide.clone(), 18), + (batch_fri.clone(), 20), (select.clone(), 19), (public_values.clone(), PUB_VALUES_LOG_HEIGHT), ], diff --git a/crates/zkvm/entrypoint/src/memcpy.s b/crates/zkvm/entrypoint/src/memcpy.s index 1735cae5c7..bbf5f1cd73 100644 --- a/crates/zkvm/entrypoint/src/memcpy.s +++ b/crates/zkvm/entrypoint/src/memcpy.s @@ -173,7 +173,7 @@ // All other files which have no copyright comments are original works // produced specifically for use as part of this library, written either // by Rich Felker, the main author of the library, or by one or more -// contibutors listed above. Details on authorship of individual files +// contributors listed above. Details on authorship of individual files // can be found in the git version control history of the project. The // omission of copyright and license comments in each file is in the // interest of source tree size. diff --git a/crates/zkvm/entrypoint/src/memset.s b/crates/zkvm/entrypoint/src/memset.s index a19a11da89..7415aea300 100644 --- a/crates/zkvm/entrypoint/src/memset.s +++ b/crates/zkvm/entrypoint/src/memset.s @@ -173,7 +173,7 @@ // All other files which have no copyright comments are original works // produced specifically for use as part of this library, written either // by Rich Felker, the main author of the library, or by one or more -// contibutors listed above. Details on authorship of individual files +// contributors listed above. Details on authorship of individual files // can be found in the git version control history of the project. The // omission of copyright and license comments in each file is in the // interest of source tree size. From 0a26f9f9e5a84b03612a9c80acb87455a4f94d83 Mon Sep 17 00:00:00 2001 From: rkm0959 Date: Fri, 1 Nov 2024 14:51:58 -0700 Subject: [PATCH 10/17] chore: fix comments and logging for select precompile (#1738) --- crates/recursion/compiler/src/ir/instructions.rs | 3 +-- crates/recursion/core/src/lib.rs | 6 +++--- crates/recursion/core/src/runtime/mod.rs | 1 + 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/recursion/compiler/src/ir/instructions.rs b/crates/recursion/compiler/src/ir/instructions.rs index 5fbd0fa210..04ddb26713 100644 --- a/crates/recursion/compiler/src/ir/instructions.rs +++ b/crates/recursion/compiler/src/ir/instructions.rs @@ -120,8 +120,7 @@ pub enum DslIr { /// Inverts an extension field element (ext = 1 / ext). InvE(Ext, Ext), - // Selecting Digest. - /// Selects the digest based on a bit (should_swap, first result, second result, first input, second input) + /// Selects order of felts based on a bit (should_swap, first result, second result, first input, second input) Select(Felt, Felt, Felt, Felt, Felt), // Control flow. diff --git a/crates/recursion/core/src/lib.rs b/crates/recursion/core/src/lib.rs index 8f526935c7..bec9e0b0ab 100644 --- a/crates/recursion/core/src/lib.rs +++ b/crates/recursion/core/src/lib.rs @@ -116,7 +116,7 @@ pub struct Poseidon2SkinnyInstr { pub type Poseidon2Event = Poseidon2Io; -/// The inputs and outputs to a select digest operation. +/// The inputs and outputs to a select operation. #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct SelectIo { pub bit: V, @@ -126,7 +126,7 @@ pub struct SelectIo { pub in2: V, } -/// An instruction invoking the select digest operation. +/// An instruction invoking the select operation. #[derive(Clone, Copy, Debug, Serialize, Deserialize)] pub struct SelectInstr { pub addrs: SelectIo>, @@ -134,7 +134,7 @@ pub struct SelectInstr { pub mult2: F, } -/// The event encoding the inputs and outputs of a select digest operation. +/// The event encoding the inputs and outputs of a select operation. pub type SelectEvent = SelectIo; /// The inputs and outputs to an exp-reverse-bits operation. diff --git a/crates/recursion/core/src/runtime/mod.rs b/crates/recursion/core/src/runtime/mod.rs index e60140a91a..90bdd1fb55 100644 --- a/crates/recursion/core/src/runtime/mod.rs +++ b/crates/recursion/core/src/runtime/mod.rs @@ -223,6 +223,7 @@ where tracing::debug!("Exp Reverse Bits Operations: {}", self.nb_exp_reverse_bits); tracing::debug!("FriFold Operations: {}", self.nb_fri_fold); tracing::debug!("Field Operations: {}", self.nb_base_ops); + tracing::debug!("Select Operations: {}", self.nb_select); tracing::debug!("Extension Operations: {}", self.nb_ext_ops); tracing::debug!("BatchFRI Operations: {}", self.nb_batch_fri); tracing::debug!("Memory Operations: {}", self.nb_memory_ops); From eaec49a1f2d6eac8f8c9c08ef99205d7ca49c552 Mon Sep 17 00:00:00 2001 From: rkm0959 Date: Fri, 1 Nov 2024 14:53:14 -0700 Subject: [PATCH 11/17] perf: implement local-only optimization (#1711) --- crates/core/machine/src/riscv/mod.rs | 1 + crates/derive/src/lib.rs | 13 ++++ crates/recursion/circuit/src/stark.rs | 35 ++++++++--- crates/recursion/core/src/chips/alu_base.rs | 4 ++ crates/recursion/core/src/chips/alu_ext.rs | 4 ++ .../recursion/core/src/chips/mem/constant.rs | 4 ++ .../recursion/core/src/chips/mem/variable.rs | 4 ++ .../core/src/chips/poseidon2_wide/trace.rs | 4 ++ crates/recursion/core/src/chips/select.rs | 4 ++ crates/stark/src/air/machine.rs | 5 ++ crates/stark/src/chip.rs | 4 ++ crates/stark/src/machine.rs | 18 ++++-- crates/stark/src/prover.rs | 63 ++++++++++++++----- crates/stark/src/verifier.rs | 33 ++++++---- 14 files changed, 156 insertions(+), 40 deletions(-) diff --git a/crates/core/machine/src/riscv/mod.rs b/crates/core/machine/src/riscv/mod.rs index b2395acf5e..8865c937a7 100644 --- a/crates/core/machine/src/riscv/mod.rs +++ b/crates/core/machine/src/riscv/mod.rs @@ -745,6 +745,7 @@ pub mod tests { assert_eq!(pk.traces, deserialized_pk.traces); assert_eq!(pk.data.root(), deserialized_pk.data.root()); assert_eq!(pk.chip_ordering, deserialized_pk.chip_ordering); + assert_eq!(pk.local_only, deserialized_pk.local_only); let serialized_vk = bincode::serialize(&vk).unwrap(); let deserialized_vk: StarkVerifyingKey = diff --git a/crates/derive/src/lib.rs b/crates/derive/src/lib.rs index 924be7d913..3721b9b93e 100644 --- a/crates/derive/src/lib.rs +++ b/crates/derive/src/lib.rs @@ -191,6 +191,13 @@ pub fn machine_air_derive(input: TokenStream) -> TokenStream { } }); + let local_only_arms = variants.iter().map(|(variant_name, field)| { + let field_ty = &field.ty; + quote! { + #name::#variant_name(x) => <#field_ty as sp1_stark::air::MachineAir>::local_only(x) + } + }); + let machine_air = quote! { impl #impl_generics sp1_stark::air::MachineAir for #name #ty_generics #where_clause { type Record = #execution_record_path; @@ -249,6 +256,12 @@ pub fn machine_air_derive(input: TokenStream) -> TokenStream { #(#commit_scope_arms,)* } } + + fn local_only(&self) -> bool { + match self { + #(#local_only_arms,)* + } + } } }; diff --git a/crates/recursion/circuit/src/stark.rs b/crates/recursion/circuit/src/stark.rs index 26e83c76d3..feb81e0ef4 100644 --- a/crates/recursion/circuit/src/stark.rs +++ b/crates/recursion/circuit/src/stark.rs @@ -358,10 +358,18 @@ where .map(|(name, domain, _)| { let i = chip_ordering[name]; let values = opened_values.chips[i].preprocessed.clone(); - TwoAdicPcsMatsVariable:: { - domain: *domain, - points: vec![zeta, domain.next_point_variable(builder, zeta)], - values: vec![values.local, values.next], + if !chips[i].local_only() { + TwoAdicPcsMatsVariable:: { + domain: *domain, + points: vec![zeta, domain.next_point_variable(builder, zeta)], + values: vec![values.local, values.next], + } + } else { + TwoAdicPcsMatsVariable:: { + domain: *domain, + points: vec![zeta], + values: vec![values.local], + } } }) .collect::>(); @@ -369,10 +377,21 @@ where let main_domains_points_and_opens = trace_domains .iter() .zip_eq(opened_values.chips.iter()) - .map(|(domain, values)| TwoAdicPcsMatsVariable:: { - domain: *domain, - points: vec![zeta, domain.next_point_variable(builder, zeta)], - values: vec![values.main.local.clone(), values.main.next.clone()], + .zip_eq(chips.iter()) + .map(|((domain, values), chip)| { + if !chip.local_only() { + TwoAdicPcsMatsVariable:: { + domain: *domain, + points: vec![zeta, domain.next_point_variable(builder, zeta)], + values: vec![values.main.local.clone(), values.main.next.clone()], + } + } else { + TwoAdicPcsMatsVariable:: { + domain: *domain, + points: vec![zeta], + values: vec![values.main.local.clone()], + } + } }) .collect::>(); diff --git a/crates/recursion/core/src/chips/alu_base.rs b/crates/recursion/core/src/chips/alu_base.rs index ba29d34434..f587c73ce8 100644 --- a/crates/recursion/core/src/chips/alu_base.rs +++ b/crates/recursion/core/src/chips/alu_base.rs @@ -149,6 +149,10 @@ impl MachineAir for BaseAluChip { fn included(&self, _record: &Self::Record) -> bool { true } + + fn local_only(&self) -> bool { + true + } } impl Air for BaseAluChip diff --git a/crates/recursion/core/src/chips/alu_ext.rs b/crates/recursion/core/src/chips/alu_ext.rs index 89e7940e49..b698a5d209 100644 --- a/crates/recursion/core/src/chips/alu_ext.rs +++ b/crates/recursion/core/src/chips/alu_ext.rs @@ -147,6 +147,10 @@ impl> MachineAir for ExtAluChip { fn included(&self, _record: &Self::Record) -> bool { true } + + fn local_only(&self) -> bool { + true + } } impl Air for ExtAluChip diff --git a/crates/recursion/core/src/chips/mem/constant.rs b/crates/recursion/core/src/chips/mem/constant.rs index 27bc64b8da..9298de73ec 100644 --- a/crates/recursion/core/src/chips/mem/constant.rs +++ b/crates/recursion/core/src/chips/mem/constant.rs @@ -122,6 +122,10 @@ impl MachineAir for MemoryChip { fn included(&self, _record: &Self::Record) -> bool { true } + + fn local_only(&self) -> bool { + true + } } impl Air for MemoryChip diff --git a/crates/recursion/core/src/chips/mem/variable.rs b/crates/recursion/core/src/chips/mem/variable.rs index a5b1fb3156..98ae999ba4 100644 --- a/crates/recursion/core/src/chips/mem/variable.rs +++ b/crates/recursion/core/src/chips/mem/variable.rs @@ -120,6 +120,10 @@ impl MachineAir for MemoryChip { fn included(&self, _record: &Self::Record) -> bool { true } + + fn local_only(&self) -> bool { + true + } } impl Air for MemoryChip diff --git a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs index 19a3b6f287..e13717bfae 100644 --- a/crates/recursion/core/src/chips/poseidon2_wide/trace.rs +++ b/crates/recursion/core/src/chips/poseidon2_wide/trace.rs @@ -82,6 +82,10 @@ impl MachineAir for Poseidon2WideChip bool { + true + } + fn preprocessed_width(&self) -> usize { PREPROCESSED_POSEIDON2_WIDTH } diff --git a/crates/recursion/core/src/chips/select.rs b/crates/recursion/core/src/chips/select.rs index eebfe7e674..d1c44d9b94 100644 --- a/crates/recursion/core/src/chips/select.rs +++ b/crates/recursion/core/src/chips/select.rs @@ -119,6 +119,10 @@ impl MachineAir for SelectChip { fn included(&self, _record: &Self::Record) -> bool { true } + + fn local_only(&self) -> bool { + true + } } impl Air for SelectChip diff --git a/crates/stark/src/air/machine.rs b/crates/stark/src/air/machine.rs index 4973c4769c..0a9b0af4a8 100644 --- a/crates/stark/src/air/machine.rs +++ b/crates/stark/src/air/machine.rs @@ -48,6 +48,11 @@ pub trait MachineAir: BaseAir + 'static + Send + Sync { fn commit_scope(&self) -> InteractionScope { InteractionScope::Local } + + /// Specifies whether the air only uses the local row, and not the next row. + fn local_only(&self) -> bool { + false + } } /// A program that defines the control flow of a machine through a program counter. diff --git a/crates/stark/src/chip.rs b/crates/stark/src/chip.rs index 9ba6651565..2d627d2ccd 100644 --- a/crates/stark/src/chip.rs +++ b/crates/stark/src/chip.rs @@ -213,6 +213,10 @@ where fn commit_scope(&self) -> crate::air::InteractionScope { self.air.commit_scope() } + + fn local_only(&self) -> bool { + self.air.local_only() + } } // Implement AIR directly on Chip, evaluating both execution and permutation constraints. diff --git a/crates/stark/src/machine.rs b/crates/stark/src/machine.rs index 58318614a0..5a5f5ea8db 100644 --- a/crates/stark/src/machine.rs +++ b/crates/stark/src/machine.rs @@ -66,6 +66,8 @@ pub struct StarkProvingKey { pub data: PcsProverData, /// The preprocessed chip ordering. pub chip_ordering: HashMap, + /// The preprocessed chip local only information. + pub local_only: Vec, } impl StarkProvingKey { @@ -196,19 +198,19 @@ impl>> StarkMachine { chip.preprocessed_width(), "Incorrect number of preprocessed columns for chip {chip_name}" ); - prep_trace.map(move |t| (chip_name, t)) + prep_trace.map(move |t| (chip_name, chip.local_only(), t)) }) .collect::>() }); // Order the chips and traces by trace size (biggest first), and get the ordering map. named_preprocessed_traces - .sort_by_key(|(name, trace)| (Reverse(trace.height()), name.clone())); + .sort_by_key(|(name, _, trace)| (Reverse(trace.height()), name.clone())); let pcs = self.config.pcs(); let (chip_information, domains_and_traces): (Vec<_>, Vec<_>) = named_preprocessed_traces .iter() - .map(|(name, trace)| { + .map(|(name, _, trace)| { let domain = pcs.natural_domain_for_degree(trace.height()); ((name.to_owned(), domain, trace.dimensions()), (domain, trace.to_owned())) }) @@ -222,12 +224,17 @@ impl>> StarkMachine { let chip_ordering = named_preprocessed_traces .iter() .enumerate() - .map(|(i, (name, _))| (name.to_owned(), i)) + .map(|(i, (name, _, _))| (name.to_owned(), i)) .collect::>(); + let local_only = named_preprocessed_traces + .iter() + .map(|(_, local_only, _)| local_only.to_owned()) + .collect::>(); + // Get the preprocessed traces let traces = - named_preprocessed_traces.into_iter().map(|(_, trace)| trace).collect::>(); + named_preprocessed_traces.into_iter().map(|(_, _, trace)| trace).collect::>(); let pc_start = program.pc_start(); @@ -238,6 +245,7 @@ impl>> StarkMachine { traces, data, chip_ordering: chip_ordering.clone(), + local_only, }, StarkVerifyingKey { commit, pc_start, chip_information, chip_ordering }, ) diff --git a/crates/stark/src/prover.rs b/crates/stark/src/prover.rs index 16d0eea234..d50487ce2e 100644 --- a/crates/stark/src/prover.rs +++ b/crates/stark/src/prover.rs @@ -593,15 +593,35 @@ where tracing::debug_span!("compute preprocessed opening points").in_scope(|| { pk.traces .iter() - .map(|trace| { + .zip(pk.local_only.iter()) + .map(|(trace, local_only)| { let domain = pcs.natural_domain_for_degree(trace.height()); - vec![zeta, domain.next_point(zeta).unwrap()] + if !local_only { + vec![zeta, domain.next_point(zeta).unwrap()] + } else { + vec![zeta] + } }) .collect::>() }); - let trace_opening_points = - tracing::debug_span!("compute trace opening points").in_scope(|| { + let main_trace_opening_points = tracing::debug_span!("compute main trace opening points") + .in_scope(|| { + trace_domains + .iter() + .zip(chips.iter()) + .map(|(domain, chip)| { + if !chip.local_only() { + vec![zeta, domain.next_point(zeta).unwrap()] + } else { + vec![zeta] + } + }) + .collect::>() + }); + + let permutation_trace_opening_points = + tracing::debug_span!("compute permutation trace opening points").in_scope(|| { trace_domains .iter() .map(|domain| vec![zeta, domain.next_point(zeta).unwrap()]) @@ -615,7 +635,7 @@ where // Split the trace_opening_points to the global and local chips. let mut global_trace_opening_points = Vec::with_capacity(global_chip_ordering.len()); let mut local_trace_opening_points = Vec::with_capacity(local_chip_ordering.len()); - for (i, trace_opening_point) in trace_opening_points.clone().into_iter().enumerate() { + for (i, trace_opening_point) in main_trace_opening_points.clone().into_iter().enumerate() { let scope = all_chip_scopes[i]; if scope == InteractionScope::Global { global_trace_opening_points.push(trace_opening_point); @@ -629,14 +649,14 @@ where (&pk.data, preprocessed_opening_points), (global_main_data, global_trace_opening_points), (&local_main_data, local_trace_opening_points), - (&permutation_data, trace_opening_points), + (&permutation_data, permutation_trace_opening_points), ("ient_data, quotient_opening_points), ] } else { vec![ (&pk.data, preprocessed_opening_points), (&local_main_data, local_trace_opening_points), - (&permutation_data, trace_opening_points), + (&permutation_data, permutation_trace_opening_points), ("ient_data, quotient_opening_points), ] }; @@ -669,9 +689,16 @@ where let preprocessed_opened_values = preprocessed_values .into_iter() - .map(|op| { - let [local, next] = op.try_into().unwrap(); - AirOpenedValues { local, next } + .zip(pk.local_only.iter()) + .map(|(op, local_only)| { + if !local_only { + let [local, next] = op.try_into().unwrap(); + AirOpenedValues { local, next } + } else { + let [local] = op.try_into().unwrap(); + let width = local.len(); + AirOpenedValues { local, next: vec![SC::Challenge::zero(); width] } + } }) .collect::>(); @@ -685,10 +712,10 @@ where (Some(&global_order), None) => { let global_main_values = global_main_values.as_ref().expect("Global main values should be Some"); - main_values.push(global_main_values[global_order].clone()); + main_values.push((global_main_values[global_order].clone(), chip.local_only())); } (None, Some(&local_order)) => { - main_values.push(local_main_values[local_order].clone()); + main_values.push((local_main_values[local_order].clone(), chip.local_only())); } _ => unreachable!(), } @@ -697,9 +724,15 @@ where let main_opened_values = main_values .into_iter() - .map(|op| { - let [local, next] = op.try_into().unwrap(); - AirOpenedValues { local, next } + .map(|(op, local_only)| { + if !local_only { + let [local, next] = op.try_into().unwrap(); + AirOpenedValues { local, next } + } else { + let [local] = op.try_into().unwrap(); + let width = local.len(); + AirOpenedValues { local, next: vec![SC::Challenge::zero(); width] } + } }) .collect::>(); let permutation_opened_values = permutation_values diff --git a/crates/stark/src/verifier.rs b/crates/stark/src/verifier.rs index 56d823e401..2fb3e8cef3 100644 --- a/crates/stark/src/verifier.rs +++ b/crates/stark/src/verifier.rs @@ -140,24 +140,33 @@ impl>> Verifier { .map(|(name, domain, _)| { let i = chip_ordering[name]; let values = opened_values.chips[i].preprocessed.clone(); - ( - *domain, - vec![(zeta, values.local), (domain.next_point(zeta).unwrap(), values.next)], - ) + if !chips[i].local_only() { + ( + *domain, + vec![(zeta, values.local), (domain.next_point(zeta).unwrap(), values.next)], + ) + } else { + (*domain, vec![(zeta, values.local)]) + } }) .collect::>(); let main_domains_points_and_opens = trace_domains .iter() .zip_eq(opened_values.chips.iter()) - .map(|(domain, values)| { - ( - *domain, - vec![ - (zeta, values.main.local.clone()), - (domain.next_point(zeta).unwrap(), values.main.next.clone()), - ], - ) + .zip_eq(chips.iter()) + .map(|((domain, values), chip)| { + if !chip.local_only() { + ( + *domain, + vec![ + (zeta, values.main.local.clone()), + (domain.next_point(zeta).unwrap(), values.main.next.clone()), + ], + ) + } else { + (*domain, vec![(zeta, values.main.local.clone())]) + } }) .collect::>(); From bc92c8bffb4df5e704c1dee903cff975516dd09d Mon Sep 17 00:00:00 2001 From: Matt Stam Date: Fri, 1 Nov 2024 15:27:54 -0700 Subject: [PATCH 12/17] chore: update network-v2 proto (#1725) --- crates/sdk/src/network-v2/client.rs | 2 +- crates/sdk/src/network-v2/proto/network.rs | 85 +++++++++++++++++++++- crates/sdk/src/network-v2/prover.rs | 10 +-- 3 files changed, 86 insertions(+), 11 deletions(-) diff --git a/crates/sdk/src/network-v2/client.rs b/crates/sdk/src/network-v2/client.rs index 4559b9a50d..a428dee332 100644 --- a/crates/sdk/src/network-v2/client.rs +++ b/crates/sdk/src/network-v2/client.rs @@ -26,7 +26,7 @@ use crate::network_v2::proto::network::{ use crate::network_v2::Signable; /// The default RPC endpoint for the Succinct prover network. -pub const DEFAULT_PROVER_NETWORK_RPC: &str = "https://rpc.dev.succinct.tools/"; +pub const DEFAULT_PROVER_NETWORK_RPC: &str = "https://rpc.production.succinct.tools/"; pub struct NetworkClient { signer: PrivateKeySigner, diff --git a/crates/sdk/src/network-v2/proto/network.rs b/crates/sdk/src/network-v2/proto/network.rs index 52d72ae958..b210cb9215 100644 --- a/crates/sdk/src/network-v2/proto/network.rs +++ b/crates/sdk/src/network-v2/proto/network.rs @@ -183,6 +183,18 @@ pub struct ExecuteProofResponse { } #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] pub struct ExecuteProofResponseBody {} +#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] +pub struct GetLatestBridgeBlockRequest { + /// The chain ID of the bridge. + #[prost(uint32, tag = "1")] + pub chain_id: u32, +} +#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, ::prost::Message)] +pub struct GetLatestBridgeBlockResponse { + /// The latest processed block in the bridge. + #[prost(uint64, tag = "1")] + pub block_number: u64, +} #[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, ::prost::Message)] pub struct GetBalanceRequest { /// The address of the account. @@ -447,8 +459,7 @@ impl ExecutionStatus { /// Generated client implementations. pub mod prover_network_client { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] - use tonic::codegen::http::Uri; - use tonic::codegen::*; + use tonic::codegen::{http::Uri, *}; #[derive(Debug, Clone)] pub struct ProverNetworkClient { inner: tonic::client::Grpc, @@ -626,6 +637,26 @@ pub mod prover_network_client { .insert(GrpcMethod::new("network.ProverNetwork", "GetProofRequestStatus")); self.inner.unary(req, path, codec).await } + /// Get the latest processed block in the bridge. + pub async fn get_latest_bridge_block( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result, tonic::Status> + { + self.inner.ready().await.map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = + http::uri::PathAndQuery::from_static("/network.ProverNetwork/GetLatestBridgeBlock"); + let mut req = request.into_request(); + req.extensions_mut() + .insert(GrpcMethod::new("network.ProverNetwork", "GetLatestBridgeBlock")); + self.inner.unary(req, path, codec).await + } /// Get the balance of an account. pub async fn get_balance( &mut self, @@ -684,7 +715,8 @@ pub mod prover_network_client { pub mod prover_network_server { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] use tonic::codegen::*; - /// Generated trait containing gRPC methods that should be implemented for use with ProverNetworkServer. + /// Generated trait containing gRPC methods that should be implemented for use with + /// ProverNetworkServer. #[async_trait] pub trait ProverNetwork: std::marker::Send + std::marker::Sync + 'static { /// Creates a proof. @@ -715,6 +747,11 @@ pub mod prover_network_server { &self, request: tonic::Request, ) -> std::result::Result, tonic::Status>; + /// Get the latest processed block in the bridge. + async fn get_latest_bridge_block( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status>; /// Get the balance of an account. async fn get_balance( &self, @@ -1013,6 +1050,48 @@ pub mod prover_network_server { }; Box::pin(fut) } + "/network.ProverNetwork/GetLatestBridgeBlock" => { + #[allow(non_camel_case_types)] + struct GetLatestBridgeBlockSvc(pub Arc); + impl + tonic::server::UnaryService + for GetLatestBridgeBlockSvc + { + type Response = super::GetLatestBridgeBlockResponse; + type Future = BoxFuture, tonic::Status>; + fn call( + &mut self, + request: tonic::Request, + ) -> Self::Future { + let inner = Arc::clone(&self.0); + let fut = async move { + ::get_latest_bridge_block(&inner, request).await + }; + Box::pin(fut) + } + } + let accept_compression_encodings = self.accept_compression_encodings; + let send_compression_encodings = self.send_compression_encodings; + let max_decoding_message_size = self.max_decoding_message_size; + let max_encoding_message_size = self.max_encoding_message_size; + let inner = self.inner.clone(); + let fut = async move { + let method = GetLatestBridgeBlockSvc(inner); + let codec = tonic::codec::ProstCodec::default(); + let mut grpc = tonic::server::Grpc::new(codec) + .apply_compression_config( + accept_compression_encodings, + send_compression_encodings, + ) + .apply_max_message_size_config( + max_decoding_message_size, + max_encoding_message_size, + ); + let res = grpc.unary(method, req).await; + Ok(res) + }; + Box::pin(fut) + } "/network.ProverNetwork/GetBalance" => { #[allow(non_camel_case_types)] struct GetBalanceSvc(pub Arc); diff --git a/crates/sdk/src/network-v2/prover.rs b/crates/sdk/src/network-v2/prover.rs index 8bd954a64a..d67ed34386 100644 --- a/crates/sdk/src/network-v2/prover.rs +++ b/crates/sdk/src/network-v2/prover.rs @@ -4,7 +4,7 @@ use std::{ }; use crate::{ - network_v2::client::{NetworkClient, DEFAULT_PROVER_NETWORK_RPC}, + network_v2::client::NetworkClient, network_v2::proto::network::{ProofMode, ProofStatus, ProofStrategy}, Prover, SP1Context, SP1ProofKind, SP1ProofWithPublicValues, SP1ProvingKey, SP1VerifyingKey, }; @@ -23,8 +23,8 @@ use crate::provers::{CpuProver, ProofOpts, ProverType}; /// The timeout for a proof request to be fulfilled. const TIMEOUT_SECS: u64 = 14400; -/// The default cycle limit for a proof request. -const DEFAULT_CYCLE_LIMIT: u64 = 1_000_000_000; +/// The default cycle limit for a proof request if simulation is skipped. +const DEFAULT_CYCLE_LIMIT: u64 = 100_000_000; /// An implementation of [crate::ProverClient] that can generate proofs on a remote RPC server. pub struct NetworkProver { @@ -99,10 +99,6 @@ impl NetworkProver { let request_id_hex = "0x".to_string() + &hex::encode(request_id.clone()); log::info!("Created request {} in transaction {}", request_id_hex, tx_hash_hex); - if NetworkClient::rpc_url() == DEFAULT_PROVER_NETWORK_RPC { - log::info!("View in explorer: https://explorer-v2.succinct.xyz/{}", request_id_hex); - } - Ok(request_id) } From 4370aad12dce2dbe78a0461aae4e84b9c6d9139a Mon Sep 17 00:00:00 2001 From: Matt Stam Date: Fri, 1 Nov 2024 17:26:52 -0700 Subject: [PATCH 13/17] docs: separate SP1VerifierGateway for PLONK and Groth16 (#1740) --- .../contract-addresses.md | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/book/onchain-verification/contract-addresses.md b/book/onchain-verification/contract-addresses.md index 3acb971edf..0a23f6ab2e 100644 --- a/book/onchain-verification/contract-addresses.md +++ b/book/onchain-verification/contract-addresses.md @@ -6,6 +6,27 @@ will automatically route your SP1 proof to the correct verifier based on the SP1 ## Canonical Verifier Gateways +There are different verifier gateway for each proof system: Groth16 and PLONK. This means that you +must use the correct verifier gateway depending on if you are verifying a Groth16 or PLONK proof. + +### Groth16 + +| Chain ID | Chain | Gateway | +| -------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | Mainnet | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://etherscan.io/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 11155111 | Sepolia | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://sepolia.etherscan.io/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 17000 | Holesky | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://holesky.etherscan.io/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 42161 | Arbitrum One | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://arbiscan.io/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 421614 | Arbitrum Sepolia | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://sepolia.arbiscan.io/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 8453 | Base | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://basescan.org/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 84532 | Base Sepolia | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://sepolia.basescan.org/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 10 | Optimism | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://optimistic.etherscan.io/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 11155420 | Optimism Sepolia | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://sepolia-optimism.etherscan.io/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 534351 | Scroll Sepolia | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://sepolia.scrollscan.com/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | +| 534352 | Scroll | [0x397A5f7f3dBd538f23DE225B51f532c34448dA9B](https://scrollscan.com/address/0x397A5f7f3dBd538f23DE225B51f532c34448dA9B) | + +### PLONK + | Chain ID | Chain | Gateway | | -------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | 1 | Mainnet | [0x3B6041173B80E77f038f3F2C0f9744f04837185e](https://etherscan.io/address/0x3B6041173B80E77f038f3F2C0f9744f04837185e) | @@ -16,7 +37,7 @@ will automatically route your SP1 proof to the correct verifier based on the SP1 | 8453 | Base | [0x3B6041173B80E77f038f3F2C0f9744f04837185e](https://basescan.org/address/0x3B6041173B80E77f038f3F2C0f9744f04837185e) | | 84532 | Base Sepolia | [0x3B6041173B80E77f038f3F2C0f9744f04837185e](https://sepolia.basescan.org/address/0x3B6041173B80E77f038f3F2C0f9744f04837185e) | | 10 | Optimism | [0x3B6041173B80E77f038f3F2C0f9744f04837185e](https://optimistic.etherscan.io/address/0x3b6041173b80e77f038f3f2c0f9744f04837185e) | -| 11155420 | Optimism Sepolia | [0x3B6041173B80E77f038f3F2C0f9744f04837185e](https://sepolia-optimism.etherscan.io/address/0x3B6041173B80E77f038f3F2C0f9744f04837185e) | +| 11155420 | Optimism Sepolia | [0x3B6041173B80E77f038f3F2C0f9744f04837185e](https://sepolia-optimism.etherscan.io/address/0x3B6041173B80E77f038f3F2C0f9744f04837185e) | | 534351 | Scroll Sepolia | [0x3B6041173B80E77f038f3F2C0f9744f04837185e](https://sepolia.scrollscan.com/address/0x3B6041173B80E77f038f3F2C0f9744f04837185e) | | 534352 | Scroll | [0x3B6041173B80E77f038f3F2C0f9744f04837185e](https://scrollscan.com/address/0x3B6041173B80E77f038f3F2C0f9744f04837185e) | From 97bb83dbec5fbfef56ade3d08e61e561eff5d53d Mon Sep 17 00:00:00 2001 From: Ratan Kaliani Date: Mon, 4 Nov 2024 15:10:21 -0800 Subject: [PATCH 14/17] docs: `generating-proofs.md` (#1749) --- book/generating-proofs/proof-types.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/generating-proofs/proof-types.md b/book/generating-proofs/proof-types.md index 67e5b7532b..7ebd300acf 100644 --- a/book/generating-proofs/proof-types.md +++ b/book/generating-proofs/proof-types.md @@ -28,7 +28,7 @@ client.prove(&pk, stdin).compressed().run().unwrap(); ## Groth16 (Recommended) -The Groth16 prover mode generate a SNARK proof that is ~260 bytes large and can be verified onchain for around ~270k gas. +The Groth16 prover mode generates a SNARK proof that is ~260 bytes large and can be verified onchain for around ~270k gas. The trusted setup for the Groth16 circuit keys uses the [Aztec Ignition ceremony](https://github.com/AztecProtocol/ignition-verification) + entropy contributions from members of the Succinct team. @@ -39,7 +39,7 @@ client.prove(&pk, stdin).groth16().run().unwrap(); ## PLONK -The PLONK prover mode generate a SNARK proof that is ~868 bytes large and can also be verified onchain for around ~300k gas. Plonk proofs take about ~1m30s longer to generate over a compressed proof. +The PLONK prover mode generates a SNARK proof that is ~868 bytes large and can also be verified onchain for around ~300k gas. Plonk proofs take about ~1m30s longer to generate over a compressed proof. PLONK does not require a trusted setup. From da8a772b056ecc94a101535ef70b235c9460cf48 Mon Sep 17 00:00:00 2001 From: Tamir Hemo Date: Mon, 4 Nov 2024 18:53:01 -0800 Subject: [PATCH 15/17] feat: new device proving key API (#1737) --- crates/core/machine/src/utils/prove.rs | 9 +++++-- crates/prover/src/lib.rs | 33 +++++++++++++------------- crates/recursion/circuit/src/utils.rs | 3 +-- crates/stark/src/prover.rs | 28 +++++++++++----------- 4 files changed, 39 insertions(+), 34 deletions(-) diff --git a/crates/core/machine/src/utils/prove.rs b/crates/core/machine/src/utils/prove.rs index 09a39ed049..18f857cdf3 100644 --- a/crates/core/machine/src/utils/prove.rs +++ b/crates/core/machine/src/utils/prove.rs @@ -700,7 +700,8 @@ where { let all_records = all_records_rx.iter().flatten().collect::>(); let mut challenger = prover.machine().config().challenger(); - prover.machine().debug_constraints(&pk.to_host(), all_records, &mut challenger); + let pk_host = prover.pk_to_host(pk); + prover.machine().debug_constraints(&pk_host, all_records, &mut challenger); } Ok((proof, public_values_stream, cycles)) @@ -798,7 +799,11 @@ where let prove_span = tracing::debug_span!("prove").entered(); #[cfg(feature = "debug")] - prover.machine().debug_constraints(&pk.to_host(), records.clone(), &mut challenger.clone()); + prover.machine().debug_constraints( + &prover.pk_to_host(&pk), + records.clone(), + &mut challenger.clone(), + ); let proof = prover.prove(&pk, records, &mut challenger, SP1CoreOpts::default()).unwrap(); prove_span.exit(); diff --git a/crates/prover/src/lib.rs b/crates/prover/src/lib.rs index 984e186e53..5ffd096e43 100644 --- a/crates/prover/src/lib.rs +++ b/crates/prover/src/lib.rs @@ -247,7 +247,11 @@ impl SP1Prover { let program = self.get_program(elf).unwrap(); let (pk, vk) = self.core_prover.setup(&program); let vk = SP1VerifyingKey { vk }; - let pk = SP1ProvingKey { pk: pk.to_host(), elf: elf.to_vec(), vk: vk.clone() }; + let pk = SP1ProvingKey { + pk: self.core_prover.pk_to_host(&pk), + elf: elf.to_vec(), + vk: vk.clone(), + }; (pk, vk) } @@ -292,20 +296,17 @@ impl SP1Prover { ) -> Result { context.subproof_verifier.replace(Arc::new(self)); let program = self.get_program(&pk.elf).unwrap(); - let (proof, public_values_stream, cycles) = sp1_core_machine::utils::prove_with_context::< - _, - C::CoreProver, - >( - &self.core_prover, - &>>::DeviceProvingKey::from_host( - &pk.pk, - ), - program, - stdin, - opts.core_opts, - context, - self.core_shape_config.as_ref(), - )?; + let pk = self.core_prover.pk_to_device(&pk.pk); + let (proof, public_values_stream, cycles) = + sp1_core_machine::utils::prove_with_context::<_, C::CoreProver>( + &self.core_prover, + &pk, + program, + stdin, + opts.core_opts, + context, + self.core_shape_config.as_ref(), + )?; Self::check_for_high_cycles(cycles); let public_values = SP1PublicValues::from(&public_values_stream); Ok(SP1CoreProof { @@ -819,7 +820,7 @@ impl SP1Prover { #[cfg(feature = "debug")] self.compress_prover.debug_constraints( - &pk.to_host(), + &self.compress_prover.pk_to_host(&pk), vec![record.clone()], &mut challenger.clone(), ); diff --git a/crates/recursion/circuit/src/utils.rs b/crates/recursion/circuit/src/utils.rs index 9609a5f40c..9c7eeaf8f0 100644 --- a/crates/recursion/circuit/src/utils.rs +++ b/crates/recursion/circuit/src/utils.rs @@ -107,7 +107,6 @@ pub(crate) mod tests { use sp1_recursion_core::{machine::RecursionAir, Runtime}; use sp1_stark::{ baby_bear_poseidon2::BabyBearPoseidon2, CpuProver, InnerChallenge, InnerVal, MachineProver, - MachineProvingKey, }; use crate::witness::WitnessBlock; @@ -145,8 +144,8 @@ pub(crate) mod tests { let proof_wide_span = tracing::debug_span!("Run test with wide machine").entered(); let wide_machine = RecursionAir::<_, 3>::compress_machine(SC::default()); let (pk, vk) = wide_machine.setup(&program); - let pk = P::DeviceProvingKey::from_host(&pk); let prover = P::new(wide_machine); + let pk = prover.pk_to_device(&pk); let result = run_test_machine_with_prover::<_, _, P>(&prover, records.clone(), pk, vk); proof_wide_span.exit(); diff --git a/crates/stark/src/prover.rs b/crates/stark/src/prover.rs index d50487ce2e..95d3da46c5 100644 --- a/crates/stark/src/prover.rs +++ b/crates/stark/src/prover.rs @@ -57,6 +57,12 @@ pub trait MachineProver>: /// Setup the preprocessed data into a proving and verifying key. fn setup(&self, program: &A::Program) -> (Self::DeviceProvingKey, StarkVerifyingKey); + /// Copy the proving key from the host to the device. + fn pk_to_device(&self, pk: &StarkProvingKey) -> Self::DeviceProvingKey; + + /// Copy the proving key from the device to the host. + fn pk_to_host(&self, pk: &Self::DeviceProvingKey) -> StarkProvingKey; + /// Generate the main traces. fn generate_traces( &self, @@ -273,12 +279,6 @@ pub trait MachineProvingKey: Send + Sync { /// The start pc. fn pc_start(&self) -> Val; - /// The proving key on the host. - fn to_host(&self) -> StarkProvingKey; - - /// The proving key on the device. - fn from_host(host: &StarkProvingKey) -> Self; - /// Observe itself in the challenger. fn observe_into(&self, challenger: &mut Challenger); } @@ -323,6 +323,14 @@ where self.machine().setup(program) } + fn pk_to_device(&self, pk: &StarkProvingKey) -> Self::DeviceProvingKey { + pk.clone() + } + + fn pk_to_host(&self, pk: &Self::DeviceProvingKey) -> StarkProvingKey { + pk.clone() + } + fn commit( &self, record: &A::Record, @@ -889,14 +897,6 @@ where self.pc_start } - fn to_host(&self) -> StarkProvingKey { - self.clone() - } - - fn from_host(host: &StarkProvingKey) -> Self { - host.clone() - } - fn observe_into(&self, challenger: &mut Challenger) { challenger.observe(self.commit.clone()); challenger.observe(self.pc_start); From 8067db61831866e75d2252aa4e1ce40525b93af9 Mon Sep 17 00:00:00 2001 From: Yuwen Zhang Date: Tue, 5 Nov 2024 10:01:45 -0800 Subject: [PATCH 16/17] perf: build time GRO-146 (#1739) --- .github/workflows/pr.yml | 9 - Cargo.lock | 1609 ++++------------- crates/core/machine/Cargo.toml | 3 - crates/eval/Cargo.toml | 2 - crates/perf/Cargo.toml | 7 - crates/prover/Cargo.toml | 6 - crates/sdk/Cargo.toml | 17 +- crates/sdk/src/network/auth.rs | 17 +- crates/stark/Cargo.toml | 2 - examples/Cargo.lock | 2317 ++++++++----------------- examples/groth16/script/Cargo.toml | 1 - examples/tendermint/script/Cargo.toml | 1 - tests/bls12381-double/Cargo.toml | 1 - tests/ed-add/Cargo.toml | 2 - tests/rand/Cargo.toml | 1 - 15 files changed, 1020 insertions(+), 2975 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 41b37ae3db..911d5ffa43 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -118,15 +118,6 @@ jobs: env: CARGO_INCREMENTAL: 1 - - name: Add wasm target - run: rustup target add wasm32-unknown-unknown - - - name: Check wasm compatibility for sdk - uses: actions-rs/cargo@v1 - with: - command: check - args: -p sp1-sdk --target wasm32-unknown-unknown --no-default-features - examples: name: Examples runs-on: diff --git a/Cargo.lock b/Cargo.lock index 748f845ec7..749e664748 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,16 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "addchain" version = "0.2.0" @@ -55,18 +45,7 @@ checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" dependencies = [ "aes-soft", "aesni", - "cipher 0.2.5", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher 0.4.4", - "cpufeatures", + "cipher", ] [[package]] @@ -76,9 +55,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" dependencies = [ "aead", - "aes 0.6.0", - "cipher 0.2.5", - "ctr 0.6.0", + "aes", + "cipher", + "ctr", "ghash", "subtle", ] @@ -89,7 +68,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" dependencies = [ - "cipher 0.2.5", + "cipher", "opaque-debug", ] @@ -99,7 +78,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" dependencies = [ - "cipher 0.2.5", + "cipher", "opaque-debug", ] @@ -132,15 +111,17 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-consensus" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629b62e38d471cc15fea534eb7283d2f8a4e8bdb1811bcc5d66dda6cfce6fae1" +checksum = "41ed961a48297c732a5d97ee321aa8bb5009ecadbcb077d8bec90cb54e651629" dependencies = [ "alloy-eips", - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-rlp", "alloy-serde", + "auto_impl", "c-kzg", + "derive_more", "serde", ] @@ -150,48 +131,61 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" dependencies = [ - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-rlp", "serde", ] [[package]] name = "alloy-eip7702" -version = "0.1.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" +checksum = "64ffc577390ce50234e02d841214b3dc0bea6aaaae8e04bbf3cb82e9a45da9eb" dependencies = [ - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-rlp", + "derive_more", "serde", ] [[package]] name = "alloy-eips" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" +checksum = "b69e06cf9c37be824b9d26d6d101114fdde6af0c87de2828b414c05c4b3daa71" dependencies = [ "alloy-eip2930", "alloy-eip7702", - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-rlp", "alloy-serde", "c-kzg", - "derive_more 1.0.0", + "derive_more", "once_cell", "serde", "sha2 0.10.8", ] +[[package]] +name = "alloy-json-abi" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31a0f0d51db8a1a30a4d98a9f90e090a94c8f44cb4d9eafc7e03aa6d00aae984" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + [[package]] name = "alloy-json-rpc" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c717b5298fad078cd3a418335b266eba91b511383ca9bd497f742d5975d5ab" +checksum = "af5979e0d5a7bf9c7eb79749121e8256e59021af611322aee56e77e20776b4b3" dependencies = [ - "alloy-primitives 0.8.8", - "alloy-sol-types 0.8.8", + "alloy-primitives", + "alloy-sol-types", "serde", "serde_json", "thiserror", @@ -200,19 +194,19 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3705ce7d8602132bcf5ac7a1dd293a42adc2f183abf5907c30ac535ceca049" +checksum = "204237129086ce5dc17a58025e93739b01b45313841f98fa339eb1d780511e57" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-json-rpc", "alloy-network-primitives", - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", "alloy-signer", - "alloy-sol-types 0.8.8", + "alloy-sol-types", "async-trait", "auto_impl", "futures-utils-wasm", @@ -221,49 +215,28 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94ad40869867ed2d9cd3842b1e800889e5b49e6b92da346e93862b4a741bedf3" +checksum = "514f70ee2a953db21631cd817b13a1571474ec77ddc03d47616d5e8203489fde" dependencies = [ + "alloy-consensus", "alloy-eips", - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-serde", "serde", ] [[package]] name = "alloy-primitives" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" -dependencies = [ - "alloy-rlp", - "bytes 1.7.2", - "cfg-if", - "const-hex", - "derive_more 0.99.18", - "hex-literal", - "itoa", - "k256", - "keccak-asm", - "proptest", - "rand 0.8.5", - "ruint", - "serde", - "tiny-keccak", -] - -[[package]] -name = "alloy-primitives" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f35429a652765189c1c5092870d8360ee7b7769b09b06d89ebaefd34676446" +checksum = "8edae627382349b56cd6a7a2106f4fd69b243a9233e560c55c2e03cabb7e1d3c" dependencies = [ "alloy-rlp", - "bytes 1.7.2", + "bytes 1.8.0", "cfg-if", "const-hex", - "derive_more 1.0.0", + "derive_more", "foldhash", "hashbrown 0.15.0", "hex-literal", @@ -283,42 +256,40 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26154390b1d205a4a7ac7352aa2eb4f81f391399d4e2f546fb81a2f8bb383f62" +checksum = "da0822426598f95e45dd1ea32a738dac057529a709ee645fcc516ffa4cbde08f" dependencies = [ "alloy-rlp-derive", "arrayvec", - "bytes 1.7.2", + "bytes 1.8.0", ] [[package]] name = "alloy-rlp-derive" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" +checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] name = "alloy-rpc-types-eth" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83aa984386deda02482660aa31cb8ca1e63d533f1c31a52d7d181ac5ec68e9b8" +checksum = "00b034779a4850b4b03f5be5ea674a1cf7d746b2da762b34d1860ab45e48ca27" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-network-primitives", - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-rlp", "alloy-serde", - "alloy-sol-types 0.8.8", - "cfg-if", - "derive_more 1.0.0", - "hashbrown 0.14.5", + "alloy-sol-types", + "derive_more", "itertools 0.13.0", "serde", "serde_json", @@ -326,22 +297,22 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "731f75ec5d383107fd745d781619bd9cedf145836c51ecb991623d41278e71fa" +checksum = "028e72eaa9703e4882344983cfe7636ce06d8cce104a78ea62fd19b46659efc4" dependencies = [ - "alloy-primitives 0.8.8", + "alloy-primitives", "serde", "serde_json", ] [[package]] name = "alloy-signer" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307324cca94354cd654d6713629f0383ec037e1ff9e3e3d547212471209860c0" +checksum = "592c185d7100258c041afac51877660c7bf6213447999787197db4842f0e938e" dependencies = [ - "alloy-primitives 0.8.8", + "alloy-primitives", "async-trait", "auto_impl", "elliptic-curve", @@ -351,13 +322,13 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "0.3.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fabe917ab1778e760b4701628d1cae8e028ee9d52ac6307de4e1e9286ab6b5f" +checksum = "6614f02fc1d5b079b2a4a5320018317b506fd0a6d67c1fd5542a71201724986c" dependencies = [ "alloy-consensus", "alloy-network", - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-signer", "async-trait", "k256", @@ -367,119 +338,72 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" -dependencies = [ - "alloy-sol-macro-expander 0.7.7", - "alloy-sol-macro-input 0.7.7", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "alloy-sol-macro" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2395336745358cc47207442127c47c63801a7065ecc0aa928da844f8bb5576" +checksum = "841eabaa4710f719fddbc24c95d386eae313f07e6da4babc25830ee37945be0c" dependencies = [ - "alloy-sol-macro-expander 0.8.8", - "alloy-sol-macro-input 0.8.8", + "alloy-sol-macro-expander", + "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", -] - -[[package]] -name = "alloy-sol-macro-expander" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" -dependencies = [ - "alloy-sol-macro-input 0.7.7", - "const-hex", - "heck", - "indexmap 2.6.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.79", - "syn-solidity 0.7.7", - "tiny-keccak", + "syn 2.0.86", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed5047c9a241df94327879c2b0729155b58b941eae7805a7ada2e19436e6b39" +checksum = "6672337f19d837b9f7073c45853aeb528ed9f7dd6a4154ce683e9e5cb7794014" dependencies = [ - "alloy-sol-macro-input 0.8.8", + "alloy-sol-macro-input", "const-hex", "heck", "indexmap 2.6.0", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", - "syn-solidity 0.8.8", + "syn 2.0.86", + "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" -dependencies = [ - "const-hex", - "dunce", - "heck", - "proc-macro2", - "quote", - "syn 2.0.79", - "syn-solidity 0.7.7", -] - -[[package]] -name = "alloy-sol-macro-input" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dee02a81f529c415082235129f0df8b8e60aa1601b9c9298ffe54d75f57210b" +checksum = "0dff37dd20bfb118b777c96eda83b2067f4226d2644c5cfa00187b3bc01770ba" dependencies = [ "const-hex", "dunce", "heck", "proc-macro2", "quote", - "syn 2.0.79", - "syn-solidity 0.8.8", + "syn 2.0.86", + "syn-solidity", ] [[package]] -name = "alloy-sol-types" -version = "0.7.7" +name = "alloy-sol-type-parser" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" +checksum = "5b853d42292dbb159671a3edae3b2750277ff130f32b726fe07dc2b17aa6f2b5" dependencies = [ - "alloy-primitives 0.7.7", - "alloy-sol-macro 0.7.7", - "const-hex", "serde", + "winnow 0.6.20", ] [[package]] name = "alloy-sol-types" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2841af22d99e2c0f82a78fe107b6481be3dd20b89bfb067290092794734343a" +checksum = "aa828bb1b9a6dc52208fbb18084fb9ce2c30facc2bfda6a5d922349b4990354f" dependencies = [ - "alloy-primitives 0.8.8", - "alloy-sol-macro 0.8.8", + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-macro", "const-hex", + "serde", ] [[package]] @@ -514,9 +438,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -529,43 +453,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" dependencies = [ "backtrace", ] @@ -748,7 +672,7 @@ dependencies = [ "async-task", "concurrent-queue", "fastrand 2.1.1", - "futures-lite 2.3.0", + "futures-lite 2.4.0", "slab", ] @@ -763,7 +687,7 @@ dependencies = [ "async-io", "async-lock", "blocking", - "futures-lite 2.3.0", + "futures-lite 2.4.0", "once_cell", ] @@ -777,7 +701,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.3.0", + "futures-lite 2.4.0", "parking", "polling", "rustix", @@ -812,8 +736,8 @@ dependencies = [ "futures-channel", "futures-core", "futures-io", - "futures-lite 2.3.0", - "gloo-timers 0.3.0", + "futures-lite 2.4.0", + "gloo-timers", "kv-log-macro", "log", "memchr", @@ -843,7 +767,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -873,7 +797,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -889,17 +813,6 @@ dependencies = [ "tungstenite", ] -[[package]] -name = "async_io_stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" -dependencies = [ - "futures", - "pharos", - "rustc_version 0.4.1", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -914,7 +827,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -931,12 +844,12 @@ checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" dependencies = [ "async-trait", "axum-core", - "bytes 1.7.2", + "bytes 1.8.0", "futures-util", "http 1.1.0", - "http-body 1.0.1", + "http-body", "http-body-util", - "hyper 1.5.0", + "hyper", "hyper-util", "itoa", "matchit", @@ -964,10 +877,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", - "bytes 1.7.2", + "bytes 1.8.0", "futures-util", "http 1.1.0", - "http-body 1.0.1", + "http-body", "http-body-util", "mime", "pin-project-lite", @@ -1032,12 +945,6 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -1050,12 +957,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - [[package]] name = "bincode" version = "1.3.3" @@ -1071,7 +972,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cexpr", "clang-sys", "itertools 0.13.0", @@ -1082,7 +983,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -1100,12 +1001,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.6.0" @@ -1144,19 +1039,6 @@ dependencies = [ "constant_time_eq", ] -[[package]] -name = "blake3" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", -] - [[package]] name = "block-buffer" version = "0.9.0" @@ -1184,7 +1066,7 @@ dependencies = [ "async-channel 2.3.1", "async-task", "futures-io", - "futures-lite 2.3.0", + "futures-lite 2.4.0", "piper", ] @@ -1213,16 +1095,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "sha2 0.10.8", - "tinyvec", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -1252,7 +1124,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -1269,9 +1141,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" dependencies = [ "serde", ] @@ -1331,9 +1203,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.30" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc", @@ -1409,16 +1281,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -1461,7 +1323,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -1470,63 +1332,11 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" -[[package]] -name = "coins-bip32" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" -dependencies = [ - "bs58", - "coins-core", - "digest 0.10.7", - "hmac 0.12.1", - "k256", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "coins-bip39" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" -dependencies = [ - "bitvec", - "coins-bip32", - "hmac 0.12.1", - "once_cell", - "pbkdf2 0.12.2", - "rand 0.8.5", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "coins-core" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" -dependencies = [ - "base64 0.21.7", - "bech32", - "bs58", - "digest 0.10.7", - "generic-array 0.14.7", - "hex", - "ripemd", - "serde", - "serde_derive", - "sha2 0.10.8", - "sha3", - "thiserror", -] - [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "concurrent-queue" @@ -1581,12 +1391,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "cookie" version = "0.14.4" @@ -1761,16 +1565,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" dependencies = [ - "cipher 0.2.5", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] @@ -1837,7 +1632,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -1983,19 +1778,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version 0.4.1", - "syn 2.0.79", -] - [[package]] name = "derive_more" version = "1.0.0" @@ -2013,7 +1795,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", "unicode-xid", ] @@ -2157,31 +1939,13 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] -[[package]] -name = "enr" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" -dependencies = [ - "base64 0.21.7", - "bytes 1.7.2", - "hex", - "k256", - "log", - "rand 0.8.5", - "rlp", - "serde", - "sha3", - "zeroize", -] - [[package]] name = "enum-map" version = "2.7.3" @@ -2200,7 +1964,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -2220,284 +1984,20 @@ dependencies = [ ] [[package]] -name = "eth-keystore" -version = "0.5.0" +name = "event-listener" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" -dependencies = [ - "aes 0.8.4", - "ctr 0.9.2", - "digest 0.10.7", - "hex", - "hmac 0.12.1", - "pbkdf2 0.11.0", - "rand 0.8.5", - "scrypt", - "serde", - "serde_json", - "sha2 0.10.8", - "sha3", - "thiserror", - "uuid", -] +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] -name = "ethabi" -version = "18.0.0" +name = "event-listener" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "primitive-types", - "scale-info", - "uint", -] - -[[package]] -name = "ethers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" -dependencies = [ - "ethers-addressbook", - "ethers-contract", - "ethers-core", - "ethers-middleware", - "ethers-providers", - "ethers-signers", -] - -[[package]] -name = "ethers-addressbook" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" -dependencies = [ - "ethers-core", - "once_cell", - "serde", - "serde_json", -] - -[[package]] -name = "ethers-contract" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" -dependencies = [ - "const-hex", - "ethers-contract-abigen", - "ethers-contract-derive", - "ethers-core", - "ethers-providers", - "futures-util", - "once_cell", - "pin-project", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "ethers-contract-abigen" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" -dependencies = [ - "Inflector", - "const-hex", - "dunce", - "ethers-core", - "eyre", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "serde", - "serde_json", - "syn 2.0.79", - "toml", - "walkdir", -] - -[[package]] -name = "ethers-contract-derive" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" -dependencies = [ - "Inflector", - "const-hex", - "ethers-contract-abigen", - "ethers-core", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.79", -] - -[[package]] -name = "ethers-core" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" -dependencies = [ - "arrayvec", - "bytes 1.7.2", - "cargo_metadata", - "chrono", - "const-hex", - "elliptic-curve", - "ethabi", - "generic-array 0.14.7", - "k256", - "num_enum 0.7.3", - "once_cell", - "open-fastrlp", - "rand 0.8.5", - "rlp", - "serde", - "serde_json", - "strum", - "syn 2.0.79", - "tempfile", - "thiserror", - "tiny-keccak", - "unicode-xid", -] - -[[package]] -name = "ethers-middleware" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" -dependencies = [ - "async-trait", - "auto_impl", - "ethers-contract", - "ethers-core", - "ethers-providers", - "ethers-signers", - "futures-channel", - "futures-locks", - "futures-util", - "instant", - "reqwest 0.11.27", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "url", -] - -[[package]] -name = "ethers-providers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" -dependencies = [ - "async-trait", - "auto_impl", - "base64 0.21.7", - "bytes 1.7.2", - "const-hex", - "enr", - "ethers-core", - "futures-core", - "futures-timer", - "futures-util", - "hashers", - "http 0.2.12", - "instant", - "jsonwebtoken", - "once_cell", - "pin-project", - "reqwest 0.11.27", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "ws_stream_wasm", -] - -[[package]] -name = "ethers-signers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" -dependencies = [ - "async-trait", - "coins-bip32", - "coins-bip39", - "const-hex", - "elliptic-curve", - "eth-keystore", - "ethers-core", - "rand 0.8.5", - "sha2 0.10.8", - "thiserror", - "tracing", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "5.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", + "concurrent-queue", + "parking", + "pin-project-lite", ] [[package]] @@ -2543,7 +2043,7 @@ checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" dependencies = [ "arrayvec", "auto_impl", - "bytes 1.7.2", + "bytes 1.8.0", ] [[package]] @@ -2728,9 +2228,9 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +checksum = "3f1fa2f9765705486b33fd2acf1577f8ec449c2ba1f318ae5447697b7c08d210" dependencies = [ "fastrand 2.1.1", "futures-core", @@ -2739,16 +2239,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "futures-locks" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" -dependencies = [ - "futures-channel", - "futures-task", -] - [[package]] name = "futures-macro" version = "0.3.31" @@ -2757,7 +2247,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -2772,16 +2262,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers 0.2.6", - "send_wrapper 0.4.0", -] - [[package]] name = "futures-util" version = "0.3.31" @@ -2806,15 +2286,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "gcd" version = "2.3.0" @@ -2886,7 +2357,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", "libgit2-sys", "log", @@ -2899,18 +2370,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "gloo-timers" version = "0.3.0" @@ -2967,25 +2426,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes 1.7.2", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.6.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "h2" version = "0.4.6" @@ -2993,7 +2433,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", - "bytes 1.7.2", + "bytes 1.8.0", "fnv", "futures-core", "futures-sink", @@ -3067,15 +2507,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hashers" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" -dependencies = [ - "fxhash", -] - [[package]] name = "heck" version = "0.5.0" @@ -3144,7 +2575,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "fnv", "itoa", ] @@ -3155,29 +2586,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "fnv", "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes 1.7.2", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "http 1.1.0", ] @@ -3187,10 +2607,10 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "futures-util", "http 1.1.0", - "http-body 1.0.1", + "http-body", "pin-project-lite", ] @@ -3242,42 +2662,18 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.14.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" -dependencies = [ - "bytes 1.7.2", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "futures-channel", "futures-util", - "h2 0.4.6", + "h2", "http 1.1.0", - "http-body 1.0.1", + "http-body", "httparse", "httpdate", "itoa", @@ -3295,9 +2691,9 @@ checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.5.0", + "hyper", "hyper-util", - "rustls 0.23.15", + "rustls 0.23.16", "rustls-pki-types", "tokio", "tokio-rustls", @@ -3311,35 +2707,22 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "hyper 1.5.0", + "hyper", "hyper-util", "pin-project-lite", "tokio", "tower-service", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes 1.7.2", - "hyper 0.14.31", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "hyper-tls" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "http-body-util", - "hyper 1.5.0", + "hyper", "hyper-util", "native-tls", "tokio", @@ -3349,16 +2732,16 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "futures-channel", "futures-util", "http 1.1.0", - "http-body 1.0.1", - "hyper 1.5.0", + "http-body", + "hyper", "pin-project-lite", "socket2", "tokio", @@ -3414,24 +2797,6 @@ dependencies = [ "parity-scale-codec", ] -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", -] - [[package]] name = "impl-trait-for-tuples" version = "0.2.2" @@ -3489,15 +2854,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array 0.14.7", -] - [[package]] name = "instant" version = "0.1.13" @@ -3604,20 +2960,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonwebtoken" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" -dependencies = [ - "base64 0.21.7", - "pem", - "ring 0.16.20", - "serde", - "serde_json", - "simple_asn1", -] - [[package]] name = "jubjub" version = "0.9.0" @@ -3685,9 +3027,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libgit2-sys" @@ -3713,9 +3055,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libnghttp2-sys" @@ -3733,7 +3075,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", ] @@ -3882,7 +3224,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -4047,16 +3389,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ - "num_enum_derive 0.5.11", -] - -[[package]] -name = "num_enum" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" -dependencies = [ - "num_enum_derive 0.7.3", + "num_enum_derive", ] [[package]] @@ -4071,18 +3404,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "num_enum_derive" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" -dependencies = [ - "proc-macro-crate 3.2.0", - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "num_threads" version = "0.1.7" @@ -4123,40 +3444,15 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" name = "opaque-debug" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "open-fastrlp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes 1.7.2", - "ethereum-types", - "open-fastrlp-derive", -] - -[[package]] -name = "open-fastrlp-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" -dependencies = [ - "bytes 1.7.2", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.67" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b8cefcf97f41316955f9294cd61f639bdcfa9f2f230faac6cb896aa8ab64704" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "foreign-types", "libc", @@ -4173,7 +3469,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -4229,15 +3525,6 @@ dependencies = [ "serde", ] -[[package]] -name = "p3-blake3" -version = "0.1.0" -source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" -dependencies = [ - "blake3", - "p3-symmetric", -] - [[package]] name = "p3-bn254-fr" version = "0.1.0" @@ -4545,34 +3832,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest 0.10.7", - "hmac 0.12.1", -] - -[[package]] -name = "pem" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" -dependencies = [ - "base64 0.13.1", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -4600,41 +3859,31 @@ dependencies = [ "indexmap 2.6.0", ] -[[package]] -name = "pharos" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" -dependencies = [ - "futures", - "rustc_version 0.4.1", -] - [[package]] name = "pin-project" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -4752,12 +4001,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -4782,9 +4031,6 @@ checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", "uint", ] @@ -4807,30 +4053,6 @@ dependencies = [ "toml_edit 0.22.22", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -4850,7 +4072,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -4861,9 +4083,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -4876,7 +4098,7 @@ checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.6.0", + "bitflags", "lazy_static", "num-traits", "rand 0.8.5", @@ -4894,7 +4116,7 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "prost-derive", ] @@ -4904,7 +4126,7 @@ version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c1318b19085f08681016926435853bbf7858f9c082d0999b80550ff5d9abe15" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "heck", "itertools 0.13.0", "log", @@ -4915,7 +4137,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.79", + "syn 2.0.86", "tempfile", ] @@ -4929,7 +4151,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -4953,12 +4175,12 @@ version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash 2.0.0", - "rustls 0.23.15", + "rustls 0.23.16", "socket2", "thiserror", "tokio", @@ -4971,11 +4193,11 @@ version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "rand 0.8.5", "ring 0.17.8", "rustc-hash 2.0.0", - "rustls 0.23.15", + "rustls 0.23.16", "slab", "thiserror", "tinyvec", @@ -4984,10 +4206,11 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780" dependencies = [ + "cfg_aliases", "libc", "once_cell", "socket2", @@ -5126,7 +4349,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -5142,9 +4365,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -5186,62 +4409,22 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes 1.7.2", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.31", - "hyper-tls 0.5.0", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration 0.5.1", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "reqwest" -version = "0.12.8" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", - "bytes 1.7.2", + "bytes 1.8.0", "encoding_rs", "futures-core", "futures-util", - "h2 0.4.6", + "h2", "http 1.1.0", - "http-body 1.0.1", + "http-body", "http-body-util", - "hyper 1.5.0", + "hyper", "hyper-rustls", - "hyper-tls 0.6.0", + "hyper-tls", "hyper-util", "ipnet", "js-sys", @@ -5252,14 +4435,14 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.15", - "rustls-pemfile 2.2.0", + "rustls 0.23.16", + "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", - "system-configuration 0.6.1", + "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", @@ -5283,7 +4466,7 @@ dependencies = [ "anyhow", "async-trait", "http 1.1.0", - "reqwest 0.12.8", + "reqwest", "serde", "thiserror", "tower-service", @@ -5329,37 +4512,16 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.7", -] - [[package]] name = "rlp" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" dependencies = [ - "bytes 1.7.2", - "rlp-derive", + "bytes 1.8.0", "rustc-hex", ] -[[package]] -name = "rlp-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "rrs-succinct" version = "0.1.0" @@ -5367,7 +4529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3372685893a9f67d18e98e792d690017287fd17379a83d798d958e517d380fa9" dependencies = [ "downcast-rs", - "num_enum 0.5.11", + "num_enum", "paste", ] @@ -5392,7 +4554,7 @@ dependencies = [ "alloy-rlp", "ark-ff 0.3.0", "ark-ff 0.4.2", - "bytes 1.7.2", + "bytes 1.8.0", "fastrlp", "num-bigint 0.4.6", "num-traits", @@ -5466,11 +4628,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -5492,9 +4654,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.15" +version = "0.23.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" dependencies = [ "log", "once_cell", @@ -5512,21 +4674,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" dependencies = [ "openssl-probe", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "rustls-pki-types", "schannel", "security-framework", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -5577,15 +4730,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher 0.4.4", -] - [[package]] name = "same-file" version = "1.0.6" @@ -5597,33 +4741,33 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.3" +version = "2.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" dependencies = [ "cfg-if", - "derive_more 0.99.18", + "derive_more", "parity-scale-codec", "scale-info-derive", ] [[package]] name = "scale-info-derive" -version = "2.11.3" +version = "2.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.86", ] [[package]] name = "scc" -version = "2.2.2" +version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c1f7fc6deb21665a9060dfc7d271be784669295a31babdcd4dd2c79ae8cbfb" +checksum = "d8d25269dd3a12467afe2e510f69fb0b46b698e5afb296b59f2145259deaf8e8" dependencies = [ "sdd", ] @@ -5660,19 +4804,7 @@ checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", -] - -[[package]] -name = "scrypt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" -dependencies = [ - "hmac 0.12.1", - "pbkdf2 0.11.0", - "salsa20", - "sha2 0.10.8", + "syn 2.0.86", ] [[package]] @@ -5711,7 +4843,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -5770,43 +4902,31 @@ dependencies = [ "pest", ] -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - [[package]] name = "serde" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -5835,15 +4955,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -5900,7 +5011,7 @@ checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -6007,18 +5118,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint 0.4.6", - "num-traits", - "thiserror", - "time 0.3.36", -] - [[package]] name = "size" version = "0.4.1" @@ -6123,7 +5222,7 @@ dependencies = [ "prettytable-rs", "rand 0.8.5", "regex", - "reqwest 0.12.8", + "reqwest", "rustc-demangle", "serde_json", "sp1-build", @@ -6187,7 +5286,6 @@ dependencies = [ "num_cpus", "p3-air", "p3-baby-bear", - "p3-blake3", "p3-challenger", "p3-field", "p3-keccak-air", @@ -6215,7 +5313,6 @@ dependencies = [ "tracing-forest", "tracing-subscriber", "typenum", - "vec_map", "web-time", ] @@ -6273,9 +5370,7 @@ dependencies = [ "anyhow", "bincode", "clap", - "csv", - "p3-baby-bear", - "reqwest 0.12.8", + "reqwest", "serde", "serde_json", "slack-rust-rs", @@ -6303,9 +5398,9 @@ dependencies = [ [[package]] name = "sp1-lib" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c372b16988e765af85ccf958b18b26d89c05886f2592d313a285415dcc769cb" +checksum = "14deb700469a37ec075bcf88dac3815b026dd9c4b9cb175980826f1fbb2e4e80" dependencies = [ "bincode", "serde", @@ -6315,22 +5410,15 @@ dependencies = [ name = "sp1-perf" version = "3.0.0" dependencies = [ - "anyhow", "bincode", "clap", - "csv", "p3-baby-bear", - "reqwest 0.12.8", - "serde", - "serde_json", - "slack-rust-rs", "sp1-core-executor", "sp1-cuda", "sp1-prover", "sp1-sdk", "sp1-stark", "time 0.3.36", - "tokio", ] [[package]] @@ -6359,7 +5447,6 @@ dependencies = [ "dirs", "eyre", "itertools 0.13.0", - "lazy_static", "lru", "num-bigint 0.4.6", "p3-baby-bear", @@ -6369,8 +5456,6 @@ dependencies = [ "p3-field", "p3-matrix", "p3-symmetric", - "rayon", - "reqwest 0.11.27", "serde", "serde_json", "serial_test", @@ -6382,8 +5467,6 @@ dependencies = [ "sp1-recursion-core", "sp1-recursion-gnark-ffi", "sp1-stark", - "subtle-encoding", - "tempfile", "thiserror", "tracing", "tracing-subscriber", @@ -6530,17 +5613,16 @@ dependencies = [ name = "sp1-sdk" version = "3.0.0" dependencies = [ - "alloy-primitives 0.8.8", + "alloy-primitives", "alloy-signer", "alloy-signer-local", - "alloy-sol-types 0.7.7", + "alloy-sol-types", "anyhow", "async-trait", "backoff", "bincode", "cfg-if", "dirs", - "ethers", "futures", "hashbrown 0.14.5", "hex", @@ -6551,7 +5633,7 @@ dependencies = [ "p3-field", "p3-fri", "prost", - "reqwest 0.12.8", + "reqwest", "reqwest-middleware", "serde", "sp1-core-executor", @@ -6576,7 +5658,6 @@ name = "sp1-stark" version = "3.0.0" dependencies = [ "arrayref", - "getrandom 0.2.15", "hashbrown 0.14.5", "itertools 0.13.0", "num-traits", @@ -6602,7 +5683,6 @@ dependencies = [ "strum", "strum_macros", "sysinfo", - "thiserror", "tracing", ] @@ -6762,13 +5842,13 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] name = "substrate-bn" version = "0.6.0" -source = "git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2#a1974dba1f3b75c16b48a84037edc12b36bba1cf" +source = "git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2#201cc196da216656044e61fea7f68707b6896662" dependencies = [ "bytemuck", "byteorder", @@ -6778,7 +5858,7 @@ dependencies = [ "num-bigint 0.4.6", "rand 0.8.5", "rustc-hex", - "sp1-lib 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp1-lib 3.1.0", ] [[package]] @@ -6787,15 +5867,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - [[package]] name = "surf" version = "2.3.2" @@ -6832,9 +5903,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c" dependencies = [ "proc-macro2", "quote", @@ -6843,26 +5914,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" -dependencies = [ - "paste", - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "syn-solidity" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebfc1bfd06acc78f16d8fd3ef846bc222ee7002468d10a7dce8d703d6eab89a3" +checksum = "16320d4a2021ba1a32470b3759676114a918885e9800e68ad60f2c67969fba62" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -6895,36 +5954,15 @@ dependencies = [ "windows", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys 0.5.0", -] - [[package]] name = "system-configuration" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.6.0", + "bitflags", "core-foundation", - "system-configuration-sys 0.6.0", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", + "system-configuration-sys", ] [[package]] @@ -6986,22 +6024,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -7150,12 +6188,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", - "bytes 1.7.2", + "bytes 1.8.0", "libc", "mio", "parking_lot", @@ -7174,7 +6212,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -7193,7 +6231,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.15", + "rustls 0.23.16", "rustls-pki-types", "tokio", ] @@ -7215,33 +6253,18 @@ version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ - "bytes 1.7.2", + "bytes 1.8.0", "futures-core", "futures-sink", "pin-project-lite", "tokio", ] -[[package]] -name = "toml" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.22", -] - [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] [[package]] name = "toml_edit" @@ -7261,8 +6284,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.6.0", - "serde", - "serde_spanned", "toml_datetime", "winnow 0.6.20", ] @@ -7277,19 +6298,19 @@ dependencies = [ "async-trait", "axum", "base64 0.22.1", - "bytes 1.7.2", - "h2 0.4.6", + "bytes 1.8.0", + "h2", "http 1.1.0", - "http-body 1.0.1", + "http-body", "http-body-util", - "hyper 1.5.0", + "hyper", "hyper-timeout", "hyper-util", "percent-encoding", "pin-project", "prost", "rustls-native-certs", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "socket2", "tokio", "tokio-rustls", @@ -7368,7 +6389,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -7447,7 +6468,7 @@ checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" dependencies = [ "base64 0.13.1", "byteorder", - "bytes 1.7.2", + "bytes 1.8.0", "http 0.2.12", "httparse", "log", @@ -7478,9 +6499,9 @@ dependencies = [ "futures", "http 1.1.0", "http-body-util", - "hyper 1.5.0", + "hyper", "prost", - "reqwest 0.12.8", + "reqwest", "serde", "serde_json", "thiserror", @@ -7521,12 +6542,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bidi" @@ -7613,16 +6631,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom 0.2.15", - "serde", -] - [[package]] name = "valuable" version = "0.1.0" @@ -7631,9 +6639,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" [[package]] name = "vcpkg" @@ -7737,7 +6745,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", "wasm-bindgen-shared", ] @@ -7771,7 +6779,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7784,9 +6792,9 @@ checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "wasm-streams" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", @@ -8089,35 +7097,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - -[[package]] -name = "ws_stream_wasm" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" -dependencies = [ - "async_io_stream", - "futures", - "js-sys", - "log", - "pharos", - "rustc_version 0.4.1", - "send_wrapper 0.6.0", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "wyz" version = "0.5.1" @@ -8151,7 +7130,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] @@ -8171,7 +7150,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.86", ] [[package]] diff --git a/crates/core/machine/Cargo.toml b/crates/core/machine/Cargo.toml index 3b0b0f34f9..60ae3da008 100644 --- a/crates/core/machine/Cargo.toml +++ b/crates/core/machine/Cargo.toml @@ -19,7 +19,6 @@ p3-air = { workspace = true } p3-baby-bear = { workspace = true } p3-challenger = { workspace = true } p3-field = { workspace = true } -p3-blake3 = { workspace = true } p3-keccak-air = { workspace = true } p3-matrix = { workspace = true } p3-maybe-rayon = { workspace = true, features = ["parallel"] } @@ -54,7 +53,6 @@ static_assertions = "1.1.0" sp1-stark = { workspace = true } sp1-core-executor = { workspace = true } sp1-curves = { workspace = true } -vec_map = "0.8.2" [dev-dependencies] tiny-keccak = { version = "2.0.2", features = ["keccak"] } @@ -65,7 +63,6 @@ sp1-zkvm = { workspace = true } sp1-core-executor = { workspace = true, features = ["programs"] } [features] -neon = ["p3-blake3/neon"] programs = [] debug = [] bigint-rug = ["sp1-curves/bigint-rug"] diff --git a/crates/eval/Cargo.toml b/crates/eval/Cargo.toml index 6cb700a464..e986c88112 100644 --- a/crates/eval/Cargo.toml +++ b/crates/eval/Cargo.toml @@ -12,12 +12,10 @@ categories = { workspace = true } [dependencies] sp1-prover = { workspace = true } sp1-sdk = { workspace = true } -p3-baby-bear = { workspace = true } sp1-stark = { workspace = true } anyhow = "1.0.83" clap = { version = "4.5.9", features = ["derive"] } -csv = "1.3.0" serde = "1.0.204" bincode = "1.3.3" time = "0.3.26" diff --git a/crates/perf/Cargo.toml b/crates/perf/Cargo.toml index 4f36711353..93ae716949 100644 --- a/crates/perf/Cargo.toml +++ b/crates/perf/Cargo.toml @@ -17,16 +17,9 @@ p3-baby-bear = { workspace = true } sp1-stark = { workspace = true } sp1-cuda = { workspace = true } -anyhow = "1.0.83" clap = { version = "4.5.9", features = ["derive"] } -csv = "1.3.0" -serde = "1.0.204" bincode = "1.3.3" time = "0.3.26" -slack-rust = { package = "slack-rust-rs", version = "0.0.1" } -tokio = { version = "1.39.0", features = ["full"] } -reqwest = { version = "0.12.4", features = ["json"] } -serde_json = "1.0.104" [features] native-gnark = ["sp1-sdk/native-gnark"] diff --git a/crates/prover/Cargo.toml b/crates/prover/Cargo.toml index a4fc480c7f..2a57c7bfd3 100644 --- a/crates/prover/Cargo.toml +++ b/crates/prover/Cargo.toml @@ -27,7 +27,6 @@ p3-bn254-fr = { workspace = true } p3-commit = { workspace = true } bincode = "1.3.3" serde = { version = "1.0", features = ["derive", "rc"] } -rayon = "1.10.0" itertools = "0.13.0" tracing = "0.1.40" tracing-subscriber = "0.3.18" @@ -35,15 +34,11 @@ serde_json = "1.0.121" clap = { version = "4.5.9", features = ["derive", "env"] } anyhow = "1.0.83" dirs = "5.0.1" -tempfile = "3.10.1" -subtle-encoding = "0.5.1" serial_test = "3.1.1" num-bigint = "0.4.6" thiserror = "1.0.63" lru = "0.12.4" eyre = "0.6.12" -reqwest = { version = "0.11", features = ["blocking"] } -lazy_static = "1.5.0" [[bin]] name = "build_plonk_bn254" @@ -66,7 +61,6 @@ name = "e2e" path = "scripts/e2e.rs" [features] -neon = ["sp1-core-machine/neon"] native-gnark = ["sp1-recursion-gnark-ffi/native"] export-tests = [] debug = ["sp1-core-machine/debug"] diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml index ffedbe26da..9d3b66d6d8 100644 --- a/crates/sdk/Cargo.toml +++ b/crates/sdk/Cargo.toml @@ -15,7 +15,7 @@ serde = { version = "1.0.204", features = ["derive"] } twirp = { package = "twirp-rs", version = "0.13.0-succinct", optional = true } async-trait = "0.1.81" reqwest-middleware = { version = "0.3.2", optional = true } -reqwest = { version = "0.12.4", features = [ +reqwest = { version = "0.12.4", default-features = false, features = [ "rustls-tls", "trust-dns", "stream", @@ -34,11 +34,9 @@ indicatif = "0.17.8" tracing = "0.1.40" hex = "0.4.3" log = "0.4.22" -alloy-sol-types = { version = "0.7.7", optional = true } dirs = "5.0.1" tempfile = "3.10.1" cfg-if = "1.0" -ethers = { version = "2", default-features = false, optional = true } strum = "0.26.3" strum_macros = "0.26.4" thiserror = "1.0.63" @@ -48,14 +46,14 @@ sp1-stark = { workspace = true } sp1-primitives = { workspace = true } itertools = "0.13.0" tonic = { version = "0.12", features = ["tls", "tls-roots"], optional = true } -alloy-signer = { version = "0.3.6", optional = true } -alloy-signer-local = { version = "0.3.6", optional = true } -alloy-primitives = { version = "0.8.7", optional = true } +alloy-sol-types = { version = "0.8", optional = true } +alloy-signer = { version = "0.5", optional = true } +alloy-signer-local = { version = "0.5", optional = true } +alloy-primitives = { version = "0.8", optional = true } backoff = { version = "0.4", features = ["tokio"], optional = true } [features] default = ["network"] -neon = ["sp1-core-machine/neon"] native-gnark = ["sp1-prover/native-gnark"] # TODO: Once alloy has a 1.* release, we can likely remove this feature flag, as there will be less # dependency resolution issues. @@ -63,7 +61,8 @@ network = [ "dep:prost", "dep:alloy-sol-types", "dep:tokio", - "dep:ethers", + "dep:alloy-signer", + "dep:alloy-signer-local", "dep:reqwest", "dep:twirp", "dep:reqwest-middleware", @@ -75,7 +74,7 @@ network-v2 = [ "dep:alloy-signer-local", "dep:alloy-primitives", "dep:tokio", - "dep:ethers", + "dep:alloy-signer", "dep:reqwest", "dep:twirp", "dep:reqwest-middleware", diff --git a/crates/sdk/src/network/auth.rs b/crates/sdk/src/network/auth.rs index 4057e6d836..7786cc4d36 100644 --- a/crates/sdk/src/network/auth.rs +++ b/crates/sdk/src/network/auth.rs @@ -1,11 +1,10 @@ use std::{borrow::Cow, str::FromStr}; +use alloy_signer::SignerSync; +use alloy_signer_local::PrivateKeySigner; + use alloy_sol_types::{sol, Eip712Domain, SolStruct}; use anyhow::Result; -use ethers::{ - signers::{LocalWallet, Signer}, - types::H256, -}; use crate::network::proto::network::UnclaimReason; @@ -54,12 +53,12 @@ sol! { /// https://eips.ethereum.org/EIPS/eip-712 pub struct NetworkAuth { // Holds a secp256k1 private key. - wallet: LocalWallet, + wallet: PrivateKeySigner, } impl NetworkAuth { pub fn new(private_key: &str) -> Self { - let wallet = LocalWallet::from_str(private_key).unwrap(); + let wallet = PrivateKeySigner::from_str(private_key).unwrap(); Self { wallet } } @@ -74,15 +73,15 @@ impl NetworkAuth { /// Gets the address of the auth's account, derived from the secp256k1 private key. pub fn get_address(&self) -> [u8; 20] { - self.wallet.address().0 + self.wallet.address().into() } // Generic function to sign a message based on the SolStruct. async fn sign_message(&self, type_struct: T) -> Result> { let domain_separator = Self::get_domain_separator(); let message_hash = type_struct.eip712_signing_hash(&domain_separator); - let signature = self.wallet.sign_hash(H256(message_hash.0))?; - Ok(signature.to_vec()) + let signature = self.wallet.sign_hash_sync(&message_hash)?; + Ok(signature.as_bytes().to_vec()) } /// Signs a message to to request to create a proof. diff --git a/crates/stark/Cargo.toml b/crates/stark/Cargo.toml index 6865e1f7d2..548dc57bbe 100644 --- a/crates/stark/Cargo.toml +++ b/crates/stark/Cargo.toml @@ -39,10 +39,8 @@ rayon-scan = "0.1.1" arrayref = "0.3.8" strum = "0.26.3" strum_macros = "0.26.4" -getrandom = { version = "0.2.15", features = ["custom"] } sysinfo = "0.30.13" num-traits = "0.2.19" -thiserror = "1.0.64" [dev-dependencies] sp1-zkvm = { workspace = true } diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 6e0fdb5471..663d53235f 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -2,16 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "addchain" version = "0.2.0" @@ -38,17 +28,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - [[package]] name = "aggregation-program" version = "1.1.0" @@ -95,11 +74,11 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "alloy-chains" -version = "0.1.42" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca4a1469a3e572e9ba362920ff145f5d0a00a3e71a64ddcb4a3659cf64c76a7" +checksum = "836cf02383d9ebb35502d379bcd1ae803155094077eaab9c29131d888cd5fa3e" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "num_enum 0.7.3", "serde", @@ -112,21 +91,37 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "629b62e38d471cc15fea534eb7283d2f8a4e8bdb1811bcc5d66dda6cfce6fae1" dependencies = [ - "alloy-eips", - "alloy-primitives 0.8.9", + "alloy-eips 0.3.6", + "alloy-primitives 0.8.10", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.3.6", "c-kzg", "serde", ] +[[package]] +name = "alloy-consensus" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed961a48297c732a5d97ee321aa8bb5009ecadbcb077d8bec90cb54e651629" +dependencies = [ + "alloy-eips 0.5.4", + "alloy-primitives 0.8.10", + "alloy-rlp", + "alloy-serde 0.5.4", + "auto_impl", + "c-kzg", + "derive_more 1.0.0", + "serde", +] + [[package]] name = "alloy-eip2930" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "serde", ] @@ -137,12 +132,24 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "k256", "serde", ] +[[package]] +name = "alloy-eip7702" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ffc577390ce50234e02d841214b3dc0bea6aaaae8e04bbf3cb82e9a45da9eb" +dependencies = [ + "alloy-primitives 0.8.10", + "alloy-rlp", + "derive_more 1.0.0", + "serde", +] + [[package]] name = "alloy-eips" version = "0.3.6" @@ -150,10 +157,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" dependencies = [ "alloy-eip2930", - "alloy-eip7702", - "alloy-primitives 0.8.9", + "alloy-eip7702 0.1.1", + "alloy-primitives 0.8.10", + "alloy-rlp", + "alloy-serde 0.3.6", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "alloy-eips" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69e06cf9c37be824b9d26d6d101114fdde6af0c87de2828b414c05c4b3daa71" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702 0.3.2", + "alloy-primitives 0.8.10", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.5.4", "c-kzg", "derive_more 1.0.0", "once_cell", @@ -167,62 +192,88 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a7a18afb0b318616b6b2b0e2e7ac5529d32a966c673b48091c9919e284e6aca" dependencies = [ - "alloy-primitives 0.8.9", - "alloy-serde", + "alloy-primitives 0.8.10", + "alloy-serde 0.3.6", "serde", ] [[package]] name = "alloy-json-abi" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b5671117c38b1c2306891f97ad3828d85487087f54ebe2c7591a055ea5bcea7" +checksum = "31a0f0d51db8a1a30a4d98a9f90e090a94c8f44cb4d9eafc7e03aa6d00aae984" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-sol-type-parser", "serde", "serde_json", ] +[[package]] +name = "alloy-json-rpc" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af5979e0d5a7bf9c7eb79749121e8256e59021af611322aee56e77e20776b4b3" +dependencies = [ + "alloy-primitives 0.8.10", + "alloy-sol-types", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "alloy-network" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "204237129086ce5dc17a58025e93739b01b45313841f98fa339eb1d780511e57" +dependencies = [ + "alloy-consensus 0.5.4", + "alloy-eips 0.5.4", + "alloy-json-rpc", + "alloy-network-primitives 0.5.4", + "alloy-primitives 0.8.10", + "alloy-rpc-types-eth 0.5.4", + "alloy-serde 0.5.4", + "alloy-signer", + "alloy-sol-types", + "async-trait", + "auto_impl", + "futures-utils-wasm", + "thiserror", +] + [[package]] name = "alloy-network-primitives" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94ad40869867ed2d9cd3842b1e800889e5b49e6b92da346e93862b4a741bedf3" dependencies = [ - "alloy-eips", - "alloy-primitives 0.8.9", - "alloy-serde", + "alloy-eips 0.3.6", + "alloy-primitives 0.8.10", + "alloy-serde 0.3.6", "serde", ] [[package]] -name = "alloy-primitives" -version = "0.6.4" +name = "alloy-network-primitives" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "600d34d8de81e23b6d909c094e23b3d357e01ca36b78a8c5424c501eedbe86f0" +checksum = "514f70ee2a953db21631cd817b13a1571474ec77ddc03d47616d5e8203489fde" dependencies = [ - "alloy-rlp", - "bytes", - "cfg-if", - "const-hex", - "derive_more 0.99.18", - "hex-literal", - "itoa", - "k256", - "keccak-asm", - "proptest", - "rand 0.8.5", - "ruint", + "alloy-consensus 0.5.4", + "alloy-eips 0.5.4", + "alloy-primitives 0.8.10", + "alloy-serde 0.5.4", "serde", - "tiny-keccak", ] [[package]] name = "alloy-primitives" -version = "0.7.7" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb3ead547f4532bc8af961649942f0b9c16ee9226e26caa3f38420651cc0bf4" +checksum = "600d34d8de81e23b6d909c094e23b3d357e01ca36b78a8c5424c501eedbe86f0" dependencies = [ "alloy-rlp", "bytes", @@ -242,9 +293,9 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71738eb20c42c5fb149571e76536a0f309d142f3957c28791662b96baf77a3d" +checksum = "8edae627382349b56cd6a7a2106f4fd69b243a9233e560c55c2e03cabb7e1d3c" dependencies = [ "alloy-rlp", "bytes", @@ -253,7 +304,7 @@ dependencies = [ "derive_more 1.0.0", "foldhash", "getrandom", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "hex-literal", "indexmap 2.6.0", "itoa", @@ -288,7 +339,7 @@ checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -297,8 +348,8 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64333d639f2a0cf73491813c629a405744e16343a4bc5640931be707c345ecc5" dependencies = [ - "alloy-rpc-types-eth", - "alloy-serde", + "alloy-rpc-types-eth 0.3.6", + "alloy-serde 0.3.6", "serde", ] @@ -308,13 +359,13 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83aa984386deda02482660aa31cb8ca1e63d533f1c31a52d7d181ac5ec68e9b8" dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-network-primitives", - "alloy-primitives 0.8.9", + "alloy-consensus 0.3.6", + "alloy-eips 0.3.6", + "alloy-network-primitives 0.3.6", + "alloy-primitives 0.8.10", "alloy-rlp", - "alloy-serde", - "alloy-sol-types 0.8.9", + "alloy-serde 0.3.6", + "alloy-sol-types", "cfg-if", "derive_more 1.0.0", "hashbrown 0.14.5", @@ -323,116 +374,129 @@ dependencies = [ "serde_json", ] +[[package]] +name = "alloy-rpc-types-eth" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b034779a4850b4b03f5be5ea674a1cf7d746b2da762b34d1860ab45e48ca27" +dependencies = [ + "alloy-consensus 0.5.4", + "alloy-eips 0.5.4", + "alloy-network-primitives 0.5.4", + "alloy-primitives 0.8.10", + "alloy-rlp", + "alloy-serde 0.5.4", + "alloy-sol-types", + "derive_more 1.0.0", + "itertools 0.13.0", + "serde", + "serde_json", +] + [[package]] name = "alloy-serde" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "731f75ec5d383107fd745d781619bd9cedf145836c51ecb991623d41278e71fa" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "serde", "serde_json", ] [[package]] -name = "alloy-sol-macro" -version = "0.7.7" +name = "alloy-serde" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b40397ddcdcc266f59f959770f601ce1280e699a91fc1862f29cef91707cd09" +checksum = "028e72eaa9703e4882344983cfe7636ce06d8cce104a78ea62fd19b46659efc4" dependencies = [ - "alloy-sol-macro-expander 0.7.7", - "alloy-sol-macro-input 0.7.7", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.85", + "alloy-primitives 0.8.10", + "serde", + "serde_json", ] [[package]] -name = "alloy-sol-macro" -version = "0.8.9" +name = "alloy-signer" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0900b83f4ee1f45c640ceee596afbc118051921b9438fdb5a3175c1a7e05f8b" +checksum = "592c185d7100258c041afac51877660c7bf6213447999787197db4842f0e938e" dependencies = [ - "alloy-sol-macro-expander 0.8.9", - "alloy-sol-macro-input 0.8.9", - "proc-macro-error2", - "proc-macro2", - "quote", - "syn 2.0.85", + "alloy-primitives 0.8.10", + "async-trait", + "auto_impl", + "elliptic-curve", + "k256", + "thiserror", ] [[package]] -name = "alloy-sol-macro-expander" -version = "0.7.7" +name = "alloy-signer-local" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "867a5469d61480fea08c7333ffeca52d5b621f5ca2e44f271b117ec1fc9a0525" +checksum = "6614f02fc1d5b079b2a4a5320018317b506fd0a6d67c1fd5542a71201724986c" dependencies = [ - "alloy-sol-macro-input 0.7.7", - "const-hex", - "heck", - "indexmap 2.6.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.85", - "syn-solidity 0.7.7", - "tiny-keccak", + "alloy-consensus 0.5.4", + "alloy-network", + "alloy-primitives 0.8.10", + "alloy-signer", + "async-trait", + "k256", + "rand 0.8.5", + "thiserror", ] [[package]] -name = "alloy-sol-macro-expander" -version = "0.8.9" +name = "alloy-sol-macro" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41b1e78dde06b5e12e6702fa8c1d30621bf07728ba75b801fb801c9c6a0ba10" +checksum = "841eabaa4710f719fddbc24c95d386eae313f07e6da4babc25830ee37945be0c" dependencies = [ - "alloy-sol-macro-input 0.8.9", - "const-hex", - "heck", - "indexmap 2.6.0", + "alloy-sol-macro-expander", + "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.85", - "syn-solidity 0.8.9", - "tiny-keccak", + "syn 2.0.87", ] [[package]] -name = "alloy-sol-macro-input" -version = "0.7.7" +name = "alloy-sol-macro-expander" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e482dc33a32b6fadbc0f599adea520bd3aaa585c141a80b404d0a3e3fa72528" +checksum = "6672337f19d837b9f7073c45853aeb528ed9f7dd6a4154ce683e9e5cb7794014" dependencies = [ + "alloy-sol-macro-input", "const-hex", - "dunce", "heck", + "indexmap 2.6.0", + "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.85", - "syn-solidity 0.7.7", + "syn 2.0.87", + "syn-solidity", + "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91dc311a561a306664393407b88d3e53ae58581624128afd8a15faa5de3627dc" +checksum = "0dff37dd20bfb118b777c96eda83b2067f4226d2644c5cfa00187b3bc01770ba" dependencies = [ "const-hex", "dunce", "heck", "proc-macro2", "quote", - "syn 2.0.85", - "syn-solidity 0.8.9", + "syn 2.0.87", + "syn-solidity", ] [[package]] name = "alloy-sol-type-parser" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d1fbee9e698f3ba176b6e7a145f4aefe6d2b746b611e8bb246fe11a0e9f6c4" +checksum = "5b853d42292dbb159671a3edae3b2750277ff130f32b726fe07dc2b17aa6f2b5" dependencies = [ "serde", "winnow 0.6.20", @@ -440,25 +504,13 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91ca40fa20793ae9c3841b83e74569d1cc9af29a2f5237314fd3452d51e38c7" -dependencies = [ - "alloy-primitives 0.7.7", - "alloy-sol-macro 0.7.7", - "const-hex", - "serde", -] - -[[package]] -name = "alloy-sol-types" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086f41bc6ebcd8cb15f38ba20e47be38dd03692149681ce8061c35d960dbf850" +checksum = "aa828bb1b9a6dc52208fbb18084fb9ce2c30facc2bfda6a5d922349b4990354f" dependencies = [ "alloy-json-abi", - "alloy-primitives 0.8.9", - "alloy-sol-macro 0.8.9", + "alloy-primitives 0.8.10", + "alloy-sol-macro", "const-hex", "serde", ] @@ -469,7 +521,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a46c9c4fdccda7982e7928904bd85fe235a0404ee3d7e197fff13d61eac8b4f" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "derive_more 1.0.0", "hashbrown 0.14.5", @@ -505,9 +557,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -520,9 +572,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -554,9 +606,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "ark-ff" @@ -708,26 +760,9 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", -] - -[[package]] -name = "async_io_stream" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" -dependencies = [ - "futures", - "pharos", - "rustc_version 0.4.1", + "syn 2.0.87", ] -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "aurora-engine-modexp" version = "1.1.0" @@ -746,7 +781,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -765,10 +800,10 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", - "hyper 1.5.0", + "hyper", "hyper-util", "itoa", "matchit", @@ -798,8 +833,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", "mime", "pin-project-lite", @@ -832,12 +867,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.7" @@ -856,12 +885,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - [[package]] name = "bincode" version = "1.3.3" @@ -877,7 +900,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cexpr", "clang-sys", "itertools 0.13.0", @@ -888,7 +911,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -906,12 +929,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.6.0" @@ -954,19 +971,6 @@ dependencies = [ "constant_time_eq", ] -[[package]] -name = "blake3" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" -dependencies = [ - "arrayref", - "arrayvec 0.7.6", - "cc", - "cfg-if", - "constant_time_eq", -] - [[package]] name = "block-buffer" version = "0.9.0" @@ -1020,14 +1024,14 @@ dependencies = [ [[package]] name = "bls12_381" version = "0.8.0" -source = "git+https://github.com/sp1-patches/bls12_381?branch=patch-v0.8.0#12f049691dc9165ccb1a0930327d2316976450a3" +source = "git+https://github.com/sp1-patches/bls12_381?tag=bls12_381-v0.8.0-patch-v1#444e109287eb3adc581425e160ed6041622dda35" dependencies = [ "cfg-if", "ff 0.13.0", "group 0.13.0", "pairing 0.23.0", "rand_core 0.6.4", - "sp1-lib 1.2.0", + "sp1-lib 3.1.0", "subtle", ] @@ -1049,7 +1053,7 @@ version = "1.1.0" dependencies = [ "rand 0.8.5", "sp1-zkvm", - "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?rev=43d854d45b5727b1ff2b9f346d728e785bb8395c)", + "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v1)", ] [[package]] @@ -1060,16 +1064,6 @@ dependencies = [ "sp1-sdk", ] -[[package]] -name = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "sha2 0.10.8", - "tinyvec", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -1099,7 +1093,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1166,9 +1160,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.31" +version = "1.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" dependencies = [ "jobserver", "libc", @@ -1237,16 +1231,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "clang-sys" version = "1.8.1" @@ -1289,7 +1273,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1298,58 +1282,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" -[[package]] -name = "coins-bip32" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" -dependencies = [ - "bs58", - "coins-core", - "digest 0.10.7", - "hmac", - "k256", - "serde", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "coins-bip39" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" -dependencies = [ - "bitvec", - "coins-bip32", - "hmac", - "once_cell", - "pbkdf2 0.12.2", - "rand 0.8.5", - "sha2 0.10.8", - "thiserror", -] - -[[package]] -name = "coins-core" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" -dependencies = [ - "base64 0.21.7", - "bech32", - "bs58", - "digest 0.10.7", - "generic-array 0.14.7", - "hex", - "ripemd", - "serde", - "serde_derive", - "sha2 0.10.8", - "sha3", - "thiserror", -] - [[package]] name = "colorchoice" version = "1.0.3" @@ -1415,16 +1347,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -1519,19 +1441,10 @@ dependencies = [ ] [[package]] -name = "ctr" -version = "0.9.2" +name = "ctrlc" +version = "3.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "ctrlc" -version = "3.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" dependencies = [ "nix", "windows-sys 0.59.0", @@ -1540,7 +1453,7 @@ dependencies = [ [[package]] name = "curve25519-dalek" version = "4.1.3" -source = "git+https://github.com/sp1-patches/curve25519-dalek?branch=patch-curve25519-v4.1.3#1d73fd95f1a76bee8f46643cf78bbccc1fb06ede" +source = "git+https://github.com/sp1-patches/curve25519-dalek?tag=curve25519_dalek-v4.1.3-patch-v1#dbdd0ffeea0ff767affc3f6765d1edbdaa9e2cb9" dependencies = [ "anyhow", "cfg-if", @@ -1549,7 +1462,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "rustc_version 0.4.1", - "sp1-lib 1.2.0", + "sp1-lib 3.1.0", "subtle", "zeroize", ] @@ -1557,24 +1470,39 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" version = "0.1.1" -source = "git+https://github.com/sp1-patches/curve25519-dalek?branch=patch-curve25519-v4.1.3#1d73fd95f1a76bee8f46643cf78bbccc1fb06ede" +source = "git+https://github.com/sp1-patches/curve25519-dalek?tag=curve25519_dalek-v4.1.3-patch-v1#dbdd0ffeea0ff767affc3f6765d1edbdaa9e2cb9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] name = "curve25519-dalek-ng" version = "4.1.1" -source = "git+https://github.com/sp1-patches/curve25519-dalek-ng?branch=patch-v4.1.1#8dd77b20f3e78965a0cc57070a04465b9d52c49e" +source = "git+https://github.com/sp1-patches/curve25519-dalek-ng?tag=curve25519_dalek_ng-v4.1.1-patch-v1#3fb3e7f6047ddeef0f0c9212f4604bd30d64bd28" dependencies = [ "anyhow", "byteorder", "cfg-if", "digest 0.9.0", "rand_core 0.6.4", - "sp1-lib 1.2.0", + "sp1-lib 3.1.0", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "git+https://github.com/sp1-patches/curve25519-dalek-ng?branch=patch-v4.1.1#3fb3e7f6047ddeef0f0c9212f4604bd30d64bd28" +dependencies = [ + "anyhow", + "byteorder", + "cfg-if", + "digest 0.9.0", + "rand_core 0.6.4", + "sp1-lib 3.1.0", "subtle-ng", "zeroize", ] @@ -1616,7 +1544,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1627,7 +1555,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1761,7 +1689,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -1782,7 +1710,7 @@ dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "unicode-xid", ] @@ -1828,6 +1756,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "downcast-rs" version = "1.2.1" @@ -1871,7 +1810,7 @@ dependencies = [ "elliptic-curve", "hex-literal", "signature", - "sp1-lib 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp1-lib 3.1.0", "spki 0.7.3", ] @@ -1888,9 +1827,9 @@ dependencies = [ [[package]] name = "ed25519-consensus" version = "2.1.0" -source = "git+https://github.com/sp1-patches/ed25519-consensus?branch=patch-v2.1.0#2b2c4b43344bc4daf5b1326f367f2d9d661eeabb" +source = "git+https://github.com/sp1-patches/ed25519-consensus?tag=ed25519_consensus-v2.1.0-patch-v1#2b2c4b43344bc4daf5b1326f367f2d9d661eeabb" dependencies = [ - "curve25519-dalek-ng", + "curve25519-dalek-ng 4.1.1 (git+https://github.com/sp1-patches/curve25519-dalek-ng?branch=patch-v4.1.1)", "hex", "rand_core 0.6.4", "serde", @@ -1950,33 +1889,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "enr" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" -dependencies = [ - "base64 0.21.7", - "bytes", - "hex", - "k256", - "log", - "rand 0.8.5", - "rlp", - "serde", - "sha3", - "zeroize", -] - [[package]] name = "enr" version = "0.12.1" @@ -2011,7 +1923,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2022,7 +1934,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2041,270 +1953,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "eth-keystore" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" -dependencies = [ - "aes", - "ctr", - "digest 0.10.7", - "hex", - "hmac", - "pbkdf2 0.11.0", - "rand 0.8.5", - "scrypt", - "serde", - "serde_json", - "sha2 0.10.8", - "sha3", - "thiserror", - "uuid", -] - -[[package]] -name = "ethabi" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "primitive-types", - "scale-info", - "uint", -] - -[[package]] -name = "ethers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" -dependencies = [ - "ethers-addressbook", - "ethers-contract", - "ethers-core", - "ethers-middleware", - "ethers-providers", - "ethers-signers", -] - -[[package]] -name = "ethers-addressbook" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" -dependencies = [ - "ethers-core", - "once_cell", - "serde", - "serde_json", -] - -[[package]] -name = "ethers-contract" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" -dependencies = [ - "const-hex", - "ethers-contract-abigen", - "ethers-contract-derive", - "ethers-core", - "ethers-providers", - "futures-util", - "once_cell", - "pin-project", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "ethers-contract-abigen" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" -dependencies = [ - "Inflector", - "const-hex", - "dunce", - "ethers-core", - "eyre", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "serde", - "serde_json", - "syn 2.0.85", - "toml", - "walkdir", -] - -[[package]] -name = "ethers-contract-derive" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" -dependencies = [ - "Inflector", - "const-hex", - "ethers-contract-abigen", - "ethers-core", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.85", -] - -[[package]] -name = "ethers-core" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" -dependencies = [ - "arrayvec 0.7.6", - "bytes", - "cargo_metadata", - "chrono", - "const-hex", - "elliptic-curve", - "ethabi", - "generic-array 0.14.7", - "k256", - "num_enum 0.7.3", - "once_cell", - "open-fastrlp", - "rand 0.8.5", - "rlp", - "serde", - "serde_json", - "strum", - "syn 2.0.85", - "tempfile", - "thiserror", - "tiny-keccak", - "unicode-xid", -] - -[[package]] -name = "ethers-middleware" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" -dependencies = [ - "async-trait", - "auto_impl", - "ethers-contract", - "ethers-core", - "ethers-providers", - "ethers-signers", - "futures-channel", - "futures-locks", - "futures-util", - "instant", - "reqwest 0.11.27", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "url", -] - -[[package]] -name = "ethers-providers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" -dependencies = [ - "async-trait", - "auto_impl", - "base64 0.21.7", - "bytes", - "const-hex", - "enr 0.10.0", - "ethers-core", - "futures-core", - "futures-timer", - "futures-util", - "hashers", - "http 0.2.12", - "instant", - "jsonwebtoken", - "once_cell", - "pin-project", - "reqwest 0.11.27", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-futures", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "ws_stream_wasm", -] - -[[package]] -name = "ethers-signers" -version = "2.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" -dependencies = [ - "async-trait", - "coins-bip32", - "coins-bip39", - "const-hex", - "elliptic-curve", - "eth-keystore", - "ethers-core", - "rand 0.8.5", - "sha2 0.10.8", - "thiserror", - "tracing", -] - [[package]] name = "eyre" version = "0.6.12" @@ -2334,7 +1982,7 @@ dependencies = [ "proc-macro2", "quote", "syn 1.0.109", - "synstructure", + "synstructure 0.12.6", ] [[package]] @@ -2449,21 +2097,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2527,16 +2160,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" -[[package]] -name = "futures-locks" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" -dependencies = [ - "futures-channel", - "futures-task", -] - [[package]] name = "futures-macro" version = "0.3.31" @@ -2545,7 +2168,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -2560,16 +2183,6 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers", - "send_wrapper 0.4.0", -] - [[package]] name = "futures-util" version = "0.3.31" @@ -2589,13 +2202,10 @@ dependencies = [ ] [[package]] -name = "fxhash" -version = "0.2.1" +name = "futures-utils-wasm" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" [[package]] name = "gcd" @@ -2647,7 +2257,7 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", "libgit2-sys", "log", @@ -2660,18 +2270,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "groth16-verifier-program" version = "1.1.0" @@ -2684,7 +2282,6 @@ dependencies = [ name = "groth16-verifier-script" version = "1.1.0" dependencies = [ - "hex", "sp1-build", "sp1-sdk", ] @@ -2712,44 +2309,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.6.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.1.0", - "indexmap 2.6.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "1.8.3" @@ -2798,9 +2357,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" dependencies = [ "allocator-api2", "equivalent", @@ -2808,15 +2367,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hashers" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" -dependencies = [ - "fxhash", -] - [[package]] name = "heck" version = "0.5.0" @@ -2853,17 +2403,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.1.0" @@ -2875,17 +2414,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.1" @@ -2893,7 +2421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.1.0", + "http", ] [[package]] @@ -2904,8 +2432,8 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", "futures-util", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "pin-project-lite", ] @@ -2921,30 +2449,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.14.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.5.0" @@ -2954,9 +2458,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "httparse", "httpdate", "itoa", @@ -2973,8 +2476,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http 1.1.0", - "hyper 1.5.0", + "http", + "hyper", "hyper-util", "rustls", "rustls-pki-types", @@ -2984,47 +2487,18 @@ dependencies = [ "webpki-roots", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper 0.14.31", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.5.0", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", - "http-body 1.0.1", - "hyper 1.5.0", + "http", + "http-body", + "hyper", "pin-project-lite", "socket2", "tokio", @@ -3056,46 +2530,157 @@ dependencies = [ ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] [[package]] -name = "idna" -version = "0.5.0" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "impl-codec" -version = "0.6.0" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ - "parity-scale-codec", + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "impl-rlp" -version = "0.3.0" +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ - "rlp", + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", ] [[package]] -name = "impl-serde" -version = "0.4.0" +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ - "serde", + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", ] [[package]] @@ -3133,7 +2718,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", "serde", ] @@ -3150,15 +2735,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "generic-array 0.14.7", -] - [[package]] name = "instant" version = "0.1.13" @@ -3289,20 +2865,6 @@ dependencies = [ "sp1-sdk", ] -[[package]] -name = "jsonwebtoken" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" -dependencies = [ - "base64 0.21.7", - "pem", - "ring 0.16.20", - "serde", - "serde_json", - "simple_asn1", -] - [[package]] name = "jubjub" version = "0.9.0" @@ -3360,7 +2922,7 @@ dependencies = [ "hex", "sha2 0.10.8", "sp1_bls12_381", - "spin 0.9.8", + "spin", ] [[package]] @@ -3369,7 +2931,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.9.8", + "spin", ] [[package]] @@ -3402,9 +2964,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bda4c6077b0b08da2c48b172195795498381a7c8988c9e6212a6c55c5b9bd70" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libredox" @@ -3412,7 +2974,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", ] @@ -3434,6 +2996,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -3456,7 +3024,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -3537,24 +3105,7 @@ checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", -] - -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "syn 1.0.109", ] [[package]] @@ -3563,7 +3114,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -3685,7 +3236,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3790,10 +3341,9 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -3845,14 +3395,14 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21aad1fbf80d2bcd7406880efc7ba109365f44bbb72896758ddcbfa46bf1592c" dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives 0.8.9", + "alloy-consensus 0.3.6", + "alloy-eips 0.3.6", + "alloy-primitives 0.8.10", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.3.6", "derive_more 1.0.0", "serde", - "spin 0.9.8", + "spin", ] [[package]] @@ -3861,11 +3411,11 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e281fbfc2198b7c0c16457d6524f83d192662bc9f3df70f24c3038d4521616df" dependencies = [ - "alloy-eips", - "alloy-network-primitives", - "alloy-primitives 0.8.9", - "alloy-rpc-types-eth", - "alloy-serde", + "alloy-eips 0.3.6", + "alloy-network-primitives 0.3.6", + "alloy-primitives 0.8.10", + "alloy-rpc-types-eth 0.3.6", + "alloy-serde 0.3.6", "cfg-if", "hashbrown 0.14.5", "op-alloy-consensus", @@ -3879,75 +3429,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "open-fastrlp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" -dependencies = [ - "arrayvec 0.7.6", - "auto_impl", - "bytes", - "ethereum-types", - "open-fastrlp-derive", -] - -[[package]] -name = "open-fastrlp-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" -dependencies = [ - "bytes", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "openssl" -version = "0.10.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" -dependencies = [ - "bitflags 2.6.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.85", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "option-ext" version = "0.2.0" @@ -3974,9 +3455,8 @@ dependencies = [ [[package]] name = "p3-air" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066f571b2e645505ed5972dd0e1e252ba03352150830c9566769ca711c0f1e9b" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -3984,9 +3464,8 @@ dependencies = [ [[package]] name = "p3-baby-bear" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff00f571044d299310d9659c6e51c98422de3bf94b8577f7f30cf59cf2043e40" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "num-bigint 0.4.6", "p3-field", @@ -3997,21 +3476,10 @@ dependencies = [ "serde", ] -[[package]] -name = "p3-blake3" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc4cb69ae54a279bbbd477566d1bdb71aa879b528fd658d0fcfc36f54b00217c" -dependencies = [ - "blake3", - "p3-symmetric", -] - [[package]] name = "p3-bn254-fr" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf19917f986d45e9abb6d177e875824ced6eed096480d574fce16f2c45c721ea" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "ff 0.13.0", "num-bigint 0.4.6", @@ -4024,9 +3492,8 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be7e4fbce4566a93091107eadfafa0b5374bd1ffd3e0f6b850da3ff72eb183f" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -4038,13 +3505,11 @@ dependencies = [ [[package]] name = "p3-commit" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a03eb0f99d68a712c41e658e9a7782a0705d4ffcfb6232a43bd3f1ef9591002" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-challenger", - "p3-dft", "p3-field", "p3-matrix", "p3-util", @@ -4053,9 +3518,8 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1556de968523fbe5d804ab50600ea306fcceea3500cfd7601e40882480524664" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -4066,9 +3530,8 @@ dependencies = [ [[package]] name = "p3-field" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2af6e1ac47a2035af5165e668d64612c4b9ccabd06df37fc1fd381fdf8a71" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "num-bigint 0.4.6", @@ -4080,9 +3543,8 @@ dependencies = [ [[package]] name = "p3-fri" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f351ee9f9d4256455164565cd91e3e6d2487cc2a5355515fa2b6d479269188dd" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-challenger", @@ -4099,9 +3561,8 @@ dependencies = [ [[package]] name = "p3-interpolation" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24d0f2907a374ebe4545fcff3120d6376d9630cf0bef30feedcfc5908ea2c37" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-field", "p3-matrix", @@ -4110,9 +3571,8 @@ dependencies = [ [[package]] name = "p3-keccak-air" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e66badd47cedf6570e91a0cabc389b80dfd53ba1a6e9a45a3923fd54b86122ff" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "p3-air", "p3-field", @@ -4124,9 +3584,8 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa272f3ae77ed8d73478aa7c89e712efb15bda3ff4aff10fadfe11a012cd5389" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-field", @@ -4139,18 +3598,16 @@ dependencies = [ [[package]] name = "p3-maybe-rayon" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eecad6292021858f282d643d9d1284ab112a200494d589863a9c4080e578ef0" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "rayon", ] [[package]] name = "p3-mds" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716c4dbe68a02f1541eb09149d07b8663a3a5951b1864a31cd67ff3bb0826e57" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-dft", @@ -4163,9 +3620,8 @@ dependencies = [ [[package]] name = "p3-merkle-tree" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad7ebab52a03c26025988663a135aed62f5084a2e2ea262176dc8748efb593e5" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-commit", @@ -4180,9 +3636,8 @@ dependencies = [ [[package]] name = "p3-poseidon2" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c042efa15beab7a8c4d0ca9b9e4cbda7582be0c08e121e830fec45f082935b" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "gcd", "p3-field", @@ -4194,9 +3649,8 @@ dependencies = [ [[package]] name = "p3-symmetric" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9896a831f5b688adc13f6fbe1dcf66ecfaa4622a500f81aa745610e777acb72" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-field", @@ -4205,9 +3659,8 @@ dependencies = [ [[package]] name = "p3-uni-stark" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437ebcd060c8a5479898030b114a93da8a86eb4c2e5f313d9eeaaf40c6e6f61" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "itertools 0.12.1", "p3-air", @@ -4224,9 +3677,8 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.1.4-succinct" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dedb9d27ba47ac314c6fac4ca54e55c3e486c864d51ec5ba55dbe47b75121157" +version = "0.1.0" +source = "git+https://github.com/Plonky3/Plonky3?branch=sp1-v4#db3d45d4ec899efaf8f7234a8573f285fbdda5db" dependencies = [ "serde", ] @@ -4338,9 +3790,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" name = "patch-testing-program" version = "1.1.0" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "curve25519-dalek", - "curve25519-dalek-ng", + "curve25519-dalek-ng 4.1.1 (git+https://github.com/sp1-patches/curve25519-dalek-ng?tag=curve25519_dalek_ng-v4.1.1-patch-v1)", "ed25519-consensus", "ed25519-dalek", "revm-precompile", @@ -4360,34 +3812,6 @@ dependencies = [ "sp1-sdk", ] -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest 0.10.7", - "hmac", -] - -[[package]] -name = "pem" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" -dependencies = [ - "base64 0.13.1", -] - [[package]] name = "pem-rfc7468" version = "0.3.1" @@ -4423,36 +3847,6 @@ dependencies = [ "ucd-trie", ] -[[package]] -name = "pharos" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" -dependencies = [ - "futures", - "rustc_version 0.4.1", -] - -[[package]] -name = "pin-project" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.85", -] - [[package]] name = "pin-project-lite" version = "0.2.15" @@ -4542,7 +3936,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4562,9 +3956,6 @@ checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", "uint", ] @@ -4587,30 +3978,6 @@ dependencies = [ "toml_edit 0.22.22", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -4630,7 +3997,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4650,7 +4017,7 @@ checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.6.0", + "bitflags", "lazy_static", "num-traits", "rand 0.8.5", @@ -4692,7 +4059,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4705,7 +4072,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -4749,7 +4116,7 @@ checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ "bytes", "rand 0.8.5", - "ring 0.17.8", + "ring", "rustc-hash 2.0.0", "rustls", "slab", @@ -4760,10 +4127,11 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" +checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780" dependencies = [ + "cfg_aliases", "libc", "once_cell", "socket2", @@ -4907,7 +4275,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -4983,82 +4351,36 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.31", - "hyper-tls 0.5.0", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration 0.5.1", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "reqwest" -version = "0.12.8" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", "bytes", - "encoding_rs", "futures-core", "futures-util", - "h2 0.4.6", - "http 1.1.0", - "http-body 1.0.1", + "http", + "http-body", "http-body-util", - "hyper 1.5.0", + "hyper", "hyper-rustls", - "hyper-tls 0.6.0", "hyper-util", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", "quinn", "rustls", - "rustls-pemfile 2.2.0", + "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", - "system-configuration 0.6.1", "tokio", - "tokio-native-tls", "tokio-rustls", "tokio-util", "tower-service", @@ -5079,8 +4401,8 @@ checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04" dependencies = [ "anyhow", "async-trait", - "http 1.1.0", - "reqwest 0.12.8", + "http", + "reqwest", "serde", "thiserror", "tower-service", @@ -5104,9 +4426,9 @@ version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ "alloy-chains", - "alloy-eips", + "alloy-eips 0.3.6", "alloy-genesis", - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-trie", "auto_impl", "derive_more 1.0.0", @@ -5125,10 +4447,10 @@ name = "reth-codecs" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.3.6", + "alloy-eips 0.3.6", "alloy-genesis", - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-trie", "bytes", "modular-bitfield", @@ -5144,7 +4466,7 @@ dependencies = [ "convert_case 0.6.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -5210,7 +4532,7 @@ version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ "alloy-chains", - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "auto_impl", "crc", @@ -5226,7 +4548,7 @@ name = "reth-evm" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-eips", + "alloy-eips 0.3.6", "auto_impl", "futures-util", "reth-chainspec", @@ -5244,8 +4566,8 @@ name = "reth-evm-ethereum" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-eips", - "alloy-sol-types 0.8.9", + "alloy-eips 0.3.6", + "alloy-sol-types", "reth-chainspec", "reth-ethereum-consensus", "reth-ethereum-forks", @@ -5282,8 +4604,8 @@ name = "reth-execution-errors" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-eips", - "alloy-primitives 0.8.9", + "alloy-eips 0.3.6", + "alloy-primitives 0.8.10", "alloy-rlp", "derive_more 1.0.0", "nybbles", @@ -5320,9 +4642,9 @@ name = "reth-network-peers" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", - "enr 0.12.1", + "enr", "serde_with", "thiserror", "url", @@ -5334,7 +4656,7 @@ version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ "alloy-chains", - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "derive_more 1.0.0", "once_cell", "reth-chainspec", @@ -5360,13 +4682,13 @@ name = "reth-primitives" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.3.6", + "alloy-eips 0.3.6", "alloy-genesis", - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "alloy-rpc-types", - "alloy-serde", + "alloy-serde 0.3.6", "bytes", "derive_more 1.0.0", "k256", @@ -5389,12 +4711,12 @@ name = "reth-primitives-traits" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.3.6", + "alloy-eips 0.3.6", "alloy-genesis", - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", - "alloy-rpc-types-eth", + "alloy-rpc-types-eth 0.3.6", "byteorder", "bytes", "derive_more 1.0.0", @@ -5410,7 +4732,7 @@ name = "reth-prune-types" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "bytes", "derive_more 1.0.0", "modular-bitfield", @@ -5439,7 +4761,7 @@ name = "reth-stages-types" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "bytes", "modular-bitfield", "reth-codecs", @@ -5452,7 +4774,7 @@ name = "reth-static-file-types" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "derive_more 1.0.0", "serde", "strum", @@ -5509,9 +4831,9 @@ name = "reth-trie-common" version = "1.0.6" source = "git+https://github.com/sp1-patches/reth?tag=rsp-20240830#260c7ed2c9374182a43a3602aaa953d37aa9217b" dependencies = [ - "alloy-consensus", + "alloy-consensus 0.3.6", "alloy-genesis", - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "alloy-trie", "bytes", @@ -5566,7 +4888,7 @@ dependencies = [ "ripemd", "secp256k1", "sha2 0.10.8", - "substrate-bn 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v1)", ] [[package]] @@ -5575,10 +4897,10 @@ version = "9.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7a6bff9dbde3370a5ac9555104117f7e6039b3cc76e8d5d9d01899088beca2a" dependencies = [ - "alloy-eips", - "alloy-primitives 0.8.9", + "alloy-eips 0.3.6", + "alloy-primitives 0.8.10", "auto_impl", - "bitflags 2.6.0", + "bitflags", "bitvec", "c-kzg", "cfg-if", @@ -5600,21 +4922,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.8" @@ -5625,8 +4932,8 @@ dependencies = [ "cfg-if", "getrandom", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.52.0", ] @@ -5646,21 +4953,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" dependencies = [ "bytes", - "rlp-derive", "rustc-hex", ] -[[package]] -name = "rlp-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "roaring" version = "0.10.6" @@ -5745,7 +5040,7 @@ name = "rsp-client-executor" version = "0.1.0" source = "git+https://github.com/succinctlabs/rsp/?rev=3647076#3647076da6580e30384dd911a3fc50d4bcdb5bc1" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "eyre", "futures", @@ -5778,7 +5073,7 @@ name = "rsp-mpt" version = "0.1.0" source = "git+https://github.com/succinctlabs/rsp/?rev=3647076#3647076da6580e30384dd911a3fc50d4bcdb5bc1" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "alloy-rlp", "alloy-rpc-types", "anyhow", @@ -5828,7 +5123,7 @@ dependencies = [ name = "rsp-script" version = "0.1.0" dependencies = [ - "alloy-primitives 0.8.9", + "alloy-primitives 0.8.10", "bincode", "clap", "rsp-client-executor", @@ -5925,11 +5220,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -5938,27 +5233,18 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.15" +version = "0.23.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" dependencies = [ "once_cell", - "ring 0.17.8", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", "zeroize", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -5980,9 +5266,9 @@ version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ - "ring 0.17.8", + "ring", "rustls-pki-types", - "untrusted 0.9.0", + "untrusted", ] [[package]] @@ -6009,24 +5295,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scale-info" version = "2.11.5" @@ -6048,7 +5316,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6060,33 +5328,12 @@ dependencies = [ "sdd", ] -[[package]] -name = "schannel" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scrypt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" -dependencies = [ - "hmac", - "pbkdf2 0.11.0", - "salsa20", - "sha2 0.10.8", -] - [[package]] name = "sdd" version = "3.0.4" @@ -6110,45 +5357,22 @@ dependencies = [ [[package]] name = "secp256k1" version = "0.29.0" -source = "git+https://github.com/sp1-patches/rust-secp256k1?branch=patch-secp256k1-v0.29.0#13910d476dbdaf436312a9f096ee312593028557" -dependencies = [ - "cfg-if", - "ecdsa 0.16.9 (git+https://github.com/sp1-patches/signatures?branch=patch-ecdsa-v0.16.9)", - "elliptic-curve", - "k256", - "rand 0.8.5", - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.10.0" -source = "git+https://github.com/sp1-patches/rust-secp256k1?branch=patch-secp256k1-v0.29.0#13910d476dbdaf436312a9f096ee312593028557" +source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=secp256k1-v0.29.0-patch-v1#c78195abe3c5bc11163d69588a5559ef21bdff31" dependencies = [ - "cc", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", + "cfg-if", + "ecdsa 0.16.9 (git+https://github.com/sp1-patches/signatures?branch=patch-ecdsa-v0.16.9)", + "elliptic-curve", + "k256", + "rand 0.8.5", + "secp256k1-sys", ] [[package]] -name = "security-framework-sys" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +name = "secp256k1-sys" +version = "0.10.0" +source = "git+https://github.com/sp1-patches/rust-secp256k1?tag=secp256k1-v0.29.0-patch-v1#c78195abe3c5bc11163d69588a5559ef21bdff31" dependencies = [ - "core-foundation-sys", - "libc", + "cc", ] [[package]] @@ -6178,23 +5402,11 @@ dependencies = [ "pest", ] -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - [[package]] name = "serde" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" dependencies = [ "serde_derive", ] @@ -6220,13 +5432,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.213" +version = "1.0.214" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6260,16 +5472,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", -] - -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", + "syn 2.0.87", ] [[package]] @@ -6311,7 +5514,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6336,7 +5539,7 @@ checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -6354,7 +5557,7 @@ dependencies = [ [[package]] name = "sha2" version = "0.9.9" -source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-sha2-v0.9.9#db82a4848f8d033eab544255e1efa036cc06f054" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?tag=sha2-v0.9.9-patch-v1#db82a4848f8d033eab544255e1efa036cc06f054" dependencies = [ "block-buffer 0.9.0", "cfg-if", @@ -6366,7 +5569,7 @@ dependencies = [ [[package]] name = "sha2" version = "0.10.8" -source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-v0.10.8#1f224388fdede7cef649bce0d63876d1a9e3f515" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?tag=sha2-v0.10.8-patch-v1#1f224388fdede7cef649bce0d63876d1a9e3f515" dependencies = [ "cfg-if", "cpufeatures", @@ -6427,18 +5630,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint 0.4.6", - "num-traits", - "thiserror", - "time", -] - [[package]] name = "size" version = "0.4.1" @@ -6543,7 +5734,6 @@ dependencies = [ "num_cpus", "p3-air", "p3-baby-bear", - "p3-blake3", "p3-challenger", "p3-field", "p3-keccak-air", @@ -6639,18 +5829,9 @@ dependencies = [ [[package]] name = "sp1-lib" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c372b16988e765af85ccf958b18b26d89c05886f2592d313a285415dcc769cb" -dependencies = [ - "bincode", - "serde", -] - -[[package]] -name = "sp1-lib" -version = "3.0.0" -source = "git+https://github.com/succinctlabs/sp1.git?branch=dev#b5c6a41816db138a84371178a84538356cd9addd" +checksum = "14deb700469a37ec075bcf88dac3815b026dd9c4b9cb175980826f1fbb2e4e80" dependencies = [ "bincode", "serde", @@ -6682,7 +5863,6 @@ dependencies = [ "dirs", "eyre", "itertools 0.13.0", - "lazy_static", "lru", "num-bigint 0.4.6", "p3-baby-bear", @@ -6692,8 +5872,6 @@ dependencies = [ "p3-field", "p3-matrix", "p3-symmetric", - "rayon", - "reqwest 0.11.27", "serde", "serde_json", "serial_test", @@ -6705,8 +5883,6 @@ dependencies = [ "sp1-recursion-core", "sp1-recursion-gnark-ffi", "sp1-stark", - "subtle-encoding", - "tempfile", "thiserror", "tracing", "tracing-subscriber", @@ -6834,13 +6010,14 @@ dependencies = [ name = "sp1-sdk" version = "3.0.0" dependencies = [ - "alloy-sol-types 0.7.7", + "alloy-signer", + "alloy-signer-local", + "alloy-sol-types", "anyhow", "async-trait", "bincode", "cfg-if", "dirs", - "ethers", "futures", "hashbrown 0.14.5", "hex", @@ -6851,7 +6028,7 @@ dependencies = [ "p3-field", "p3-fri", "prost 0.13.3", - "reqwest 0.12.8", + "reqwest", "reqwest-middleware", "serde", "sp1-core-executor", @@ -6875,7 +6052,6 @@ name = "sp1-stark" version = "3.0.0" dependencies = [ "arrayref", - "getrandom", "hashbrown 0.14.5", "itertools 0.13.0", "num-traits", @@ -6900,7 +6076,6 @@ dependencies = [ "strum", "strum_macros", "sysinfo", - "thiserror", "tracing", ] @@ -6911,13 +6086,13 @@ dependencies = [ "hex", "lazy_static", "sha2 0.10.8", - "substrate-bn 0.6.0 (git+https://github.com/yuwen01/bn?branch=yuwen/sp1-flag)", + "substrate-bn 0.6.0 (git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2)", "thiserror-no-std", ] [[package]] name = "sp1-zkvm" -version = "3.0.0" +version = "3.0.1" dependencies = [ "cfg-if", "getrandom", @@ -6946,12 +6121,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -7028,6 +6197,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -7059,51 +6234,38 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.85", -] - -[[package]] -name = "substrate-bn" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b5bbfa79abbae15dd642ea8176a21a635ff3c00059961d1ea27ad04e5b441c" -dependencies = [ - "byteorder", - "crunchy", - "lazy_static", - "rand 0.8.5", - "rustc-hex", + "syn 2.0.87", ] [[package]] name = "substrate-bn" version = "0.6.0" -source = "git+https://github.com/yuwen01/bn?branch=yuwen/sp1-flag#d5c1270f612fcaa7107e5b3a5686df8fed78cc3b" +source = "git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v1#9b0e986d32ea128a08cebfe90767072beccdb45f" dependencies = [ "bytemuck", "byteorder", "cfg-if", "crunchy", "lazy_static", - "num-bigint 0.4.6", "rand 0.8.5", "rustc-hex", - "sp1-lib 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sp1-lib 3.1.0", ] [[package]] name = "substrate-bn" version = "0.6.0" -source = "git+https://github.com/sp1-patches/bn?rev=43d854d45b5727b1ff2b9f346d728e785bb8395c#43d854d45b5727b1ff2b9f346d728e785bb8395c" +source = "git+https://github.com/sp1-patches/bn?tag=substrate_bn-v0.6.0-patch-v2#8ef05d3969312eca34fa9f1f566a469022badda6" dependencies = [ "bytemuck", "byteorder", "cfg-if", "crunchy", "lazy_static", + "num-bigint 0.4.6", "rand 0.8.5", "rustc-hex", - "sp1-lib 3.0.0 (git+https://github.com/succinctlabs/sp1.git?branch=dev)", + "sp1-lib 3.1.0", ] [[package]] @@ -7140,9 +6302,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -7151,26 +6313,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.7.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c837dc8852cb7074e46b444afb81783140dab12c58867b49fb3898fbafedf7ea" -dependencies = [ - "paste", - "proc-macro2", - "quote", - "syn 2.0.85", -] - -[[package]] -name = "syn-solidity" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5e0c2ea8db64b2898b62ea2fbd60204ca95e0b2c6bdf53ff768bbe916fbe4d" +checksum = "16320d4a2021ba1a32470b3759676114a918885e9800e68ad60f2c67969fba62" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7200,6 +6350,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "sysinfo" version = "0.30.13" @@ -7215,48 +6376,6 @@ dependencies = [ "windows", ] -[[package]] -name = "system-configuration" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys 0.5.0", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "system-configuration-sys 0.6.0", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tap" version = "1.0.1" @@ -7349,7 +6468,6 @@ dependencies = [ name = "tendermint-script" version = "1.1.0" dependencies = [ - "serde", "serde_cbor", "serde_json", "sp1-build", @@ -7359,22 +6477,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7452,12 +6570,22 @@ dependencies = [ [[package]] name = "tiny-keccak" version = "2.0.2" -source = "git+https://github.com/sp1-patches/tiny-keccak?branch=patch-v2.0.2#bf0b28f63510a90c7b6c21ac6ff461c93ecd2331" +source = "git+https://github.com/sp1-patches/tiny-keccak?tag=tiny_keccak-v2.0.2-patch-v1#bf0b28f63510a90c7b6c21ac6ff461c93ecd2331" dependencies = [ "cfg-if", "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -7499,17 +6627,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", + "syn 2.0.87", ] [[package]] @@ -7536,26 +6654,11 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.8.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.22", -] - [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -dependencies = [ - "serde", -] [[package]] name = "toml_edit" @@ -7575,8 +6678,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.6.0", - "serde", - "serde_spanned", "toml_datetime", "winnow 0.6.20", ] @@ -7629,7 +6730,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", ] [[package]] @@ -7655,16 +6756,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project", - "tracing", -] - [[package]] name = "tracing-log" version = "0.2.0" @@ -7709,11 +6800,11 @@ dependencies = [ "async-trait", "axum", "futures", - "http 1.1.0", + "http", "http-body-util", - "hyper 1.5.0", + "hyper", "prost 0.13.3", - "reqwest 0.12.8", + "reqwest", "serde", "serde_json", "thiserror", @@ -7752,27 +6843,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - [[package]] name = "unicode-ident" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - [[package]] name = "unicode-segmentation" version = "1.12.0" @@ -7791,12 +6867,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -7805,9 +6875,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", "idna", @@ -7815,20 +6885,22 @@ dependencies = [ ] [[package]] -name = "utf8parse" -version = "0.2.2" +name = "utf16_iter" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] -name = "uuid" -version = "0.8.2" +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom", - "serde", -] +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "valuable" @@ -7879,16 +6951,6 @@ dependencies = [ "libc", ] -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "want" version = "0.3.1" @@ -7926,7 +6988,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -7960,7 +7022,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8029,15 +7091,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -8260,41 +7313,48 @@ dependencies = [ ] [[package]] -name = "winreg" -version = "0.50.0" +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "wyz" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ - "cfg-if", - "windows-sys 0.48.0", + "tap", ] [[package]] -name = "ws_stream_wasm" +name = "yoke" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" dependencies = [ - "async_io_stream", - "futures", - "js-sys", - "log", - "pharos", - "rustc_version 0.4.1", - "send_wrapper 0.6.0", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", ] [[package]] -name = "wyz" -version = "0.5.1" +name = "yoke-derive" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ - "tap", + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", ] [[package]] @@ -8315,7 +7375,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", + "synstructure 0.13.1", ] [[package]] @@ -8335,7 +7416,29 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.87", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] @@ -8368,14 +7471,14 @@ dependencies = [ [[patch.unused]] name = "ecdsa" version = "0.16.8" -source = "git+https://github.com/sp1-patches/signatures?branch=ratan/secp256k1-add-fixes-v0.16.8#cdeab4f0ed0d715ceae3fc6d09d16ec3ae41ead7" +source = "git+https://github.com/sp1-patches/signatures?tag=ecdsa-v0.16.8-patch-v1#aad9626d51e830729969220eee44de082ff97d53" [[patch.unused]] name = "sha2" version = "0.10.6" -source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-sha2-v0.10.6#e5f8b7eaaa9801503bd998932a52b65848eee234" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?tag=sha2-v0.10.6-patch-v1#e5f8b7eaaa9801503bd998932a52b65848eee234" [[patch.unused]] name = "sha2" version = "0.9.8" -source = "git+https://github.com/sp1-patches/RustCrypto-hashes?branch=patch-sha2-v0.9.8#afdbfb09c325f8a69c01d540ec9a261e3637725d" +source = "git+https://github.com/sp1-patches/RustCrypto-hashes?tag=sha2-v0.9.8-patch-v1#afdbfb09c325f8a69c01d540ec9a261e3637725d" diff --git a/examples/groth16/script/Cargo.toml b/examples/groth16/script/Cargo.toml index a9768a95ba..24e96a2fc5 100644 --- a/examples/groth16/script/Cargo.toml +++ b/examples/groth16/script/Cargo.toml @@ -5,7 +5,6 @@ edition = { workspace = true } publish = false [dependencies] -hex = "0.4.3" sp1-sdk = { workspace = true } [build-dependencies] diff --git a/examples/tendermint/script/Cargo.toml b/examples/tendermint/script/Cargo.toml index af778202d0..4e60dab52b 100644 --- a/examples/tendermint/script/Cargo.toml +++ b/examples/tendermint/script/Cargo.toml @@ -6,7 +6,6 @@ publish = false [dependencies] sp1-sdk = { workspace = true } -serde = { version = "1.0", default-features = false, features = ["derive"] } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } tendermint-light-client-verifier = { version = "0.35.0", default-features = false, features = [ "rust-crypto", diff --git a/tests/bls12381-double/Cargo.toml b/tests/bls12381-double/Cargo.toml index 33bc133f77..f93909483e 100644 --- a/tests/bls12381-double/Cargo.toml +++ b/tests/bls12381-double/Cargo.toml @@ -6,4 +6,3 @@ publish = false [dependencies] sp1-zkvm = { path = "../../crates/zkvm/entrypoint" } -num = { version = "0.4.1", default-features = false } diff --git a/tests/ed-add/Cargo.toml b/tests/ed-add/Cargo.toml index 9e820d6b6b..0beb43f4f6 100644 --- a/tests/ed-add/Cargo.toml +++ b/tests/ed-add/Cargo.toml @@ -6,5 +6,3 @@ publish = false [dependencies] sp1-zkvm = { path = "../../crates/zkvm/entrypoint" } -hex-literal = "0.4.1" -num = { version = "0.4.1", default-features = false } diff --git a/tests/rand/Cargo.toml b/tests/rand/Cargo.toml index 1d432a3892..fed3efb4cf 100644 --- a/tests/rand/Cargo.toml +++ b/tests/rand/Cargo.toml @@ -6,5 +6,4 @@ publish = false [dependencies] sp1-zkvm = { path = "../../crates/zkvm/entrypoint" } -sp1-derive = { path = "../../crates/derive" } rand = "0.8.5" From 432b4a4db2f8b007c0febf94a8ba1164e5908ecb Mon Sep 17 00:00:00 2001 From: Probot <94048855+Prabhat1308@users.noreply.github.com> Date: Wed, 6 Nov 2024 03:15:13 +0530 Subject: [PATCH 17/17] docs: change docs for updated function call (#1732) --- book/writing-programs/proof-aggregation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/book/writing-programs/proof-aggregation.md b/book/writing-programs/proof-aggregation.md index f9bc1c1068..36ee28e1ce 100644 --- a/book/writing-programs/proof-aggregation.md +++ b/book/writing-programs/proof-aggregation.md @@ -15,10 +15,10 @@ Note that by itself, SP1 can already prove arbitrarily large programs by chunkin ## Verifying Proofs inside the zkVM -To verify a proof inside the zkVM, you can use the `sp1_zkvm::lib::verify::verify_proof` function. +To verify a proof inside the zkVM, you can use the `sp1_zkvm::lib::verify::verify_sp1_proof` function. ```rust,noplayground -sp1_zkvm::lib::verify::verify_proof(vkey, public_values_digest); +sp1_zkvm::lib::verify::verify_sp1_proof(vkey, public_values_digest); ``` **You do not need to pass in the proof as input into the syscall, as the proof will automatically be read for the proof input stream by the prover.**