diff --git a/emulator/src/state.rs b/emulator/src/state.rs index a5b5fbea..e155e1ac 100644 --- a/emulator/src/state.rs +++ b/emulator/src/state.rs @@ -541,44 +541,59 @@ impl InstrumentedState { log::debug!("syscall {} {} {} {}", syscall_num, a0, a1, a2); match syscall_num { - 0x300105 => { // SHA_EXTEND + 0x300105 => { + // SHA_EXTEND let w_ptr = a0; assert!(a1 == 0, "arg2 must be 0"); for i in 16..64 { // Read w[i-15]. - let w_i_minus_15 = self.state.memory.get_memory(w_ptr + (i - 15) * 4); + let w_i_minus_15 = self.state.memory.get_memory(w_ptr + (i - 15) * 4); // Compute `s0`. - let s0 = - w_i_minus_15.rotate_right(7) ^ w_i_minus_15.rotate_right(18) ^ (w_i_minus_15 >> 3); + let s0 = w_i_minus_15.rotate_right(7) + ^ w_i_minus_15.rotate_right(18) + ^ (w_i_minus_15 >> 3); // Read w[i-2]. - let w_i_minus_2 = self.state.memory.get_memory(w_ptr + (i - 2) * 4); + let w_i_minus_2 = self.state.memory.get_memory(w_ptr + (i - 2) * 4); // Compute `s1`. - let s1 = - w_i_minus_2.rotate_right(17) ^ w_i_minus_2.rotate_right(19) ^ (w_i_minus_2 >> 10); + let s1 = w_i_minus_2.rotate_right(17) + ^ w_i_minus_2.rotate_right(19) + ^ (w_i_minus_2 >> 10); // Read w[i-16]. - let w_i_minus_16 = self.state.memory.get_memory(w_ptr + (i - 16) * 4); + let w_i_minus_16 = self.state.memory.get_memory(w_ptr + (i - 16) * 4); // Read w[i-7]. - let w_i_minus_7 = self.state.memory.get_memory(w_ptr + (i - 7) * 4); + let w_i_minus_7 = self.state.memory.get_memory(w_ptr + (i - 7) * 4); // Compute `w_i`. - let w_i = s1.wrapping_add(w_i_minus_16).wrapping_add(s0).wrapping_add(w_i_minus_7); + let w_i = s1 + .wrapping_add(w_i_minus_16) + .wrapping_add(s0) + .wrapping_add(w_i_minus_7); // Write w[i]. - log::debug!("{:X}, {:X}, {:X} {:X} {:X} {:X}", s1, s0, w_i_minus_16, w_i_minus_7, w_i_minus_15, w_i_minus_2); + log::debug!( + "{:X}, {:X}, {:X} {:X} {:X} {:X}", + s1, + s0, + w_i_minus_16, + w_i_minus_7, + w_i_minus_15, + w_i_minus_2 + ); self.state.memory.set_memory(w_ptr + i * 4, w_i); log::debug!("extend write {:X} {:X}", w_ptr + i * 4, w_i); } - }, - 0x010106 => { // SHA_COMPRESS + } + 0x010106 => { + // SHA_COMPRESS let w_ptr = a0; let h_ptr = a1; let mut hx = [0u32; 8]; - for i in 0..8 { - hx[i] = self.state.memory.get_memory(h_ptr + i as u32 * 4); + for (i, hx_item) in hx.iter_mut().enumerate() { + *hx_item = self.state.memory.get_memory(h_ptr + i as u32 * 4); } let mut original_w = Vec::new(); @@ -617,11 +632,18 @@ impl InstrumentedState { // Execute the "finalize" phase. let v = [a, b, c, d, e, f, g, h]; for i in 0..8 { - self.state.memory.set_memory(h_ptr + i as u32 * 4, hx[i].wrapping_add(v[i])); - log::debug!("write {:X} {:X}", h_ptr + i as u32 * 4, hx[i].wrapping_add(v[i])); + self.state + .memory + .set_memory(h_ptr + i as u32 * 4, hx[i].wrapping_add(v[i])); + log::debug!( + "write {:X} {:X}", + h_ptr + i as u32 * 4, + hx[i].wrapping_add(v[i]) + ); } - }, - 0x010109 => { //keccak + } + 0x010109 => { + //keccak assert!((a0 & 3) == 0); assert!((a2 & 3) == 0); let bytes = (0..a1) @@ -664,7 +686,7 @@ impl InstrumentedState { log::debug!("input: {:?}", vec); assert_eq!(a0 % 4, 0, "hint read address not aligned to 4 bytes"); if a1 >= 1 { - self.state.cycle += (a1 as u64 + 31) / 32; + self.state.cycle += (a1 as u64).div_ceil(32); } for i in (0..a1).step_by(4) { // Get each byte in the chunk diff --git a/prover/src/all_stark.rs b/prover/src/all_stark.rs index b15fd893..dc867624 100644 --- a/prover/src/all_stark.rs +++ b/prover/src/all_stark.rs @@ -26,7 +26,9 @@ use crate::poseidon_sponge::poseidon_sponge_stark::PoseidonSpongeStark; use crate::sha_compress::sha_compress_stark; use crate::sha_compress::sha_compress_stark::ShaCompressStark; use crate::sha_compress_sponge::sha_compress_sponge_stark; -use crate::sha_compress_sponge::sha_compress_sponge_stark::{ShaCompressSpongeStark, SHA_COMPRESS_SPONGE_READ_BITS}; +use crate::sha_compress_sponge::sha_compress_sponge_stark::{ + ShaCompressSpongeStark, SHA_COMPRESS_SPONGE_READ_BITS, +}; use crate::sha_extend::sha_extend_stark; use crate::sha_extend::sha_extend_stark::ShaExtendStark; use crate::sha_extend_sponge::columns::SHA_EXTEND_SPONGE_READ_BITS; @@ -81,9 +83,11 @@ impl, const D: usize> AllStark { self.keccak_stark.num_lookup_helper_columns(config), self.keccak_sponge_stark.num_lookup_helper_columns(config), self.sha_extend_stark.num_lookup_helper_columns(config), - self.sha_extend_sponge_stark.num_lookup_helper_columns(config), + self.sha_extend_sponge_stark + .num_lookup_helper_columns(config), self.sha_compress_stark.num_lookup_helper_columns(config), - self.sha_compress_sponge_stark.num_lookup_helper_columns(config), + self.sha_compress_sponge_stark + .num_lookup_helper_columns(config), self.logic_stark.num_lookup_helper_columns(config), self.memory_stark.num_lookup_helper_columns(config), ] @@ -292,7 +296,6 @@ fn ctl_sha_extend_sponge() -> CrossTableLookup { CrossTableLookup::new(vec![cpu_looking], sha_extend_sponge_looked) } - fn ctl_sha_compress_inputs() -> CrossTableLookup { let sha_compress_sponge_looking = TableWithColumns::new( Table::ShaCompressSponge, diff --git a/prover/src/lib.rs b/prover/src/lib.rs index 9eea1ca6..868f1829 100644 --- a/prover/src/lib.rs +++ b/prover/src/lib.rs @@ -28,13 +28,13 @@ pub mod poseidon_sponge; pub mod proof; pub mod prover; pub mod recursive_verifier; +pub mod sha_compress; +pub mod sha_compress_sponge; +pub mod sha_extend; +pub mod sha_extend_sponge; pub mod stark; pub mod stark_testing; pub mod util; pub mod vanishing_poly; pub mod verifier; pub mod witness; -pub mod sha_extend; -pub mod sha_extend_sponge; -pub mod sha_compress; -pub mod sha_compress_sponge; diff --git a/prover/src/sha_compress/columns.rs b/prover/src/sha_compress/columns.rs index fc0eeb24..2a9913fc 100644 --- a/prover/src/sha_compress/columns.rs +++ b/prover/src/sha_compress/columns.rs @@ -1,10 +1,8 @@ +use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; use std::borrow::{Borrow, BorrowMut}; use std::intrinsics::transmute; -use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; #[derive(Clone)] pub(crate) struct ShaCompressColumnsView { - - /// input state: a,b,c,d,e,f,g,h in binary form pub input_state: [T; 256], /// Out @@ -20,37 +18,36 @@ pub(crate) struct ShaCompressColumnsView { pub s_1: [T; 32], pub e_and_f: [T; 32], pub not_e_and_g: [T; 32], - pub ch: [T;32], + pub ch: [T; 32], // h.wrapping_add(s1) - pub inter_1: [T;32], - pub carry_1: [T;32], + pub inter_1: [T; 32], + pub carry_1: [T; 32], // inter_1.wrapping_add(ch) - pub inter_2: [T;32], - pub carry_2: [T;32], + pub inter_2: [T; 32], + pub carry_2: [T; 32], // inter_2.wrapping_add(SHA_COMPRESS_K[i]) - pub inter_3: [T;32], - pub carry_3: [T;32], + pub inter_3: [T; 32], + pub carry_3: [T; 32], // inter_3.wrapping_add(w_i) - pub temp1: [T;32], - pub carry_4: [T;32], - - pub a_rr_2: [T;32], - pub a_rr_13: [T;32], - pub a_rr_22: [T;32], - pub s_0: [T;32], - pub a_and_b: [T;32], - pub a_and_c: [T;32], - pub b_and_c: [T;32], - pub maj: [T;32], - pub temp2: [T;32], - pub carry_5: [T;32], + pub temp1: [T; 32], + pub carry_4: [T; 32], + + pub a_rr_2: [T; 32], + pub a_rr_13: [T; 32], + pub a_rr_22: [T; 32], + pub s_0: [T; 32], + pub a_and_b: [T; 32], + pub a_and_c: [T; 32], + pub b_and_c: [T; 32], + pub maj: [T; 32], + pub temp2: [T; 32], + pub carry_5: [T; 32], pub carry_a: [T; 32], pub carry_e: [T; 32], /// The timestamp at which inputs should be read from memory. pub timestamp: T, pub is_normal_round: T, - } pub const NUM_SHA_COMPRESS_COLUMNS: usize = size_of::>(); diff --git a/prover/src/sha_compress/logic.rs b/prover/src/sha_compress/logic.rs index dbd7da1c..bccd962e 100644 --- a/prover/src/sha_compress/logic.rs +++ b/prover/src/sha_compress/logic.rs @@ -1,13 +1,13 @@ +use crate::keccak::logic::andn_gen_circuit; use plonky2::field::extension::Extendable; use plonky2::field::packed::PackedField; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; use plonky2::plonk::circuit_builder::CircuitBuilder; -use crate::keccak::logic::andn_gen_circuit; pub(crate) fn and_op, const D: usize, const N: usize>( x: [F; N], - y: [F; N] + y: [F; N], ) -> [F; N] { let mut result = [F::ZERO; N]; for i in 0..N { @@ -21,7 +21,7 @@ pub(crate) fn and_op, const D: usize, const N: usiz pub(crate) fn and_op_packed_constraints( x: [P; N], y: [P; N], - out: [P; N] + out: [P; N], ) -> Vec

{ let mut result = vec![]; for i in 0..N { @@ -31,15 +31,18 @@ pub(crate) fn and_op_packed_constraints( result } -pub(crate) fn and_op_ext_circuit_constraints, const D: usize, const N: usize>( +pub(crate) fn and_op_ext_circuit_constraints< + F: RichField + Extendable, + const D: usize, + const N: usize, +>( builder: &mut CircuitBuilder, x: [ExtensionTarget; N], y: [ExtensionTarget; N], - out: [ExtensionTarget; N] + out: [ExtensionTarget; N], ) -> Vec> { let mut result = vec![]; for i in 0..N { - let expected_out = builder.mul_extension(x[i], y[i]); let out_constraint = builder.sub_extension(expected_out, out[i]); result.push(out_constraint); @@ -49,7 +52,7 @@ pub(crate) fn and_op_ext_circuit_constraints, const pub(crate) fn andn_op, const D: usize, const N: usize>( x: [F; N], - y: [F; N] + y: [F; N], ) -> [F; N] { let mut result = [F::ZERO; N]; for i in 0..N { @@ -63,7 +66,7 @@ pub(crate) fn andn_op, const D: usize, const N: usi pub(crate) fn andn_op_packed_constraints( x: [P; N], y: [P; N], - out: [P; N] + out: [P; N], ) -> Vec

{ let mut result = vec![]; for i in 0..N { @@ -73,15 +76,18 @@ pub(crate) fn andn_op_packed_constraints( result } -pub(crate) fn andn_op_ext_circuit_constraints, const D: usize, const N: usize>( +pub(crate) fn andn_op_ext_circuit_constraints< + F: RichField + Extendable, + const D: usize, + const N: usize, +>( builder: &mut CircuitBuilder, x: [ExtensionTarget; N], y: [ExtensionTarget; N], - out: [ExtensionTarget; N] + out: [ExtensionTarget; N], ) -> Vec> { let mut result = vec![]; for i in 0..N { - let expected_out = andn_gen_circuit(builder, x[i], y[i]); let out_constraint = builder.sub_extension(expected_out, out[i]); result.push(out_constraint); @@ -91,7 +97,7 @@ pub(crate) fn andn_op_ext_circuit_constraints, cons pub(crate) fn xor_op, const D: usize, const N: usize>( x: [F; N], - y: [F; N] + y: [F; N], ) -> [F; N] { let mut result = [F::ZERO; N]; for i in 0..N { @@ -113,7 +119,11 @@ pub(crate) fn equal_packed_constraint( result } -pub(crate) fn equal_ext_circuit_constraints, const D: usize, const N: usize>( +pub(crate) fn equal_ext_circuit_constraints< + F: RichField + Extendable, + const D: usize, + const N: usize, +>( builder: &mut CircuitBuilder, x: [ExtensionTarget; N], y: [ExtensionTarget; N], @@ -126,10 +136,10 @@ pub(crate) fn equal_ext_circuit_constraints, const result } -pub(crate) fn from_be_bits_to_u32( bits: [u8; 32]) -> u32 { +pub(crate) fn from_be_bits_to_u32(bits: [u8; 32]) -> u32 { let mut result = 0; for i in 0..32 { result |= (bits[i] as u32) << i; } result -} \ No newline at end of file +} diff --git a/prover/src/sha_compress/mod.rs b/prover/src/sha_compress/mod.rs index f48755ac..e8b4ff9c 100644 --- a/prover/src/sha_compress/mod.rs +++ b/prover/src/sha_compress/mod.rs @@ -1,3 +1,3 @@ pub mod columns; +pub mod logic; pub mod sha_compress_stark; -pub mod logic; \ No newline at end of file diff --git a/prover/src/sha_compress/sha_compress_stark.rs b/prover/src/sha_compress/sha_compress_stark.rs index f0078e91..04bc968c 100644 --- a/prover/src/sha_compress/sha_compress_stark.rs +++ b/prover/src/sha_compress/sha_compress_stark.rs @@ -1,5 +1,22 @@ -use std::marker::PhantomData; -use std::borrow::Borrow; +use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::cross_table_lookup::{Column, Filter}; +use crate::evaluation_frame::{StarkEvaluationFrame, StarkFrame}; +use crate::keccak::logic::{xor3_gen, xor3_gen_circuit, xor_gen, xor_gen_circuit}; +use crate::sha_compress::columns::{ + ShaCompressColumnsView, NUM_SHA_COMPRESS_COLUMNS, SHA_COMPRESS_COL_MAP, +}; +use crate::sha_compress::logic::{ + and_op, and_op_ext_circuit_constraints, and_op_packed_constraints, andn_op, + andn_op_ext_circuit_constraints, andn_op_packed_constraints, equal_ext_circuit_constraints, + equal_packed_constraint, xor_op, +}; +use crate::sha_extend::logic::{ + get_input_range, rotate_right, rotate_right_ext_circuit_constraint, + rotate_right_packed_constraints, wrapping_add, wrapping_add_ext_circuit_constraints, + wrapping_add_packed_constraints, xor3, +}; +use crate::stark::Stark; +use crate::util::trace_rows_to_poly_values; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::packed::PackedField; use plonky2::field::polynomial::PolynomialValues; @@ -7,21 +24,13 @@ use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; use plonky2::plonk::circuit_builder::CircuitBuilder; -use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use crate::cross_table_lookup::{Column, Filter}; -use crate::evaluation_frame::{StarkEvaluationFrame, StarkFrame}; -use crate::keccak::logic::{xor3_gen, xor3_gen_circuit, xor_gen, xor_gen_circuit}; -use crate::sha_compress::columns::{ShaCompressColumnsView, NUM_SHA_COMPRESS_COLUMNS, SHA_COMPRESS_COL_MAP}; -use crate::sha_compress::logic::{and_op, and_op_ext_circuit_constraints, and_op_packed_constraints, andn_op, andn_op_ext_circuit_constraints, andn_op_packed_constraints, equal_ext_circuit_constraints, equal_packed_constraint, xor_op}; -use crate::sha_extend::logic::{rotate_right, get_input_range, xor3, wrapping_add, rotate_right_packed_constraints, wrapping_add_packed_constraints, rotate_right_ext_circuit_constraint, wrapping_add_ext_circuit_constraints}; -use crate::stark::Stark; -use crate::util::trace_rows_to_poly_values; +use std::borrow::Borrow; +use std::marker::PhantomData; pub const NUM_ROUND_CONSTANTS: usize = 64; pub const NUM_INPUTS: usize = 10 * 32; // 8 states (a, b, ..., h) + w_i + key_i - pub fn ctl_data_inputs() -> Vec> { let cols = SHA_COMPRESS_COL_MAP; let mut res: Vec<_> = Column::singles( @@ -30,9 +39,9 @@ pub fn ctl_data_inputs() -> Vec> { cols.w_i.as_slice(), cols.k_i.as_slice(), ] - .concat(), + .concat(), ) - .collect(); + .collect(); res.push(Column::single(cols.timestamp)); res } @@ -77,7 +86,8 @@ impl, const D: usize> ShaCompressStark { inputs_and_timestamps: Vec<([u8; NUM_INPUTS], usize)>, min_rows: usize, ) -> Vec<[F; NUM_SHA_COMPRESS_COLUMNS]> { - let num_rows = inputs_and_timestamps.len() + let num_rows = inputs_and_timestamps + .len() .max(min_rows) .next_power_of_two(); @@ -97,7 +107,6 @@ impl, const D: usize> ShaCompressStark { &self, input_and_timestamp: ([u8; NUM_INPUTS], usize), ) -> [F; NUM_SHA_COMPRESS_COLUMNS] { - let timestamp = input_and_timestamp.1; let inputs = input_and_timestamp.0; @@ -105,9 +114,24 @@ impl, const D: usize> ShaCompressStark { row.timestamp = F::from_canonical_usize(timestamp); row.is_normal_round = F::ONE; // read inputs - row.input_state = inputs[0..256].iter().map(|x| F::from_canonical_u8(*x)).collect::>().try_into().unwrap(); - row.w_i = inputs[256..288].iter().map(|x| F::from_canonical_u8(*x)).collect::>().try_into().unwrap(); - row.k_i = inputs[288..320].iter().map(|x| F::from_canonical_u8(*x)).collect::>().try_into().unwrap(); + row.input_state = inputs[0..256] + .iter() + .map(|x| F::from_canonical_u8(*x)) + .collect::>() + .try_into() + .unwrap(); + row.w_i = inputs[256..288] + .iter() + .map(|x| F::from_canonical_u8(*x)) + .collect::>() + .try_into() + .unwrap(); + row.k_i = inputs[288..320] + .iter() + .map(|x| F::from_canonical_u8(*x)) + .collect::>() + .try_into() + .unwrap(); // compute row.e_rr_6 = rotate_right(row.input_state[get_input_range(4)].try_into().unwrap(), 6); @@ -132,20 +156,11 @@ impl, const D: usize> ShaCompressStark { row.s_1, ); - (row.inter_2, row.carry_2) = wrapping_add( - row.inter_1, - row.ch, - ); + (row.inter_2, row.carry_2) = wrapping_add(row.inter_1, row.ch); - (row.inter_3, row.carry_3) = wrapping_add( - row.inter_2, - row.k_i, - ); + (row.inter_3, row.carry_3) = wrapping_add(row.inter_2, row.k_i); - (row.temp1, row.carry_4) = wrapping_add( - row.inter_3, - row.w_i, - ); + (row.temp1, row.carry_4) = wrapping_add(row.inter_3, row.w_i); row.a_rr_2 = rotate_right(row.input_state[get_input_range(0)].try_into().unwrap(), 2); row.a_rr_13 = rotate_right(row.input_state[get_input_range(0)].try_into().unwrap(), 13); @@ -168,11 +183,7 @@ impl, const D: usize> ShaCompressStark { ); row.maj = xor3(row.a_and_b, row.a_and_c, row.b_and_c); - (row.temp2, row.carry_5) = wrapping_add( - row.s_0, - row.maj, - ); - + (row.temp2, row.carry_5) = wrapping_add(row.s_0, row.maj); for i in 32..256 { row.output_state[i] = row.input_state[i - 32]; @@ -186,10 +197,7 @@ impl, const D: usize> ShaCompressStark { row.temp1, ); - (new_a, row.carry_a) = wrapping_add( - row.temp1, - row.temp2, - ); + (new_a, row.carry_a) = wrapping_add(row.temp1, row.temp2); for i in 0..32 { row.output_state[i] = new_a[i]; @@ -202,19 +210,19 @@ impl, const D: usize> ShaCompressStark { impl, const D: usize> Stark for ShaCompressStark { type EvaluationFrame - = StarkFrame + = StarkFrame where - FE: FieldExtension, - P: PackedField; + FE: FieldExtension, + P: PackedField; type EvaluationFrameTarget = StarkFrame, NUM_SHA_COMPRESS_COLUMNS>; fn eval_packed_generic( &self, vars: &Self::EvaluationFrame, - yield_constr: &mut ConstraintConsumer

+ yield_constr: &mut ConstraintConsumer

, ) where - FE: FieldExtension, - P: PackedField + FE: FieldExtension, + P: PackedField, { let local_values: &[P; NUM_SHA_COMPRESS_COLUMNS] = vars.get_local_values().try_into().unwrap(); @@ -222,7 +230,8 @@ impl, const D: usize> Stark for ShaCompressSt // check the input binary form for i in 0..256 { - yield_constr.constraint(local_values.input_state[i] * (local_values.input_state[i] - P::ONES)); + yield_constr + .constraint(local_values.input_state[i] * (local_values.input_state[i] - P::ONES)); } for i in 0..32 { yield_constr.constraint(local_values.w_i[i] * (local_values.w_i[i] - P::ONES)); @@ -231,68 +240,91 @@ impl, const D: usize> Stark for ShaCompressSt // check the bit values are zero or one in output for i in 0..256 { - yield_constr.constraint(local_values.output_state[i] * (local_values.output_state[i] - P::ONES)); + yield_constr.constraint( + local_values.output_state[i] * (local_values.output_state[i] - P::ONES), + ); } // check the rotation rotate_right_packed_constraints( - local_values.input_state[get_input_range(4)].try_into().unwrap(), + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), local_values.e_rr_6, - 6 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 6, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); rotate_right_packed_constraints( - local_values.input_state[get_input_range(4)].try_into().unwrap(), + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), local_values.e_rr_11, - 11 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 11, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); rotate_right_packed_constraints( - local_values.input_state[get_input_range(4)].try_into().unwrap(), + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), local_values.e_rr_25, - 25 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 25, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); rotate_right_packed_constraints( - local_values.input_state[get_input_range(0)].try_into().unwrap(), + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), local_values.a_rr_2, - 2 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 2, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); rotate_right_packed_constraints( - local_values.input_state[get_input_range(0)].try_into().unwrap(), + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), local_values.a_rr_13, - 13 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 13, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); rotate_right_packed_constraints( - local_values.input_state[get_input_range(0)].try_into().unwrap(), + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), local_values.a_rr_22, - 22 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 22, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); // check the xor for i in 0..32 { let s1 = xor3_gen( local_values.e_rr_6[i], local_values.e_rr_11[i], - local_values.e_rr_25[i] + local_values.e_rr_25[i], ); yield_constr.constraint(local_values.s_1[i] - s1); let s0 = xor3_gen( local_values.a_rr_2[i], local_values.a_rr_13[i], - local_values.a_rr_22[i] + local_values.a_rr_22[i], ); yield_constr.constraint(local_values.s_0[i] - s0); - let ch = xor_gen( - local_values.e_and_f[i], - local_values.not_e_and_g[i] - ); + let ch = xor_gen(local_values.e_and_f[i], local_values.not_e_and_g[i]); yield_constr.constraint(local_values.ch[i] - ch); let maj = xor3_gen( local_values.a_and_b[i], local_values.a_and_c[i], - local_values.b_and_c[i] + local_values.b_and_c[i], ); yield_constr.constraint(local_values.maj[i] - maj); } @@ -300,101 +332,170 @@ impl, const D: usize> Stark for ShaCompressSt // wrapping add constraints wrapping_add_packed_constraints( - local_values.input_state[get_input_range(7)].try_into().unwrap(), + local_values.input_state[get_input_range(7)] + .try_into() + .unwrap(), local_values.s_1, local_values.carry_1, - local_values.inter_1 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.inter_1, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); wrapping_add_packed_constraints( local_values.inter_1, local_values.ch, local_values.carry_2, - local_values.inter_2 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.inter_2, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); wrapping_add_packed_constraints( local_values.inter_2, local_values.k_i, local_values.carry_3, - local_values.inter_3 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.inter_3, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); wrapping_add_packed_constraints( local_values.inter_3, local_values.w_i, local_values.carry_4, - local_values.temp1 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.temp1, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); wrapping_add_packed_constraints( local_values.s_0, local_values.maj, local_values.carry_5, - local_values.temp2 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.temp2, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); wrapping_add_packed_constraints( - local_values.input_state[get_input_range(3)].try_into().unwrap(), + local_values.input_state[get_input_range(3)] + .try_into() + .unwrap(), local_values.temp1, local_values.carry_e, - local_values.output_state[get_input_range(4)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.output_state[get_input_range(4)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); wrapping_add_packed_constraints( local_values.temp1, local_values.temp2, local_values.carry_a, - local_values.output_state[get_input_range(0)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.output_state[get_input_range(0)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); // The op constraints and_op_packed_constraints( - local_values.input_state[get_input_range(4)].try_into().unwrap(), - local_values.input_state[get_input_range(5)].try_into().unwrap(), - local_values.e_and_f - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(5)] + .try_into() + .unwrap(), + local_values.e_and_f, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); and_op_packed_constraints( - local_values.input_state[get_input_range(0)].try_into().unwrap(), - local_values.input_state[get_input_range(1)].try_into().unwrap(), - local_values.a_and_b - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(1)] + .try_into() + .unwrap(), + local_values.a_and_b, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); and_op_packed_constraints( - local_values.input_state[get_input_range(0)].try_into().unwrap(), - local_values.input_state[get_input_range(2)].try_into().unwrap(), - local_values.a_and_c - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(2)] + .try_into() + .unwrap(), + local_values.a_and_c, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); and_op_packed_constraints( - local_values.input_state[get_input_range(1)].try_into().unwrap(), - local_values.input_state[get_input_range(2)].try_into().unwrap(), - local_values.b_and_c - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.input_state[get_input_range(1)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(2)] + .try_into() + .unwrap(), + local_values.b_and_c, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); andn_op_packed_constraints( - local_values.input_state[get_input_range(4)].try_into().unwrap(), - local_values.input_state[get_input_range(6)].try_into().unwrap(), - local_values.not_e_and_g - ).into_iter().for_each(|c| yield_constr.constraint(c)); - + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(6)] + .try_into() + .unwrap(), + local_values.not_e_and_g, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); // output constraint equal_packed_constraint::( - local_values.output_state[get_input_range(1)].try_into().unwrap(), - local_values.input_state[get_input_range(0)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.output_state[get_input_range(1)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); equal_packed_constraint::( - local_values.output_state[get_input_range(2)].try_into().unwrap(), - local_values.input_state[get_input_range(1)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.output_state[get_input_range(2)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(1)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); equal_packed_constraint::( - local_values.output_state[get_input_range(3)].try_into().unwrap(), - local_values.input_state[get_input_range(2)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.output_state[get_input_range(3)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(2)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); // equal_packed_constraint( // local_values.output_state[get_input_range(4)].try_into().unwrap(), @@ -402,26 +503,44 @@ impl, const D: usize> Stark for ShaCompressSt // ).into_iter().for_each(|c| yield_constr.constraint(c)); equal_packed_constraint::( - local_values.output_state[get_input_range(5)].try_into().unwrap(), - local_values.input_state[get_input_range(4)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.output_state[get_input_range(5)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); equal_packed_constraint::( - local_values.output_state[get_input_range(6)].try_into().unwrap(), - local_values.input_state[get_input_range(5)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.output_state[get_input_range(6)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(5)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); equal_packed_constraint::( - local_values.output_state[get_input_range(7)].try_into().unwrap(), - local_values.input_state[get_input_range(6)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.output_state[get_input_range(7)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(6)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); } fn eval_ext_circuit( &self, builder: &mut CircuitBuilder, vars: &Self::EvaluationFrameTarget, - yield_constr: &mut RecursiveConstraintConsumer + yield_constr: &mut RecursiveConstraintConsumer, ) { let local_values: &[ExtensionTarget; NUM_SHA_COMPRESS_COLUMNS] = vars.get_local_values().try_into().unwrap(); @@ -430,65 +549,100 @@ impl, const D: usize> Stark for ShaCompressSt // check the input binary form for i in 0..256 { let constraint = builder.mul_sub_extension( - local_values.input_state[i], local_values.input_state[i], local_values.input_state[i]); + local_values.input_state[i], + local_values.input_state[i], + local_values.input_state[i], + ); yield_constr.constraint(builder, constraint); - } for i in 0..32 { let constraint = builder.mul_sub_extension( - local_values.w_i[i], local_values.w_i[i], local_values.w_i[i]); + local_values.w_i[i], + local_values.w_i[i], + local_values.w_i[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.k_i[i], local_values.k_i[i], local_values.k_i[i]); + local_values.k_i[i], + local_values.k_i[i], + local_values.k_i[i], + ); yield_constr.constraint(builder, constraint); } // check the bit values are zero or one in output for i in 0..256 { let constraint = builder.mul_sub_extension( - local_values.output_state[i], local_values.output_state[i], local_values.output_state[i]); + local_values.output_state[i], + local_values.output_state[i], + local_values.output_state[i], + ); yield_constr.constraint(builder, constraint); } // check the rotation rotate_right_ext_circuit_constraint( builder, - local_values.input_state[get_input_range(4)].try_into().unwrap(), + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), local_values.e_rr_6, - 6 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 6, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); rotate_right_ext_circuit_constraint( builder, - local_values.input_state[get_input_range(4)].try_into().unwrap(), + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), local_values.e_rr_11, - 11 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 11, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); rotate_right_ext_circuit_constraint( builder, - local_values.input_state[get_input_range(4)].try_into().unwrap(), + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), local_values.e_rr_25, - 25 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 25, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); rotate_right_ext_circuit_constraint( builder, - local_values.input_state[get_input_range(0)].try_into().unwrap(), + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), local_values.a_rr_2, - 2 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 2, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); rotate_right_ext_circuit_constraint( builder, - local_values.input_state[get_input_range(0)].try_into().unwrap(), + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), local_values.a_rr_13, - 13 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 13, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); rotate_right_ext_circuit_constraint( builder, - local_values.input_state[get_input_range(0)].try_into().unwrap(), + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), local_values.a_rr_22, - 22 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 22, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); // check the xor for i in 0..32 { @@ -496,7 +650,7 @@ impl, const D: usize> Stark for ShaCompressSt builder, local_values.e_rr_6[i], local_values.e_rr_11[i], - local_values.e_rr_25[i] + local_values.e_rr_25[i], ); let constraint = builder.sub_extension(local_values.s_1[i], s1); yield_constr.constraint(builder, constraint); @@ -505,7 +659,7 @@ impl, const D: usize> Stark for ShaCompressSt builder, local_values.a_rr_2[i], local_values.a_rr_13[i], - local_values.a_rr_22[i] + local_values.a_rr_22[i], ); let constraint = builder.sub_extension(local_values.s_0[i], s0); yield_constr.constraint(builder, constraint); @@ -513,7 +667,7 @@ impl, const D: usize> Stark for ShaCompressSt let ch = xor_gen_circuit( builder, local_values.e_and_f[i], - local_values.not_e_and_g[i] + local_values.not_e_and_g[i], ); let constraint = builder.sub_extension(local_values.ch[i], ch); yield_constr.constraint(builder, constraint); @@ -522,7 +676,7 @@ impl, const D: usize> Stark for ShaCompressSt builder, local_values.a_and_b[i], local_values.a_and_c[i], - local_values.b_and_c[i] + local_values.b_and_c[i], ); let constraint = builder.sub_extension(local_values.maj[i], maj); yield_constr.constraint(builder, constraint); @@ -532,115 +686,184 @@ impl, const D: usize> Stark for ShaCompressSt wrapping_add_ext_circuit_constraints( builder, - local_values.input_state[get_input_range(7)].try_into().unwrap(), + local_values.input_state[get_input_range(7)] + .try_into() + .unwrap(), local_values.s_1, local_values.carry_1, - local_values.inter_1 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.inter_1, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); wrapping_add_ext_circuit_constraints( builder, local_values.inter_1, local_values.ch, local_values.carry_2, - local_values.inter_2 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.inter_2, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); wrapping_add_ext_circuit_constraints( builder, local_values.inter_2, local_values.k_i, local_values.carry_3, - local_values.inter_3 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.inter_3, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); wrapping_add_ext_circuit_constraints( builder, local_values.inter_3, local_values.w_i, local_values.carry_4, - local_values.temp1 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.temp1, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); wrapping_add_ext_circuit_constraints( builder, local_values.s_0, local_values.maj, local_values.carry_5, - local_values.temp2 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.temp2, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); wrapping_add_ext_circuit_constraints( builder, - local_values.input_state[get_input_range(3)].try_into().unwrap(), + local_values.input_state[get_input_range(3)] + .try_into() + .unwrap(), local_values.temp1, local_values.carry_e, - local_values.output_state[get_input_range(4)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.output_state[get_input_range(4)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); wrapping_add_ext_circuit_constraints( builder, local_values.temp1, local_values.temp2, local_values.carry_a, - local_values.output_state[get_input_range(0)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.output_state[get_input_range(0)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); // The op constraints and_op_ext_circuit_constraints( builder, - local_values.input_state[get_input_range(4)].try_into().unwrap(), - local_values.input_state[get_input_range(5)].try_into().unwrap(), - local_values.e_and_f - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(5)] + .try_into() + .unwrap(), + local_values.e_and_f, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); and_op_ext_circuit_constraints( builder, - local_values.input_state[get_input_range(0)].try_into().unwrap(), - local_values.input_state[get_input_range(1)].try_into().unwrap(), - local_values.a_and_b - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(1)] + .try_into() + .unwrap(), + local_values.a_and_b, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); and_op_ext_circuit_constraints( builder, - local_values.input_state[get_input_range(0)].try_into().unwrap(), - local_values.input_state[get_input_range(2)].try_into().unwrap(), - local_values.a_and_c - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(2)] + .try_into() + .unwrap(), + local_values.a_and_c, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); and_op_ext_circuit_constraints( builder, - local_values.input_state[get_input_range(1)].try_into().unwrap(), - local_values.input_state[get_input_range(2)].try_into().unwrap(), - local_values.b_and_c - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.input_state[get_input_range(1)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(2)] + .try_into() + .unwrap(), + local_values.b_and_c, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); andn_op_ext_circuit_constraints( builder, - local_values.input_state[get_input_range(4)].try_into().unwrap(), - local_values.input_state[get_input_range(6)].try_into().unwrap(), - local_values.not_e_and_g - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); - + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(6)] + .try_into() + .unwrap(), + local_values.not_e_and_g, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); // output constraint equal_ext_circuit_constraints::( builder, - local_values.output_state[get_input_range(1)].try_into().unwrap(), - local_values.input_state[get_input_range(0)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.output_state[get_input_range(1)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(0)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); equal_ext_circuit_constraints::( builder, - local_values.output_state[get_input_range(2)].try_into().unwrap(), - local_values.input_state[get_input_range(1)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.output_state[get_input_range(2)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(1)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); equal_ext_circuit_constraints::( builder, - local_values.output_state[get_input_range(3)].try_into().unwrap(), - local_values.input_state[get_input_range(2)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.output_state[get_input_range(3)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(2)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); // equal_packed_constraint( // local_values.output_state[get_input_range(4)].try_into().unwrap(), @@ -649,21 +872,39 @@ impl, const D: usize> Stark for ShaCompressSt equal_ext_circuit_constraints::( builder, - local_values.output_state[get_input_range(5)].try_into().unwrap(), - local_values.input_state[get_input_range(4)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.output_state[get_input_range(5)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(4)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); equal_ext_circuit_constraints::( builder, - local_values.output_state[get_input_range(6)].try_into().unwrap(), - local_values.input_state[get_input_range(5)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.output_state[get_input_range(6)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(5)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); equal_ext_circuit_constraints::( builder, - local_values.output_state[get_input_range(7)].try_into().unwrap(), - local_values.input_state[get_input_range(6)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.output_state[get_input_range(7)] + .try_into() + .unwrap(), + local_values.input_state[get_input_range(6)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); } fn constraint_degree(&self) -> usize { @@ -673,12 +914,18 @@ impl, const D: usize> Stark for ShaCompressSt #[cfg(test)] mod test { - use plonky2::field::goldilocks_field::GoldilocksField; + use crate::config::StarkConfig; + use crate::cross_table_lookup::{ + Column, CtlData, CtlZData, Filter, GrandProductChallenge, GrandProductChallengeSet, + }; + use crate::prover::prove_single_table; use crate::sha_compress::columns::ShaCompressColumnsView; use crate::sha_compress::sha_compress_stark::{ShaCompressStark, NUM_INPUTS}; + use crate::sha_compress_sponge::constants::SHA_COMPRESS_K; use crate::sha_extend::logic::{from_u32_to_be_bits, get_input_range}; - use std::borrow::Borrow; + use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; + use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::polynomial::PolynomialValues; use plonky2::field::types::Field; use plonky2::fri::oracle::PolynomialBatch; @@ -686,24 +933,22 @@ mod test { use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::timed; use plonky2::util::timing::TimingTree; - use crate::config::StarkConfig; - use crate::cross_table_lookup::{Column, CtlData, CtlZData, Filter, GrandProductChallenge, GrandProductChallengeSet}; - use crate::prover::prove_single_table; - use crate::sha_compress_sponge::constants::SHA_COMPRESS_K; - use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; + use std::borrow::Borrow; + + const W: [u32; 64] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 34013193, 67559435, 1711661200, + 3020350282, 1447362251, 3118632270, 4004188394, 690615167, 6070360, 1105370215, 2385558114, + 2348232513, 507799627, 2098764358, 5845374, 823657968, 2969863067, 3903496557, 4274682881, + 2059629362, 1849247231, 2656047431, 835162919, 2096647516, 2259195856, 1779072524, + 3152121987, 4210324067, 1557957044, 376930560, 982142628, 3926566666, 4164334963, + 789545383, 1028256580, 2867933222, 3843938318, 1135234440, 390334875, 2025924737, + 3318322046, 3436065867, 652746999, 4261492214, 2543173532, 3334668051, 3166416553, + 634956631, + ]; - const W: [u32; 64] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 34013193, - 67559435, 1711661200, 3020350282, 1447362251, 3118632270, 4004188394, 690615167, - 6070360, 1105370215, 2385558114, 2348232513, 507799627, 2098764358, 5845374, 823657968, - 2969863067, 3903496557, 4274682881, 2059629362, 1849247231, 2656047431, 835162919, - 2096647516, 2259195856, 1779072524, 3152121987, 4210324067, 1557957044, 376930560, - 982142628, 3926566666, 4164334963, 789545383, 1028256580, 2867933222, 3843938318, 1135234440, - 390334875, 2025924737, 3318322046, 3436065867, 652746999, 4261492214, 2543173532, 3334668051, - 3166416553, 634956631]; - - pub const H256_256: [u32;8] = [ - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, + pub const H256_256: [u32; 8] = [ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, + 0x5be0cd19, ]; fn get_random_input() -> [u8; NUM_INPUTS] { @@ -716,8 +961,7 @@ mod test { } #[test] - fn test_generation() -> Result<(), String>{ - + fn test_generation() -> Result<(), String> { const D: usize = 2; type F = GoldilocksField; type S = ShaCompressStark; @@ -732,42 +976,65 @@ mod test { input.extend(from_u32_to_be_bits(w[0])); input.extend(from_u32_to_be_bits(SHA_COMPRESS_K[0])); - let stark = S::default(); let row = stark.generate_trace_rows_for_compress((input.try_into().unwrap(), 0)); let local_values: &ShaCompressColumnsView = row.borrow(); assert_eq!( local_values.output_state[get_input_range(0)], - from_u32_to_be_bits(4228417613).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(4228417613) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(1)], - from_u32_to_be_bits(1779033703).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(1779033703) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(2)], - from_u32_to_be_bits(3144134277).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(3144134277) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(3)], - from_u32_to_be_bits(1013904242).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(1013904242) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(4)], - from_u32_to_be_bits(2563236514).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(2563236514) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(5)], - from_u32_to_be_bits(1359893119).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(1359893119) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(6)], - from_u32_to_be_bits(2600822924).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(2600822924) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(7)], - from_u32_to_be_bits(528734635).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(528734635) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); Ok(()) } @@ -869,4 +1136,4 @@ mod test { fn init_logger() { let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); } -} \ No newline at end of file +} diff --git a/prover/src/sha_compress_sponge/columns.rs b/prover/src/sha_compress_sponge/columns.rs index 7485a6a9..74a3e93d 100644 --- a/prover/src/sha_compress_sponge/columns.rs +++ b/prover/src/sha_compress_sponge/columns.rs @@ -1,10 +1,9 @@ +use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; use std::borrow::{Borrow, BorrowMut}; use std::intrinsics::transmute; -use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; pub(crate) struct ShaCompressSpongeColumnsView { - - pub hx: [T;256], + pub hx: [T; 256], pub input_state: [T; 256], pub output_state: [T; 256], pub output_hx: [T; 256], @@ -23,7 +22,6 @@ pub(crate) struct ShaCompressSpongeColumnsView { pub segment: T, } - pub const NUM_SHA_COMPRESS_SPONGE_COLUMNS: usize = size_of::>(); //1420 impl From<[T; NUM_SHA_COMPRESS_SPONGE_COLUMNS]> for ShaCompressSpongeColumnsView { @@ -71,7 +69,9 @@ impl Default for ShaCompressSpongeColumnsView { const fn make_col_map() -> ShaCompressSpongeColumnsView { let indices_arr = indices_arr::(); unsafe { - transmute::<[usize; NUM_SHA_COMPRESS_SPONGE_COLUMNS], ShaCompressSpongeColumnsView>(indices_arr) + transmute::<[usize; NUM_SHA_COMPRESS_SPONGE_COLUMNS], ShaCompressSpongeColumnsView>( + indices_arr, + ) } } diff --git a/prover/src/sha_compress_sponge/constants.rs b/prover/src/sha_compress_sponge/constants.rs index d50bde1f..74c9c1d9 100644 --- a/prover/src/sha_compress_sponge/constants.rs +++ b/prover/src/sha_compress_sponge/constants.rs @@ -13,68 +13,260 @@ pub const NUM_COMPRESS_ROWS: usize = 64; // big-endian form pub const SHA_COMPRESS_K_BINARY: [[u8; 32]; 64] = [ - [0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0], - [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0], - [1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1], - [1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1], - [1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0], - [1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0], - [0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1], - [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1], - [0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1], - [1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0], - [0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0], - [1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0], - [0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0], - [0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1], - [1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1], - [0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1], - [1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1], - [0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1], - [0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0], - [0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0], - [1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0], - [0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0], - [0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0], - [0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0], - [0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1], - [1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1], - [0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1], - [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1], - [1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1], - [1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1], - [1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0], - [1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0], - [1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0], - [0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0], - [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0], - [1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0], - [0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0], - [1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0], - [0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1], - [1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], - [1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1], - [1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1], - [0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1], - [1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1], - [1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1], - [0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1], - [1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1], - [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0], - [0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0], - [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0], - [0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0], - [1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0], - [1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0], - [0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0], - [1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0], - [1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0], - [0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0], - [1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0], - [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1], - [0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1], - [0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1], - [1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1], - [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1], - [0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1], -]; \ No newline at end of file + [ + 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, + 1, 0, + ], + [ + 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, + 1, 0, + ], + [ + 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, + 0, 1, + ], + [ + 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, + 1, 1, + ], + [ + 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, + 0, 0, + ], + [ + 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, + 1, 0, + ], + [ + 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, + 0, 1, + ], + [ + 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, + 0, 1, + ], + [ + 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, + 1, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, + 0, 0, + ], + [ + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, + 0, 0, + ], + [ + 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, + ], + [ + 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, + 1, 0, + ], + [ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 1, + ], + [ + 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, + 0, 1, + ], + [ + 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, + 1, 1, + ], + [ + 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, + 1, 1, + ], + [ + 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, + 1, 1, + ], + [ + 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, + ], + [ + 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, + 0, 0, + ], + [ + 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, + 0, 0, + ], + [ + 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, + 1, 0, + ], + [ + 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, + 1, 0, + ], + [ + 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, + 1, 0, + ], + [ + 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, + 0, 1, + ], + [ + 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, + 0, 1, + ], + [ + 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 0, 1, + ], + [ + 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, + 0, 1, + ], + [ + 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, + 1, 1, + ], + [ + 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, + 1, 1, + ], + [ + 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, + 0, 0, + ], + [ + 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, + 0, 0, + ], + [ + 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, + 0, 0, + ], + [ + 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, + 0, 0, + ], + [ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, + 1, 0, + ], + [ + 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, + 1, 0, + ], + [ + 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, + 1, 0, + ], + [ + 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, + 1, 0, + ], + [ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 1, + ], + [ + 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, + 0, 1, + ], + [ + 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, + 0, 1, + ], + [ + 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, + 0, 1, + ], + [ + 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, + 1, 1, + ], + [ + 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, + 1, 1, + ], + [ + 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, + 1, 1, + ], + [ + 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, + 1, 1, + ], + [ + 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, + 1, 1, + ], + [ + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, + 0, 0, + ], + [ + 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 0, + ], + [ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, + 0, 0, + ], + [ + 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, + 0, 0, + ], + [ + 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, + 0, 0, + ], + [ + 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, + 0, 0, + ], + [ + 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, + 1, 0, + ], + [ + 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, + 1, 0, + ], + [ + 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, + 1, 0, + ], + [ + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, + 1, 0, + ], + [ + 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, + 1, 0, + ], + [ + 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, + 0, 1, + ], + [ + 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, + 0, 1, + ], + [ + 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, + 0, 1, + ], + [ + 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, + 0, 1, + ], + [ + 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 0, 1, + ], + [ + 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, + 1, 1, + ], +]; diff --git a/prover/src/sha_compress_sponge/mod.rs b/prover/src/sha_compress_sponge/mod.rs index c47afc31..d1fb8826 100644 --- a/prover/src/sha_compress_sponge/mod.rs +++ b/prover/src/sha_compress_sponge/mod.rs @@ -1,3 +1,3 @@ pub mod columns; +pub mod constants; pub mod sha_compress_sponge_stark; -pub mod constants; \ No newline at end of file diff --git a/prover/src/sha_compress_sponge/sha_compress_sponge_stark.rs b/prover/src/sha_compress_sponge/sha_compress_sponge_stark.rs index 54465df7..1ec8281b 100644 --- a/prover/src/sha_compress_sponge/sha_compress_sponge_stark.rs +++ b/prover/src/sha_compress_sponge/sha_compress_sponge_stark.rs @@ -1,29 +1,34 @@ -use std::marker::PhantomData; -use std::borrow::Borrow; -use itertools::Itertools; -use plonky2::field::extension::{Extendable, FieldExtension}; -use plonky2::field::packed::PackedField; -use plonky2::field::polynomial::PolynomialValues; -use plonky2::field::types::Field; -use plonky2::hash::hash_types::RichField; -use plonky2::iop::ext_target::ExtensionTarget; -use plonky2::plonk::circuit_builder::CircuitBuilder; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::cross_table_lookup::{Column, Filter}; use crate::evaluation_frame::{StarkEvaluationFrame, StarkFrame}; use crate::memory::segments::Segment; use crate::sha_compress::logic::from_be_bits_to_u32; -use crate::sha_compress_sponge::columns::{ShaCompressSpongeColumnsView, NUM_SHA_COMPRESS_SPONGE_COLUMNS, SHA_COMPRESS_SPONGE_COL_MAP}; +use crate::sha_compress_sponge::columns::{ + ShaCompressSpongeColumnsView, NUM_SHA_COMPRESS_SPONGE_COLUMNS, SHA_COMPRESS_SPONGE_COL_MAP, +}; use crate::sha_compress_sponge::constants::{NUM_COMPRESS_ROWS, SHA_COMPRESS_K_BINARY}; -use crate::sha_extend::logic::{from_u32_to_be_bits, get_input_range, wrapping_add, wrapping_add_ext_circuit_constraints, wrapping_add_packed_constraints}; +use crate::sha_extend::logic::{ + from_u32_to_be_bits, get_input_range, wrapping_add, wrapping_add_ext_circuit_constraints, + wrapping_add_packed_constraints, +}; use crate::stark::Stark; use crate::util::trace_rows_to_poly_values; use crate::witness::memory::MemoryAddress; use crate::witness::operation::SHA_COMPRESS_K; +use itertools::Itertools; +use plonky2::field::extension::{Extendable, FieldExtension}; +use plonky2::field::packed::PackedField; +use plonky2::field::polynomial::PolynomialValues; +use plonky2::field::types::Field; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::ext_target::ExtensionTarget; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use std::borrow::Borrow; +use std::marker::PhantomData; pub(crate) const NUM_ROUNDS: usize = 64; -pub(crate) const SHA_COMPRESS_SPONGE_READ_BITS: usize = 9 * 32; // h[0],...,h[7], w[i]. +pub(crate) const SHA_COMPRESS_SPONGE_READ_BITS: usize = 9 * 32; // h[0],...,h[7], w[i]. pub(crate) fn ctl_looking_sha_compress_inputs() -> Vec> { let cols = SHA_COMPRESS_SPONGE_COL_MAP; let mut res: Vec<_> = Column::singles( @@ -32,9 +37,9 @@ pub(crate) fn ctl_looking_sha_compress_inputs() -> Vec> { cols.w_i.as_slice(), cols.k_i.as_slice(), ] - .concat(), + .concat(), ) - .collect(); + .collect(); res.push(Column::single(cols.timestamp)); res } @@ -62,12 +67,7 @@ pub(crate) fn ctl_looked_data() -> Vec> { outputs.push(cur_col); } - Column::singles([ - cols.context, - cols.segment, - cols.hx_virt[0], - cols.timestamp, - ]) + Column::singles([cols.context, cols.segment, cols.hx_virt[0], cols.timestamp]) .chain(outputs) .collect() } @@ -105,13 +105,10 @@ pub(crate) fn ctl_looking_memory(i: usize) -> Vec> { res } - pub(crate) fn ctl_looking_sha_compress_filter() -> Filter { let cols = SHA_COMPRESS_SPONGE_COL_MAP; // not the padding rows. - Filter::new_simple(Column::sum( - &cols.round, - )) + Filter::new_simple(Column::sum(&cols.round)) } pub(crate) fn ctl_looked_filter() -> Filter { @@ -119,9 +116,7 @@ pub(crate) fn ctl_looked_filter() -> Filter { // compress sponge output. let cols = SHA_COMPRESS_SPONGE_COL_MAP; // the final row only. - Filter::new_simple(Column::single( - cols.round[63], - )) + Filter::new_simple(Column::single(cols.round[63])) } #[derive(Clone, Debug)] @@ -180,31 +175,42 @@ impl, const D: usize> ShaCompressSpongeStark rows } - fn generate_rows_for_op( - &self, - op: ShaCompressSpongeOp, - ) -> ShaCompressSpongeColumnsView { + fn generate_rows_for_op(&self, op: ShaCompressSpongeOp) -> ShaCompressSpongeColumnsView { let mut row = ShaCompressSpongeColumnsView::default(); row.timestamp = F::from_canonical_usize(op.timestamp); row.context = F::from_canonical_usize(op.base_address[0].context); row.segment = F::from_canonical_usize(op.base_address[Segment::Code as usize].segment); - let hx_virt = (0..8) - .map(|i| op.base_address[i].virt) - .collect_vec(); + let hx_virt = (0..8).map(|i| op.base_address[i].virt).collect_vec(); let hx_virt: [usize; 8] = hx_virt.try_into().unwrap(); row.hx_virt = hx_virt.map(F::from_canonical_usize); - let w_virt = op.base_address[8].virt; + let w_virt = op.base_address[8].virt; row.w_virt = F::from_canonical_usize(w_virt); row.round = [F::ZEROS; 64]; row.round[op.i] = F::ONE; row.k_i = SHA_COMPRESS_K_BINARY[op.i].map(|k| F::from_canonical_u8(k)); - row.w_i = op.input[256..288].iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); - row.hx = op.input[..256].iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); - row.input_state = op.input_states.iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + row.w_i = op.input[256..288] + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); + row.hx = op.input[..256] + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); + row.input_state = op + .input_states + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); let output = self.compress(&op.input_states, &op.input[256..288], op.i); row.output_state = output.map(F::from_canonical_u8); @@ -213,10 +219,9 @@ impl, const D: usize> ShaCompressSpongeStark // The computation in other rounds are ensure the constraint degree // not to be exceeded 3. for i in 0..8 { - let (output_hx, carry) = wrapping_add::( row.hx[get_input_range(i)].try_into().unwrap(), - row.output_state[get_input_range(i)].try_into().unwrap() + row.output_state[get_input_range(i)].try_into().unwrap(), ); row.output_hx[get_input_range(i)].copy_from_slice(&output_hx[0..]); @@ -227,14 +232,23 @@ impl, const D: usize> ShaCompressSpongeStark } fn compress(&self, input_state: &[u8], w_i: &[u8], round: usize) -> [u8; 256] { - let values: Vec<[u8; 32]> = input_state.chunks(32).map(|chunk| chunk.try_into().unwrap()).collect(); - let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = values.into_iter().map( - |x| from_be_bits_to_u32(x) - ).collect::>().try_into().unwrap(); + let values: Vec<[u8; 32]> = input_state + .chunks(32) + .map(|chunk| chunk.try_into().unwrap()) + .collect(); + let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = values + .into_iter() + .map(|x| from_be_bits_to_u32(x)) + .collect::>() + .try_into() + .unwrap(); let w_i = from_be_bits_to_u32(w_i.try_into().unwrap()); - let t1 = h.wrapping_add(e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25)) - .wrapping_add((e & f) ^ ((!e) & g)).wrapping_add(SHA_COMPRESS_K[round]).wrapping_add(w_i); + let t1 = h + .wrapping_add(e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25)) + .wrapping_add((e & f) ^ ((!e) & g)) + .wrapping_add(SHA_COMPRESS_K[round]) + .wrapping_add(w_i); let t2 = (a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22)) .wrapping_add((a & b) ^ (a & c) ^ (b & c)); h = g; @@ -262,22 +276,21 @@ impl, const D: usize> ShaCompressSpongeStark impl, const D: usize> Stark for ShaCompressSpongeStark { type EvaluationFrame - = StarkFrame + = StarkFrame where - FE: FieldExtension, - P: PackedField; + FE: FieldExtension, + P: PackedField; type EvaluationFrameTarget = StarkFrame, NUM_SHA_COMPRESS_SPONGE_COLUMNS>; fn eval_packed_generic( &self, vars: &Self::EvaluationFrame, - yield_constr: &mut ConstraintConsumer

+ yield_constr: &mut ConstraintConsumer

, ) where - FE: FieldExtension, - P: PackedField + FE: FieldExtension, + P: PackedField, { - let local_values: &[P; NUM_SHA_COMPRESS_SPONGE_COLUMNS] = vars.get_local_values().try_into().unwrap(); let local_values: &ShaCompressSpongeColumnsView

= local_values.borrow(); @@ -289,7 +302,8 @@ impl, const D: usize> Stark for ShaCompressSp // check the bit values are zero or one in input for i in 0..256 { yield_constr.constraint(local_values.hx[i] * (local_values.hx[i] - P::ONES)); - yield_constr.constraint(local_values.input_state[i] * (local_values.input_state[i] - P::ONES)); + yield_constr + .constraint(local_values.input_state[i] * (local_values.input_state[i] - P::ONES)); } for i in 0..32 { yield_constr.constraint(local_values.w_i[i] * (local_values.w_i[i] - P::ONES)); @@ -298,8 +312,11 @@ impl, const D: usize> Stark for ShaCompressSp // check the bit values are zero or one in output for i in 0..256 { - yield_constr.constraint(local_values.output_state[i] * (local_values.output_state[i] - P::ONES)); - yield_constr.constraint(local_values.output_hx[i] * (local_values.output_hx[i] - P::ONES)); + yield_constr.constraint( + local_values.output_state[i] * (local_values.output_state[i] - P::ONES), + ); + yield_constr + .constraint(local_values.output_hx[i] * (local_values.output_hx[i] - P::ONES)); yield_constr.constraint(local_values.carry[i] * (local_values.carry[i] - P::ONES)); } @@ -318,7 +335,6 @@ impl, const D: usize> Stark for ShaCompressSp .sum::

(); yield_constr.constraint(sum_round_flags * (sum_round_flags - P::ONES)); - // If this is not the final step or a padding row: // the local and next timestamps must match. @@ -336,21 +352,27 @@ impl, const D: usize> Stark for ShaCompressSp // the output state of local row must be the input state of next row for i in 0..256 { yield_constr.constraint( - sum_round_flags * not_final * (next_values.input_state[i] - local_values.output_state[i]) + sum_round_flags + * not_final + * (next_values.input_state[i] - local_values.output_state[i]), ); } // the address of w_i must be increased by 4 yield_constr.constraint( - sum_round_flags * not_final * (next_values.w_virt - local_values.w_virt - FE::from_canonical_u8(4)), + sum_round_flags + * not_final + * (next_values.w_virt - local_values.w_virt - FE::from_canonical_u8(4)), ); - // if not the padding row, the hx address must be a sequence of numbers spaced 4 units apart for i in 0..7 { yield_constr.constraint( - sum_round_flags * (local_values.hx_virt[i + 1] - local_values.hx_virt[i] - FE::from_canonical_u8(4)), + sum_round_flags + * (local_values.hx_virt[i + 1] + - local_values.hx_virt[i] + - FE::from_canonical_u8(4)), ); } @@ -359,7 +381,8 @@ impl, const D: usize> Stark for ShaCompressSp for i in 0..32 { let mut bit_i = P::ZEROS; for j in 0..64 { - bit_i = bit_i + local_values.round[j] * FE::from_canonical_u8(SHA_COMPRESS_K_BINARY[j][i]); + bit_i = bit_i + + local_values.round[j] * FE::from_canonical_u8(SHA_COMPRESS_K_BINARY[j][i]); } yield_constr.constraint(local_values.k_i[i] - bit_i); } @@ -367,23 +390,26 @@ impl, const D: usize> Stark for ShaCompressSp // wrapping add constraints for i in 0..8 { - wrapping_add_packed_constraints::( local_values.hx[get_input_range(i)].try_into().unwrap(), - local_values.output_state[get_input_range(i)].try_into().unwrap(), + local_values.output_state[get_input_range(i)] + .try_into() + .unwrap(), local_values.carry[get_input_range(i)].try_into().unwrap(), - local_values.output_hx[get_input_range(i)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(c)); - + local_values.output_hx[get_input_range(i)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); } - } fn eval_ext_circuit( &self, builder: &mut CircuitBuilder, vars: &Self::EvaluationFrameTarget, - yield_constr: &mut RecursiveConstraintConsumer + yield_constr: &mut RecursiveConstraintConsumer, ) { let local_values: &[ExtensionTarget; NUM_SHA_COMPRESS_SPONGE_COLUMNS] = vars.get_local_values().try_into().unwrap(); @@ -399,44 +425,66 @@ impl, const D: usize> Stark for ShaCompressSp // check the bit values are zero or one in input for i in 0..256 { let constraint = builder.mul_sub_extension( - local_values.hx[i], local_values.hx[i], local_values.hx[i]); + local_values.hx[i], + local_values.hx[i], + local_values.hx[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.input_state[i], local_values.input_state[i], local_values.input_state[i]); + local_values.input_state[i], + local_values.input_state[i], + local_values.input_state[i], + ); yield_constr.constraint(builder, constraint); } for i in 0..32 { let constraint = builder.mul_sub_extension( - local_values.w_i[i], local_values.w_i[i], local_values.w_i[i]); + local_values.w_i[i], + local_values.w_i[i], + local_values.w_i[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.k_i[i], local_values.k_i[i], local_values.k_i[i]); + local_values.k_i[i], + local_values.k_i[i], + local_values.k_i[i], + ); yield_constr.constraint(builder, constraint); - } // check the bit values are zero or one in output for i in 0..256 { - let constraint = builder.mul_sub_extension( - local_values.output_state[i], local_values.output_state[i], local_values.output_state[i]); + local_values.output_state[i], + local_values.output_state[i], + local_values.output_state[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.output_hx[i], local_values.output_hx[i], local_values.output_hx[i]); + local_values.output_hx[i], + local_values.output_hx[i], + local_values.output_hx[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.carry[i], local_values.carry[i], local_values.carry[i]); + local_values.carry[i], + local_values.carry[i], + local_values.carry[i], + ); yield_constr.constraint(builder, constraint); } // check the round for i in 0..NUM_ROUNDS { let constraint = builder.mul_sub_extension( - local_values.round[i], local_values.round[i], local_values.round[i]); + local_values.round[i], + local_values.round[i], + local_values.round[i], + ); yield_constr.constraint(builder, constraint); } @@ -449,12 +497,10 @@ impl, const D: usize> Stark for ShaCompressSp let sum_round_flags = builder.add_many_extension((0..NUM_COMPRESS_ROWS).map(|i| local_values.round[i])); - let constraint = builder.mul_sub_extension( - sum_round_flags, sum_round_flags, sum_round_flags - ); + let constraint = + builder.mul_sub_extension(sum_round_flags, sum_round_flags, sum_round_flags); yield_constr.constraint(builder, constraint); - // If this is not the final step or a padding row: // the local and next timestamps must match. @@ -472,7 +518,8 @@ impl, const D: usize> Stark for ShaCompressSp // the output state of local row must be the input state of next row for i in 0..256 { - let diff = builder.sub_extension(next_values.input_state[i], local_values.output_state[i]); + let diff = + builder.sub_extension(next_values.input_state[i], local_values.output_state[i]); let constraint = builder.mul_many_extension([sum_round_flags, not_final, diff]); yield_constr.constraint(builder, constraint); } @@ -480,31 +527,31 @@ impl, const D: usize> Stark for ShaCompressSp // the address of w_i must be increased by 4 let increment = builder.sub_extension(next_values.w_virt, local_values.w_virt); let address_increment = builder.sub_extension(increment, four_ext); - let constraint = builder.mul_many_extension( - [sum_round_flags, not_final, address_increment] - ); + let constraint = + builder.mul_many_extension([sum_round_flags, not_final, address_increment]); yield_constr.constraint(builder, constraint); - // if not the padding row, the hx address must be a sequence of numbers spaced 4 units apart for i in 0..7 { - let increment = builder.sub_extension(local_values.hx_virt[i + 1], local_values.hx_virt[i]); + let increment = + builder.sub_extension(local_values.hx_virt[i + 1], local_values.hx_virt[i]); let address_increment = builder.sub_extension(increment, four_ext); - let constraint = builder.mul_extension( - sum_round_flags, address_increment - ); + let constraint = builder.mul_extension(sum_round_flags, address_increment); yield_constr.constraint(builder, constraint); } // check the validation of key[i] for i in 0..32 { - - let bit_i_comp: Vec<_> = (0..64).map(|j| { - let k_j_i = builder.constant_extension(F::Extension::from_canonical_u8(SHA_COMPRESS_K_BINARY[j][i])); - builder.mul_extension(local_values.round[j], k_j_i) - }).collect(); + let bit_i_comp: Vec<_> = (0..64) + .map(|j| { + let k_j_i = builder.constant_extension(F::Extension::from_canonical_u8( + SHA_COMPRESS_K_BINARY[j][i], + )); + builder.mul_extension(local_values.round[j], k_j_i) + }) + .collect(); let bit_i = builder.add_many_extension(bit_i_comp); let constraint = builder.sub_extension(local_values.k_i[i], bit_i); yield_constr.constraint(builder, constraint); @@ -516,11 +563,16 @@ impl, const D: usize> Stark for ShaCompressSp wrapping_add_ext_circuit_constraints::( builder, local_values.hx[get_input_range(i)].try_into().unwrap(), - local_values.output_state[get_input_range(i)].try_into().unwrap(), + local_values.output_state[get_input_range(i)] + .try_into() + .unwrap(), local_values.carry[get_input_range(i)].try_into().unwrap(), - local_values.output_hx[get_input_range(i)].try_into().unwrap(), - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); - + local_values.output_hx[get_input_range(i)] + .try_into() + .unwrap(), + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); } } @@ -529,41 +581,45 @@ impl, const D: usize> Stark for ShaCompressSp } } - #[cfg(test)] mod test { - use plonky2::field::goldilocks_field::GoldilocksField; - use plonky2::field::types::{Field}; - use std::borrow::Borrow; + use crate::config::StarkConfig; + use crate::cross_table_lookup::{ + Column, CtlData, CtlZData, Filter, GrandProductChallenge, GrandProductChallengeSet, + }; + use crate::prover::prove_single_table; + use crate::sha_compress_sponge::columns::ShaCompressSpongeColumnsView; + use crate::sha_compress_sponge::sha_compress_sponge_stark::{ + ShaCompressSpongeOp, ShaCompressSpongeStark, + }; + use crate::sha_extend::logic::{from_u32_to_be_bits, get_input_range}; + use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; + use crate::witness::memory::MemoryAddress; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; + use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::polynomial::PolynomialValues; + use plonky2::field::types::Field; use plonky2::fri::oracle::PolynomialBatch; use plonky2::iop::challenger::Challenger; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::timed; use plonky2::util::timing::TimingTree; - use crate::config::StarkConfig; - use crate::cross_table_lookup::{Column, CtlData, CtlZData, Filter, GrandProductChallenge, GrandProductChallengeSet}; - use crate::prover::prove_single_table; - use crate::sha_compress_sponge::columns::ShaCompressSpongeColumnsView; - use crate::sha_compress_sponge::sha_compress_sponge_stark::{ShaCompressSpongeOp, ShaCompressSpongeStark}; - use crate::sha_extend::logic::{from_u32_to_be_bits, get_input_range}; - use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; - use crate::witness::memory::MemoryAddress; - + use std::borrow::Borrow; - const W: [u32; 64] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 34013193, - 67559435, 1711661200, 3020350282, 1447362251, 3118632270, 4004188394, 690615167, - 6070360, 1105370215, 2385558114, 2348232513, 507799627, 2098764358, 5845374, 823657968, - 2969863067, 3903496557, 4274682881, 2059629362, 1849247231, 2656047431, 835162919, - 2096647516, 2259195856, 1779072524, 3152121987, 4210324067, 1557957044, 376930560, - 982142628, 3926566666, 4164334963, 789545383, 1028256580, 2867933222, 3843938318, 1135234440, - 390334875, 2025924737, 3318322046, 3436065867, 652746999, 4261492214, 2543173532, 3334668051, - 3166416553, 634956631]; + const W: [u32; 64] = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 34013193, 67559435, 1711661200, + 3020350282, 1447362251, 3118632270, 4004188394, 690615167, 6070360, 1105370215, 2385558114, + 2348232513, 507799627, 2098764358, 5845374, 823657968, 2969863067, 3903496557, 4274682881, + 2059629362, 1849247231, 2656047431, 835162919, 2096647516, 2259195856, 1779072524, + 3152121987, 4210324067, 1557957044, 376930560, 982142628, 3926566666, 4164334963, + 789545383, 1028256580, 2867933222, 3843938318, 1135234440, 390334875, 2025924737, + 3318322046, 3436065867, 652746999, 4261492214, 2543173532, 3334668051, 3166416553, + 634956631, + ]; - pub const H256_256: [u32;8] = [ - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, + pub const H256_256: [u32; 8] = [ + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, + 0x5be0cd19, ]; #[test] fn test_generation() -> Result<(), String> { @@ -573,26 +629,40 @@ mod test { type S = ShaCompressSpongeStark; let stark = S::default(); - let hx_addresses: Vec = (0..32).step_by(4).map(|i| { - MemoryAddress { + let hx_addresses: Vec = (0..32) + .step_by(4) + .map(|i| MemoryAddress { context: 0, segment: 0, virt: i, - } - }).collect(); + }) + .collect(); - let w_addresses: Vec = (32..288).step_by(4).map(|i| { - MemoryAddress { + let w_addresses: Vec = (32..288) + .step_by(4) + .map(|i| MemoryAddress { context: 0, segment: 0, virt: i, - } - }).collect(); - let mut input = H256_256.iter().map(|x| from_u32_to_be_bits(*x)).flatten().collect::>(); + }) + .collect(); + let mut input = H256_256 + .iter() + .map(|x| from_u32_to_be_bits(*x)) + .flatten() + .collect::>(); input.extend(from_u32_to_be_bits(W[0])); - let input_state = H256_256.iter().map(|x| from_u32_to_be_bits(*x)).flatten().collect::>(); + let input_state = H256_256 + .iter() + .map(|x| from_u32_to_be_bits(*x)) + .flatten() + .collect::>(); let op = ShaCompressSpongeOp { - base_address: hx_addresses.iter().chain([w_addresses[0]].iter()).cloned().collect(), + base_address: hx_addresses + .iter() + .chain([w_addresses[0]].iter()) + .cloned() + .collect(), i: 0, timestamp: 0, input_states: input_state, @@ -603,42 +673,78 @@ mod test { assert_eq!( local_values.output_state[get_input_range(0)], - from_u32_to_be_bits(4228417613).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(4228417613) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(1)], - from_u32_to_be_bits(1779033703).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(1779033703) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(2)], - from_u32_to_be_bits(3144134277).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(3144134277) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(3)], - from_u32_to_be_bits(1013904242).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(1013904242) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(4)], - from_u32_to_be_bits(2563236514).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(2563236514) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(5)], - from_u32_to_be_bits(1359893119).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(1359893119) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(6)], - from_u32_to_be_bits(2600822924).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(2600822924) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_state[get_input_range(7)], - from_u32_to_be_bits(528734635).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(528734635) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); - let mut input = H256_256.iter().map(|x| from_u32_to_be_bits(*x)).flatten().collect::>(); + let mut input = H256_256 + .iter() + .map(|x| from_u32_to_be_bits(*x)) + .flatten() + .collect::>(); input.extend(from_u32_to_be_bits(W[63])); - let input_state = H256_256.iter().map(|x| from_u32_to_be_bits(*x)).flatten().collect::>(); + let input_state = H256_256 + .iter() + .map(|x| from_u32_to_be_bits(*x)) + .flatten() + .collect::>(); let op = ShaCompressSpongeOp { - base_address: hx_addresses.iter().chain([w_addresses[0]].iter()).cloned().collect(), + base_address: hx_addresses + .iter() + .chain([w_addresses[0]].iter()) + .cloned() + .collect(), i: 63, timestamp: 0, input_states: input_state, @@ -647,43 +753,65 @@ mod test { let row = stark.generate_rows_for_op(op); let local_values: &ShaCompressSpongeColumnsView = row.borrow(); - assert_eq!( local_values.output_hx[get_input_range(0)], - from_u32_to_be_bits(H256_256[0].wrapping_add(2781379838 as u32)).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(H256_256[0].wrapping_add(2781379838 as u32)) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_hx[get_input_range(1)], - from_u32_to_be_bits(H256_256[1].wrapping_add(1779033703 as u32)).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(H256_256[1].wrapping_add(1779033703 as u32)) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_hx[get_input_range(2)], - from_u32_to_be_bits(H256_256[2].wrapping_add(3144134277 as u32)).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(H256_256[2].wrapping_add(3144134277 as u32)) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_hx[get_input_range(3)], - from_u32_to_be_bits(H256_256[3].wrapping_add(1013904242 as u32)).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(H256_256[3].wrapping_add(1013904242 as u32)) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_hx[get_input_range(4)], - from_u32_to_be_bits(H256_256[4].wrapping_add(1116198739 as u32)).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(H256_256[4].wrapping_add(1116198739 as u32)) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_hx[get_input_range(5)], - from_u32_to_be_bits(H256_256[5].wrapping_add(1359893119 as u32)).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(H256_256[5].wrapping_add(1359893119 as u32)) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_hx[get_input_range(6)], - from_u32_to_be_bits(H256_256[6].wrapping_add(2600822924 as u32)).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(H256_256[6].wrapping_add(2600822924 as u32)) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); assert_eq!( local_values.output_hx[get_input_range(7)], - from_u32_to_be_bits(H256_256[7].wrapping_add(528734635 as u32)).iter().map(|&x| F::from_canonical_u8(x)).collect::>() + from_u32_to_be_bits(H256_256[7].wrapping_add(528734635 as u32)) + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() ); Ok(()) } - #[test] fn test_stark_circuit() -> anyhow::Result<()> { const D: usize = 2; @@ -708,42 +836,55 @@ mod test { test_stark_low_degree(stark) } - fn get_random_input() -> Vec { - const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; type S = ShaCompressSpongeStark; let stark = S::default(); - let hx_addresses: Vec = (0..32).step_by(4).map(|i| { - MemoryAddress { + let hx_addresses: Vec = (0..32) + .step_by(4) + .map(|i| MemoryAddress { context: 0, segment: 0, virt: i, - } - }).collect(); + }) + .collect(); - let w_addresses: Vec = (32..288).step_by(4).map(|i| { - MemoryAddress { + let w_addresses: Vec = (32..288) + .step_by(4) + .map(|i| MemoryAddress { context: 0, segment: 0, virt: i, - } - }).collect(); + }) + .collect(); let mut res = vec![]; - let mut output_state = H256_256.iter().map(|x| from_u32_to_be_bits(*x)).flatten().collect::>(); + let mut output_state = H256_256 + .iter() + .map(|x| from_u32_to_be_bits(*x)) + .flatten() + .collect::>(); for i in 0..64 { - - let mut input = H256_256.iter().map(|x| from_u32_to_be_bits(*x)).flatten().collect::>(); + let mut input = H256_256 + .iter() + .map(|x| from_u32_to_be_bits(*x)) + .flatten() + .collect::>(); input.extend(from_u32_to_be_bits(W[i])); let input_state = output_state.clone(); - output_state = stark.compress(&input_state, &from_u32_to_be_bits(W[i]), i).to_vec(); + output_state = stark + .compress(&input_state, &from_u32_to_be_bits(W[i]), i) + .to_vec(); let op = ShaCompressSpongeOp { - base_address: hx_addresses.iter().chain([w_addresses[i]].iter()).cloned().collect(), + base_address: hx_addresses + .iter() + .chain([w_addresses[i]].iter()) + .cloned() + .collect(), i: i, timestamp: 0, input_states: input_state, @@ -754,7 +895,6 @@ mod test { } res - } #[test] fn sha_extend_sponge_benchmark() -> anyhow::Result<()> { @@ -824,5 +964,4 @@ mod test { fn init_logger() { let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); } - -} \ No newline at end of file +} diff --git a/prover/src/sha_extend/columns.rs b/prover/src/sha_extend/columns.rs index 4d3982f6..e81c4ddd 100644 --- a/prover/src/sha_extend/columns.rs +++ b/prover/src/sha_extend/columns.rs @@ -1,9 +1,8 @@ +use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; use std::borrow::{Borrow, BorrowMut}; use std::intrinsics::transmute; -use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; pub(crate) struct ShaExtendColumnsView { - /// Input in big-endian order pub w_i_minus_15: [T; 32], pub w_i_minus_2: [T; 32], @@ -83,4 +82,3 @@ const fn make_col_map() -> ShaExtendColumnsView { } pub(crate) const SHA_EXTEND_COL_MAP: ShaExtendColumnsView = make_col_map(); - diff --git a/prover/src/sha_extend/logic.rs b/prover/src/sha_extend/logic.rs index eab8f703..45db7f9d 100644 --- a/prover/src/sha_extend/logic.rs +++ b/prover/src/sha_extend/logic.rs @@ -5,14 +5,15 @@ use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; use plonky2::plonk::circuit_builder::CircuitBuilder; - pub(crate) fn get_input_range(i: usize) -> std::ops::Range { (0 + i * 32)..(32 + i * 32) } - // these operators are applied in big-endian form -pub(crate) fn rotate_right, const D: usize>(value: [F; 32], amount: usize) -> [F; 32] { +pub(crate) fn rotate_right, const D: usize>( + value: [F; 32], + amount: usize, +) -> [F; 32] { let mut result = [F::ZERO; 32]; for i in 0..32 { result[i] = value[(i + amount) % 32]; @@ -22,7 +23,7 @@ pub(crate) fn rotate_right, const D: usize>(value: pub(crate) fn rotate_right_packed_constraints( value: [P; 32], - rotated_value: [P;32], + rotated_value: [P; 32], amount: usize, ) -> Vec

{ let mut result = Vec::new(); @@ -34,9 +35,9 @@ pub(crate) fn rotate_right_packed_constraints( pub(crate) fn rotate_right_ext_circuit_constraint, const D: usize>( builder: &mut CircuitBuilder, - value: [ExtensionTarget;32], + value: [ExtensionTarget; 32], rotated_value: [ExtensionTarget; 32], - amount: usize + amount: usize, ) -> Vec> { let mut result = Vec::new(); for i in 0..32 { @@ -45,7 +46,10 @@ pub(crate) fn rotate_right_ext_circuit_constraint, result } -pub(crate) fn shift_right, const D: usize>(value: [F; 32], amount: usize) -> [F; 32] { +pub(crate) fn shift_right, const D: usize>( + value: [F; 32], + amount: usize, +) -> [F; 32] { let mut result = [F::ZERO; 32]; if amount < 32 { for i in 0..32 - amount { @@ -57,7 +61,7 @@ pub(crate) fn shift_right, const D: usize>(value: [ pub(crate) fn shift_right_packed_constraints( value: [P; 32], - shifted_value: [P;32], + shifted_value: [P; 32], amount: usize, ) -> Vec

{ let mut result = Vec::new(); @@ -72,9 +76,9 @@ pub(crate) fn shift_right_packed_constraints( pub(crate) fn shift_right_ext_circuit_constraints, const D: usize>( builder: &mut CircuitBuilder, - value: [ExtensionTarget;32], + value: [ExtensionTarget; 32], shifted_value: [ExtensionTarget; 32], - amount: usize + amount: usize, ) -> Vec> { let mut result = Vec::new(); for i in 0..32 - amount { @@ -86,7 +90,11 @@ pub(crate) fn shift_right_ext_circuit_constraints, result } -pub(crate) fn xor3 , const D: usize, const N: usize>(a: [F; N], b: [F; N], c: [F; N]) -> [F; N] { +pub(crate) fn xor3, const D: usize, const N: usize>( + a: [F; N], + b: [F; N], + c: [F; N], +) -> [F; N] { let mut result = [F::ZERO; N]; for i in 0..N { result[i] = crate::keccak::logic::xor([a[i], b[i], c[i]]); @@ -96,7 +104,7 @@ pub(crate) fn xor3 , const D: usize, const N: usize pub(crate) fn wrapping_add, const D: usize, const N: usize>( a: [F; N], - b: [F; N] + b: [F; N], ) -> ([F; N], [F; N]) { let mut result = [F::ZERO; N]; let mut carries = [F::ZERO; N]; @@ -115,7 +123,9 @@ pub(crate) fn wrapping_add, const D: usize, const N (result, carries) } -pub(crate) fn from_be_fbits_to_u32, const D: usize>(value: [F; 32]) -> u32 { +pub(crate) fn from_be_fbits_to_u32, const D: usize>( + value: [F; 32], +) -> u32 { let mut result = 0; for i in 0..32 { debug_assert!(value[i].is_zero() || value[i].is_one()); @@ -137,9 +147,8 @@ pub(crate) fn wrapping_add_packed_constraints( x: [P; N], y: [P; N], carry: [P; N], - out: [P; N] + out: [P; N], ) -> Vec

{ - let mut result = vec![]; let mut pre_carry = P::ZEROS; for i in 0..N { @@ -156,16 +165,19 @@ pub(crate) fn wrapping_add_packed_constraints( result } -pub(crate) fn wrapping_add_ext_circuit_constraints, const D: usize, const N: usize>( +pub(crate) fn wrapping_add_ext_circuit_constraints< + F: RichField + Extendable, + const D: usize, + const N: usize, +>( builder: &mut CircuitBuilder, x: [ExtensionTarget; N], y: [ExtensionTarget; N], carry: [ExtensionTarget; N], - out: [ExtensionTarget; N] + out: [ExtensionTarget; N], ) -> Vec> { - let mut result = vec![]; - let mut pre_carry= builder.zero_extension(); + let mut pre_carry = builder.zero_extension(); let one_ext = builder.one_extension(); let two_ext = builder.two_extension(); let three_ext = builder.constant_extension(F::Extension::from_canonical_u8(3)); @@ -174,23 +186,17 @@ pub(crate) fn wrapping_add_ext_circuit_constraints, let inner_1 = builder.sub_extension(sum, one_ext); let inner_2 = builder.sub_extension(sum, three_ext); - let tmp1 = builder.mul_many_extension( - [inner_1, inner_2, out[i]] - ); + let tmp1 = builder.mul_many_extension([inner_1, inner_2, out[i]]); let inner_1 = builder.sub_extension(sum, two_ext); let inner_2 = builder.sub_extension(out[i], one_ext); - let tmp2 = builder.mul_many_extension( - [sum, inner_1, inner_2] - ); + let tmp2 = builder.mul_many_extension([sum, inner_1, inner_2]); result.push(builder.add_extension(tmp1, tmp2)); - let tmp3 = builder.add_many_extension( - [carry[i], carry[i], out[i]] - ); + let tmp3 = builder.add_many_extension([carry[i], carry[i], out[i]]); result.push(builder.sub_extension(tmp3, sum)); pre_carry = carry[i]; } result -} \ No newline at end of file +} diff --git a/prover/src/sha_extend/mod.rs b/prover/src/sha_extend/mod.rs index 8fb26d6f..a7cb89b8 100644 --- a/prover/src/sha_extend/mod.rs +++ b/prover/src/sha_extend/mod.rs @@ -1,3 +1,3 @@ pub mod columns; +pub mod logic; pub mod sha_extend_stark; -pub mod logic; \ No newline at end of file diff --git a/prover/src/sha_extend/sha_extend_stark.rs b/prover/src/sha_extend/sha_extend_stark.rs index 2165ee7b..8b5decc7 100644 --- a/prover/src/sha_extend/sha_extend_stark.rs +++ b/prover/src/sha_extend/sha_extend_stark.rs @@ -1,5 +1,18 @@ -use std::borrow::Borrow; -use std::marker::PhantomData; +use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; +use crate::cross_table_lookup::{Column, Filter}; +use crate::evaluation_frame::{StarkEvaluationFrame, StarkFrame}; +use crate::keccak::logic::{xor3_gen, xor3_gen_circuit}; +use crate::sha_extend::columns::{ + ShaExtendColumnsView, NUM_SHA_EXTEND_COLUMNS, SHA_EXTEND_COL_MAP, +}; +use crate::sha_extend::logic::{ + get_input_range, rotate_right, rotate_right_ext_circuit_constraint, + rotate_right_packed_constraints, shift_right, shift_right_ext_circuit_constraints, + shift_right_packed_constraints, wrapping_add, wrapping_add_ext_circuit_constraints, + wrapping_add_packed_constraints, xor3, +}; +use crate::stark::Stark; +use crate::util::trace_rows_to_poly_values; use plonky2::field::extension::{Extendable, FieldExtension}; use plonky2::field::packed::PackedField; use plonky2::field::polynomial::PolynomialValues; @@ -7,14 +20,8 @@ use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; use plonky2::plonk::circuit_builder::CircuitBuilder; -use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; -use crate::cross_table_lookup::{Column, Filter}; -use crate::evaluation_frame::{StarkEvaluationFrame, StarkFrame}; -use crate::keccak::logic::{xor3_gen, xor3_gen_circuit}; -use crate::sha_extend::columns::{ShaExtendColumnsView, NUM_SHA_EXTEND_COLUMNS, SHA_EXTEND_COL_MAP}; -use crate::sha_extend::logic::{get_input_range, rotate_right, rotate_right_ext_circuit_constraint, rotate_right_packed_constraints, shift_right, shift_right_ext_circuit_constraints, shift_right_packed_constraints, wrapping_add, wrapping_add_ext_circuit_constraints, wrapping_add_packed_constraints, xor3}; -use crate::stark::Stark; -use crate::util::trace_rows_to_poly_values; +use std::borrow::Borrow; +use std::marker::PhantomData; pub const NUM_INPUTS: usize = 4 * 32; // w_i_minus_15, w_i_minus_2, w_i_minus_16, w_i_minus_7 @@ -27,9 +34,9 @@ pub fn ctl_data_inputs() -> Vec> { cols.w_i_minus_16.as_slice(), cols.w_i_minus_7.as_slice(), ] - .concat(), + .concat(), ) - .collect(); + .collect(); res.push(Column::single(cols.timestamp)); res } @@ -52,7 +59,6 @@ pub fn ctl_filter_outputs() -> Filter { Filter::new_simple(Column::single(cols.is_normal_round)) } - #[derive(Copy, Clone, Default)] pub struct ShaExtendStark { pub(crate) f: PhantomData, @@ -74,8 +80,10 @@ impl, const D: usize> ShaExtendStark { inputs_and_timestamps: Vec<([u8; NUM_INPUTS], usize)>, min_rows: usize, ) -> Vec<[F; NUM_SHA_EXTEND_COLUMNS]> { - let num_rows = inputs_and_timestamps.len() - .max(min_rows).next_power_of_two(); + let num_rows = inputs_and_timestamps + .len() + .max(min_rows) + .next_power_of_two(); let mut rows = Vec::with_capacity(num_rows); for input_and_timestamp in inputs_and_timestamps.iter() { @@ -99,13 +107,29 @@ impl, const D: usize> ShaExtendStark { row.timestamp = F::from_canonical_usize(input_and_timestamp.1); row.w_i_minus_15 = input_and_timestamp.0[get_input_range(0)] - .iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); row.w_i_minus_2 = input_and_timestamp.0[get_input_range(1)] - .iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); row.w_i_minus_16 = input_and_timestamp.0[get_input_range(2)] - .iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); row.w_i_minus_7 = input_and_timestamp.0[get_input_range(3)] - .iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); row.is_normal_round = F::ONE; self.generate_trace_row_for_round(&mut row); row @@ -117,14 +141,22 @@ impl, const D: usize> ShaExtendStark { row.w_i_minus_15_rs_3 = shift_right(row.w_i_minus_15, 3); // s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3) - row.s_0 = xor3(row.w_i_minus_15_rr_7, row.w_i_minus_15_rr_18, row.w_i_minus_15_rs_3); + row.s_0 = xor3( + row.w_i_minus_15_rr_7, + row.w_i_minus_15_rr_18, + row.w_i_minus_15_rs_3, + ); row.w_i_minus_2_rr_17 = rotate_right(row.w_i_minus_2, 17); row.w_i_minus_2_rr_19 = rotate_right(row.w_i_minus_2, 19); row.w_i_minus_2_rs_10 = shift_right(row.w_i_minus_2, 10); // s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10) - row.s_1 = xor3(row.w_i_minus_2_rr_17, row.w_i_minus_2_rr_19, row.w_i_minus_2_rs_10); + row.s_1 = xor3( + row.w_i_minus_2_rr_17, + row.w_i_minus_2_rr_19, + row.w_i_minus_2_rs_10, + ); // (w_i_inter_0, carry) = w[i-7] + s1. (row.w_i_inter_0, row.carry_0) = wrapping_add(row.w_i_minus_7, row.s_1); @@ -134,23 +166,22 @@ impl, const D: usize> ShaExtendStark { } } - impl, const D: usize> Stark for ShaExtendStark { type EvaluationFrame - = StarkFrame + = StarkFrame where - FE: FieldExtension, - P: PackedField; + FE: FieldExtension, + P: PackedField; - type EvaluationFrameTarget = StarkFrame, NUM_SHA_EXTEND_COLUMNS>; + type EvaluationFrameTarget = StarkFrame, NUM_SHA_EXTEND_COLUMNS>; fn eval_packed_generic( &self, vars: &Self::EvaluationFrame, - yield_constr: &mut ConstraintConsumer

+ yield_constr: &mut ConstraintConsumer

, ) where - FE: FieldExtension, - P: PackedField + FE: FieldExtension, + P: PackedField, { let local_values: &[P; NUM_SHA_EXTEND_COLUMNS] = vars.get_local_values().try_into().unwrap(); @@ -158,16 +189,24 @@ impl, const D: usize> Stark for ShaExtendStar // check the bit values are zero or one in input for i in 0..32 { - yield_constr.constraint(local_values.w_i_minus_15[i] * (local_values.w_i_minus_15[i] - P::ONES)); - yield_constr.constraint(local_values.w_i_minus_2[i] * (local_values.w_i_minus_2[i] - P::ONES)); - yield_constr.constraint(local_values.w_i_minus_16[i] * (local_values.w_i_minus_16[i] - P::ONES)); - yield_constr.constraint(local_values.w_i_minus_7[i] * (local_values.w_i_minus_7[i] - P::ONES)); + yield_constr.constraint( + local_values.w_i_minus_15[i] * (local_values.w_i_minus_15[i] - P::ONES), + ); + yield_constr + .constraint(local_values.w_i_minus_2[i] * (local_values.w_i_minus_2[i] - P::ONES)); + yield_constr.constraint( + local_values.w_i_minus_16[i] * (local_values.w_i_minus_16[i] - P::ONES), + ); + yield_constr + .constraint(local_values.w_i_minus_7[i] * (local_values.w_i_minus_7[i] - P::ONES)); } // check the bit values are zero or one in intermediate values for i in 0..32 { - yield_constr.constraint(local_values.w_i_inter_0[i] * (local_values.w_i_inter_0[i] - P::ONES)); - yield_constr.constraint(local_values.w_i_inter_1[i] * (local_values.w_i_inter_1[i] - P::ONES)); + yield_constr + .constraint(local_values.w_i_inter_0[i] * (local_values.w_i_inter_0[i] - P::ONES)); + yield_constr + .constraint(local_values.w_i_inter_1[i] * (local_values.w_i_inter_1[i] - P::ONES)); yield_constr.constraint(local_values.carry_0[i] * (local_values.carry_0[i] - P::ONES)); yield_constr.constraint(local_values.carry_1[i] * (local_values.carry_1[i] - P::ONES)); yield_constr.constraint(local_values.carry_2[i] * (local_values.carry_2[i] - P::ONES)); @@ -182,51 +221,62 @@ impl, const D: usize> Stark for ShaExtendStar rotate_right_packed_constraints( local_values.w_i_minus_15, local_values.w_i_minus_15_rr_7, - 7 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 7, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); rotate_right_packed_constraints( local_values.w_i_minus_15, local_values.w_i_minus_15_rr_18, - 18 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 18, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); rotate_right_packed_constraints( local_values.w_i_minus_2, local_values.w_i_minus_2_rr_17, - 17 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 17, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); rotate_right_packed_constraints( local_values.w_i_minus_2, local_values.w_i_minus_2_rr_19, - 19 - ).into_iter().for_each(|c| yield_constr.constraint(c)); - + 19, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); // check the shift shift_right_packed_constraints( local_values.w_i_minus_15, local_values.w_i_minus_15_rs_3, - 3 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + 3, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); shift_right_packed_constraints( local_values.w_i_minus_2, local_values.w_i_minus_2_rs_10, - 10 - ).into_iter().for_each(|c| yield_constr.constraint(c)); - + 10, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); // check the computation of s0 and s1 for i in 0..32 { - let s0 = xor3_gen(local_values.w_i_minus_15_rr_7[i], - local_values.w_i_minus_15_rr_18[i], - local_values.w_i_minus_15_rs_3[i] + let s0 = xor3_gen( + local_values.w_i_minus_15_rr_7[i], + local_values.w_i_minus_15_rr_18[i], + local_values.w_i_minus_15_rs_3[i], ); yield_constr.constraint(local_values.s_0[i] - s0); let s1 = xor3_gen( local_values.w_i_minus_2_rr_17[i], local_values.w_i_minus_2_rr_19[i], - local_values.w_i_minus_2_rs_10[i] + local_values.w_i_minus_2_rs_10[i], ); yield_constr.constraint(local_values.s_1[i] - s1); } @@ -236,33 +286,38 @@ impl, const D: usize> Stark for ShaExtendStar local_values.w_i_minus_7, local_values.s_1, local_values.carry_0, - local_values.w_i_inter_0 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.w_i_inter_0, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); // check the computation of w_i_inter_1 = w_i_inter_0 + s0 wrapping_add_packed_constraints( local_values.w_i_inter_0, local_values.s_0, local_values.carry_1, - local_values.w_i_inter_1 - ).into_iter().for_each(|c| yield_constr.constraint(c)); + local_values.w_i_inter_1, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); // check the computation of w_i = w_i_inter_1 + w_i_minus_16 wrapping_add_packed_constraints( local_values.w_i_inter_1, local_values.w_i_minus_16, local_values.carry_2, - local_values.w_i - ).into_iter().for_each(|c| yield_constr.constraint(c)); - + local_values.w_i, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(c)); } fn eval_ext_circuit( &self, builder: &mut CircuitBuilder, vars: &Self::EvaluationFrameTarget, - yield_constr: &mut RecursiveConstraintConsumer) { - + yield_constr: &mut RecursiveConstraintConsumer, + ) { let local_values: &[ExtensionTarget; NUM_SHA_EXTEND_COLUMNS] = vars.get_local_values().try_into().unwrap(); let local_values: &ShaExtendColumnsView> = local_values.borrow(); @@ -270,49 +325,79 @@ impl, const D: usize> Stark for ShaExtendStar // check the bit values are zero or one in input for i in 0..32 { let constraint = builder.mul_sub_extension( - local_values.w_i_minus_15[i], local_values.w_i_minus_15[i], local_values.w_i_minus_15[i]); + local_values.w_i_minus_15[i], + local_values.w_i_minus_15[i], + local_values.w_i_minus_15[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.w_i_minus_2[i], local_values.w_i_minus_2[i], local_values.w_i_minus_2[i]); + local_values.w_i_minus_2[i], + local_values.w_i_minus_2[i], + local_values.w_i_minus_2[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.w_i_minus_16[i], local_values.w_i_minus_16[i], local_values.w_i_minus_16[i]); + local_values.w_i_minus_16[i], + local_values.w_i_minus_16[i], + local_values.w_i_minus_16[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.w_i_minus_7[i], local_values.w_i_minus_7[i], local_values.w_i_minus_7[i]); + local_values.w_i_minus_7[i], + local_values.w_i_minus_7[i], + local_values.w_i_minus_7[i], + ); yield_constr.constraint(builder, constraint); } // check the bit values are zero or one in intermediate values for i in 0..32 { let constraint = builder.mul_sub_extension( - local_values.w_i_inter_0[i], local_values.w_i_inter_0[i], local_values.w_i_inter_0[i]); + local_values.w_i_inter_0[i], + local_values.w_i_inter_0[i], + local_values.w_i_inter_0[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.w_i_inter_1[i], local_values.w_i_inter_1[i], local_values.w_i_inter_1[i]); + local_values.w_i_inter_1[i], + local_values.w_i_inter_1[i], + local_values.w_i_inter_1[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.carry_0[i], local_values.carry_0[i], local_values.carry_0[i]); + local_values.carry_0[i], + local_values.carry_0[i], + local_values.carry_0[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.carry_1[i], local_values.carry_1[i], local_values.carry_1[i]); + local_values.carry_1[i], + local_values.carry_1[i], + local_values.carry_1[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.carry_2[i], local_values.carry_2[i], local_values.carry_2[i]); + local_values.carry_2[i], + local_values.carry_2[i], + local_values.carry_2[i], + ); yield_constr.constraint(builder, constraint); } // check the bit values are zero or one in output for i in 0..32 { let constraint = builder.mul_sub_extension( - local_values.w_i[i], local_values.w_i[i], local_values.w_i[i]); + local_values.w_i[i], + local_values.w_i[i], + local_values.w_i[i], + ); yield_constr.constraint(builder, constraint); } @@ -321,41 +406,53 @@ impl, const D: usize> Stark for ShaExtendStar builder, local_values.w_i_minus_15, local_values.w_i_minus_15_rr_7, - 7 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 7, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); rotate_right_ext_circuit_constraint( builder, local_values.w_i_minus_15, local_values.w_i_minus_15_rr_18, - 18 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 18, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); rotate_right_ext_circuit_constraint( builder, local_values.w_i_minus_2, local_values.w_i_minus_2_rr_17, - 17 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 17, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); rotate_right_ext_circuit_constraint( builder, local_values.w_i_minus_2, local_values.w_i_minus_2_rr_19, - 19 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 19, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); // check the shift shift_right_ext_circuit_constraints( builder, local_values.w_i_minus_15, local_values.w_i_minus_15_rs_3, - 3 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 3, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); shift_right_ext_circuit_constraints( builder, local_values.w_i_minus_2, local_values.w_i_minus_2_rs_10, - 10 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + 10, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); // check the computation of s0 and s1 for i in 0..32 { @@ -363,7 +460,7 @@ impl, const D: usize> Stark for ShaExtendStar builder, local_values.w_i_minus_15_rr_7[i], local_values.w_i_minus_15_rr_18[i], - local_values.w_i_minus_15_rs_3[i] + local_values.w_i_minus_15_rs_3[i], ); let constraint = builder.sub_extension(local_values.s_0[i], s0); yield_constr.constraint(builder, constraint); @@ -372,7 +469,7 @@ impl, const D: usize> Stark for ShaExtendStar builder, local_values.w_i_minus_2_rr_17[i], local_values.w_i_minus_2_rr_19[i], - local_values.w_i_minus_2_rs_10[i] + local_values.w_i_minus_2_rs_10[i], ); let constraint = builder.sub_extension(local_values.s_1[i], s1); yield_constr.constraint(builder, constraint); @@ -384,8 +481,10 @@ impl, const D: usize> Stark for ShaExtendStar local_values.w_i_minus_7, local_values.s_1, local_values.carry_0, - local_values.w_i_inter_0 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.w_i_inter_0, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); // check the computation of w_i_inter_1 = w_i_inter_0 + s0 wrapping_add_ext_circuit_constraints( @@ -393,8 +492,10 @@ impl, const D: usize> Stark for ShaExtendStar local_values.w_i_inter_0, local_values.s_0, local_values.carry_1, - local_values.w_i_inter_1 - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.w_i_inter_1, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); // check the computation of w_i = w_i_inter_1 + w_i_minus_16 wrapping_add_ext_circuit_constraints( @@ -402,8 +503,10 @@ impl, const D: usize> Stark for ShaExtendStar local_values.w_i_inter_1, local_values.w_i_minus_16, local_values.carry_2, - local_values.w_i - ).into_iter().for_each(|c| yield_constr.constraint(builder, c)); + local_values.w_i, + ) + .into_iter() + .for_each(|c| yield_constr.constraint(builder, c)); } fn constraint_degree(&self) -> usize { @@ -411,24 +514,25 @@ impl, const D: usize> Stark for ShaExtendStar } } - #[cfg(test)] mod test { + use crate::config::StarkConfig; + use crate::cross_table_lookup::{ + Column, CtlData, CtlZData, Filter, GrandProductChallenge, GrandProductChallengeSet, + }; + use crate::prover::prove_single_table; + use crate::sha_extend::sha_extend_stark::ShaExtendStark; + use crate::sha_extend_sponge::columns::NUM_EXTEND_INPUT; + use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::polynomial::PolynomialValues; - use plonky2::field::types::{Field}; + use plonky2::field::types::Field; use plonky2::fri::oracle::PolynomialBatch; use plonky2::iop::challenger::Challenger; use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::timed; use plonky2::util::timing::TimingTree; - use crate::config::StarkConfig; - use crate::cross_table_lookup::{Column, CtlData, CtlZData, Filter, GrandProductChallenge, GrandProductChallengeSet}; - use crate::prover::prove_single_table; - use crate::sha_extend::sha_extend_stark::ShaExtendStark; - use crate::sha_extend_sponge::columns::NUM_EXTEND_INPUT; - use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; fn to_be_bits(value: u32) -> [u8; 32] { let mut result = [0; 32]; @@ -461,7 +565,6 @@ mod test { let stark = S::default(); let row = stark.generate_trace_rows_for_extend(input_and_timestamp.try_into().unwrap()); - // extend phase let w_i_minus_15 = 0 as u32; let s0 = w_i_minus_15.rotate_right(7) ^ w_i_minus_15.rotate_right(18) ^ (w_i_minus_15 >> 3); @@ -580,4 +683,4 @@ mod test { fn init_logger() { let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); } -} \ No newline at end of file +} diff --git a/prover/src/sha_extend_sponge/columns.rs b/prover/src/sha_extend_sponge/columns.rs index 9b849386..030d2a8c 100644 --- a/prover/src/sha_extend_sponge/columns.rs +++ b/prover/src/sha_extend_sponge/columns.rs @@ -1,11 +1,10 @@ +use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; use std::borrow::{Borrow, BorrowMut}; use std::intrinsics::transmute; -use crate::util::{indices_arr, transmute_no_compile_time_size_checks}; pub(crate) const NUM_EXTEND_INPUT: usize = 4; -pub(crate) const SHA_EXTEND_SPONGE_READ_BITS: usize = NUM_EXTEND_INPUT * 32; +pub(crate) const SHA_EXTEND_SPONGE_READ_BITS: usize = NUM_EXTEND_INPUT * 32; pub(crate) struct ShaExtendSpongeColumnsView { - /// Input pub w_i_minus_15: [T; 32], pub w_i_minus_2: [T; 32], @@ -78,9 +77,10 @@ impl Default for ShaExtendSpongeColumnsView { const fn make_col_map() -> ShaExtendSpongeColumnsView { let indices_arr = indices_arr::(); unsafe { - transmute::<[usize; NUM_SHA_EXTEND_SPONGE_COLUMNS], ShaExtendSpongeColumnsView>(indices_arr) + transmute::<[usize; NUM_SHA_EXTEND_SPONGE_COLUMNS], ShaExtendSpongeColumnsView>( + indices_arr, + ) } } pub(crate) const SHA_EXTEND_SPONGE_COL_MAP: ShaExtendSpongeColumnsView = make_col_map(); - diff --git a/prover/src/sha_extend_sponge/logic.rs b/prover/src/sha_extend_sponge/logic.rs index be31b63f..67d74516 100644 --- a/prover/src/sha_extend_sponge/logic.rs +++ b/prover/src/sha_extend_sponge/logic.rs @@ -1,10 +1,9 @@ +use crate::sha_extend_sponge::sha_extend_sponge_stark::NUM_ROUNDS; use plonky2::field::extension::Extendable; use plonky2::field::types::Field; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; use plonky2::plonk::circuit_builder::CircuitBuilder; -use crate::sha_extend_sponge::sha_extend_sponge_stark::NUM_ROUNDS; - // Compute (x - y - diff) * sum_round_flags pub(crate) fn diff_address_ext_circuit_constraint, const D: usize>( @@ -12,7 +11,7 @@ pub(crate) fn diff_address_ext_circuit_constraint, sum_round_flags: ExtensionTarget, x: ExtensionTarget, y: ExtensionTarget, - diff: usize + diff: usize, ) -> ExtensionTarget { let inter_1 = builder.sub_extension(x, y); let diff_ext = builder.constant_extension(F::Extension::from_canonical_u32(diff as u32)); @@ -21,30 +20,33 @@ pub(crate) fn diff_address_ext_circuit_constraint, } // Compute nxt_round - local_round - 1 -pub(crate) fn round_increment_ext_circuit_constraint, const D: usize>( +pub(crate) fn round_increment_ext_circuit_constraint< + F: RichField + Extendable, + const D: usize, +>( builder: &mut CircuitBuilder, local_round: [ExtensionTarget; NUM_ROUNDS], next_round: [ExtensionTarget; NUM_ROUNDS], ) -> ExtensionTarget { - let one_ext = builder.one_extension(); - let local_round_indices: Vec<_> = - (0..NUM_ROUNDS).map(|i| { + let local_round_indices: Vec<_> = (0..NUM_ROUNDS) + .map(|i| { let index = builder.constant_extension(F::Extension::from_canonical_u32(i as u32)); builder.mul_extension(local_round[i], index) - }).collect(); + }) + .collect(); let local_round_index = builder.add_many_extension(local_round_indices); - let next_round_indices: Vec<_> = - (0..NUM_ROUNDS).map(|i| { + let next_round_indices: Vec<_> = (0..NUM_ROUNDS) + .map(|i| { let index = builder.constant_extension(F::Extension::from_canonical_u32(i as u32)); builder.mul_extension(next_round[i], index) - }).collect(); + }) + .collect(); let next_round_index = builder.add_many_extension(next_round_indices); let increment = builder.sub_extension(next_round_index, local_round_index); builder.sub_extension(increment, one_ext) - -} \ No newline at end of file +} diff --git a/prover/src/sha_extend_sponge/mod.rs b/prover/src/sha_extend_sponge/mod.rs index afdca798..c08a6d5a 100644 --- a/prover/src/sha_extend_sponge/mod.rs +++ b/prover/src/sha_extend_sponge/mod.rs @@ -1,3 +1,3 @@ pub mod columns; -pub mod sha_extend_sponge_stark; pub mod logic; +pub mod sha_extend_sponge_stark; diff --git a/prover/src/sha_extend_sponge/sha_extend_sponge_stark.rs b/prover/src/sha_extend_sponge/sha_extend_sponge_stark.rs index a64cd310..bb6c6d47 100644 --- a/prover/src/sha_extend_sponge/sha_extend_sponge_stark.rs +++ b/prover/src/sha_extend_sponge/sha_extend_sponge_stark.rs @@ -1,24 +1,29 @@ -use std::marker::PhantomData; -use std::borrow::Borrow; -use itertools::Itertools; -use plonky2::field::extension::{Extendable, FieldExtension}; -use plonky2::field::packed::PackedField; -use plonky2::field::polynomial::PolynomialValues; -use plonky2::field::types::Field; -use plonky2::hash::hash_types::RichField; -use plonky2::iop::ext_target::ExtensionTarget; -use plonky2::plonk::circuit_builder::CircuitBuilder; use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer}; use crate::cpu::membus::NUM_CHANNELS; use crate::cross_table_lookup::{Column, Filter}; use crate::evaluation_frame::{StarkEvaluationFrame, StarkFrame}; use crate::memory::segments::Segment; -use crate::sha_extend::logic::{get_input_range, from_u32_to_be_bits, from_be_fbits_to_u32}; -use crate::sha_extend_sponge::columns::{ShaExtendSpongeColumnsView, NUM_EXTEND_INPUT, NUM_SHA_EXTEND_SPONGE_COLUMNS, SHA_EXTEND_SPONGE_COL_MAP}; -use crate::sha_extend_sponge::logic::{diff_address_ext_circuit_constraint, round_increment_ext_circuit_constraint}; +use crate::sha_extend::logic::{from_be_fbits_to_u32, from_u32_to_be_bits, get_input_range}; +use crate::sha_extend_sponge::columns::{ + ShaExtendSpongeColumnsView, NUM_EXTEND_INPUT, NUM_SHA_EXTEND_SPONGE_COLUMNS, + SHA_EXTEND_SPONGE_COL_MAP, +}; +use crate::sha_extend_sponge::logic::{ + diff_address_ext_circuit_constraint, round_increment_ext_circuit_constraint, +}; use crate::stark::Stark; use crate::util::trace_rows_to_poly_values; use crate::witness::memory::MemoryAddress; +use itertools::Itertools; +use plonky2::field::extension::{Extendable, FieldExtension}; +use plonky2::field::packed::PackedField; +use plonky2::field::polynomial::PolynomialValues; +use plonky2::field::types::Field; +use plonky2::hash::hash_types::RichField; +use plonky2::iop::ext_target::ExtensionTarget; +use plonky2::plonk::circuit_builder::CircuitBuilder; +use std::borrow::Borrow; +use std::marker::PhantomData; pub const NUM_ROUNDS: usize = 48; @@ -31,9 +36,9 @@ pub(crate) fn ctl_looking_sha_extend_inputs() -> Vec> { cols.w_i_minus_16.as_slice(), cols.w_i_minus_7.as_slice(), ] - .concat(), + .concat(), ) - .collect(); + .collect(); res.push(Column::single(cols.timestamp)); res } @@ -50,17 +55,15 @@ pub(crate) fn ctl_looking_sha_extend_outputs() -> Vec> { pub(crate) fn ctl_looked_data() -> Vec> { let cols = SHA_EXTEND_SPONGE_COL_MAP; let w_i_usize = Column::linear_combination( - cols.w_i.iter() + cols.w_i + .iter() .enumerate() .map(|(i, &b)| (b, F::from_canonical_usize(1 << i))), ); - Column::singles([ - cols.context, - cols.segment, - cols.output_virt, - cols.timestamp, - ]).chain([w_i_usize]).collect() + Column::singles([cols.context, cols.segment, cols.output_virt, cols.timestamp]) + .chain([w_i_usize]) + .collect() } pub(crate) fn ctl_looking_memory(i: usize) -> Vec> { @@ -99,13 +102,11 @@ pub(crate) fn ctl_looking_memory(i: usize) -> Vec> { pub(crate) fn ctl_looking_sha_extend_filter() -> Filter { let cols = SHA_EXTEND_SPONGE_COL_MAP; // not the padding rows. - Filter::new_simple(Column::sum( - &cols.round, - )) + Filter::new_simple(Column::sum(&cols.round)) } #[derive(Clone, Debug)] -pub(crate) struct ShaExtendSpongeOp { +pub(crate) struct ShaExtendSpongeOp { /// The base address at which inputs are read pub(crate) base_address: Vec, @@ -159,7 +160,7 @@ impl, const D: usize> ShaExtendSpongeStark { rows } - fn generate_rows_for_op(&self, op: ShaExtendSpongeOp) -> ShaExtendSpongeColumnsView{ + fn generate_rows_for_op(&self, op: ShaExtendSpongeOp) -> ShaExtendSpongeColumnsView { let mut row = ShaExtendSpongeColumnsView::default(); row.timestamp = F::from_canonical_usize(op.timestamp); row.round = [F::ZEROS; 48]; @@ -175,13 +176,29 @@ impl, const D: usize> ShaExtendSpongeStark { row.output_virt = F::from_canonical_usize(op.output_address.virt); row.w_i_minus_15 = op.input[get_input_range(0)] - .iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); row.w_i_minus_2 = op.input[get_input_range(1)] - .iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); row.w_i_minus_16 = op.input[get_input_range(2)] - .iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); row.w_i_minus_7 = op.input[get_input_range(3)] - .iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap(); + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap(); row.w_i = self.compute_w_i(&mut row); row @@ -200,28 +217,32 @@ impl, const D: usize> ShaExtendSpongeStark { .wrapping_add(w_i_minus_7); let w_i_bin = from_u32_to_be_bits(w_i_u32); - w_i_bin.iter().map(|&x| F::from_canonical_u8(x)).collect::>().try_into().unwrap() + w_i_bin + .iter() + .map(|&x| F::from_canonical_u8(x)) + .collect::>() + .try_into() + .unwrap() } } impl, const D: usize> Stark for ShaExtendSpongeStark { type EvaluationFrame - = StarkFrame + = StarkFrame where - FE: FieldExtension, - P: PackedField; + FE: FieldExtension, + P: PackedField; type EvaluationFrameTarget = StarkFrame, NUM_SHA_EXTEND_SPONGE_COLUMNS>; fn eval_packed_generic( &self, vars: &Self::EvaluationFrame, - yield_constr: &mut ConstraintConsumer

+ yield_constr: &mut ConstraintConsumer

, ) where - FE: FieldExtension, - P: PackedField + FE: FieldExtension, + P: PackedField, { - let local_values: &[P; NUM_SHA_EXTEND_SPONGE_COLUMNS] = vars.get_local_values().try_into().unwrap(); let local_values: &ShaExtendSpongeColumnsView

= local_values.borrow(); @@ -231,10 +252,16 @@ impl, const D: usize> Stark for ShaExtendSpon // check the binary form for i in 0..32 { - yield_constr.constraint(local_values.w_i_minus_15[i] * (local_values.w_i_minus_15[i] - P::ONES)); - yield_constr.constraint(local_values.w_i_minus_2[i] * (local_values.w_i_minus_2[i] - P::ONES)); - yield_constr.constraint(local_values.w_i_minus_16[i] * (local_values.w_i_minus_16[i] - P::ONES)); - yield_constr.constraint(local_values.w_i_minus_7[i] * (local_values.w_i_minus_7[i] - P::ONES)); + yield_constr.constraint( + local_values.w_i_minus_15[i] * (local_values.w_i_minus_15[i] - P::ONES), + ); + yield_constr + .constraint(local_values.w_i_minus_2[i] * (local_values.w_i_minus_2[i] - P::ONES)); + yield_constr.constraint( + local_values.w_i_minus_16[i] * (local_values.w_i_minus_16[i] - P::ONES), + ); + yield_constr + .constraint(local_values.w_i_minus_7[i] * (local_values.w_i_minus_7[i] - P::ONES)); yield_constr.constraint(local_values.w_i[i] * (local_values.w_i[i] - P::ONES)); } @@ -248,15 +275,16 @@ impl, const D: usize> Stark for ShaExtendSpon yield_constr.constraint(is_final * (is_final - P::ONES)); let not_final = P::ONES - is_final; - let sum_round_flags = (0..NUM_ROUNDS) - .map(|i| local_values.round[i]) - .sum::

(); + let sum_round_flags = (0..NUM_ROUNDS).map(|i| local_values.round[i]).sum::

(); // If this is not the final step or a padding row, // the timestamp must be increased by 2 * NUM_CHANNELS. yield_constr.constraint( - sum_round_flags * not_final * - (next_values.timestamp - local_values.timestamp - FE::from_canonical_usize(2 * NUM_CHANNELS)), + sum_round_flags + * not_final + * (next_values.timestamp + - local_values.timestamp + - FE::from_canonical_usize(2 * NUM_CHANNELS)), ); // If this is not the final step or a padding row, @@ -269,18 +297,24 @@ impl, const D: usize> Stark for ShaExtendSpon .map(|i| next_values.round[i] * FE::from_canonical_u32(i as u32)) .sum::

(); yield_constr.constraint( - sum_round_flags * not_final * (next_round_index - local_round_index - P::ONES) + sum_round_flags * not_final * (next_round_index - local_round_index - P::ONES), ); // If this is not the final step or a padding row, // input and output addresses should be increased by 4 each (0..NUM_EXTEND_INPUT).for_each(|i| { yield_constr.constraint( - sum_round_flags * not_final * (next_values.input_virt[i] - local_values.input_virt[i] - FE::from_canonical_u32(4)) + sum_round_flags + * not_final + * (next_values.input_virt[i] + - local_values.input_virt[i] + - FE::from_canonical_u32(4)), ); }); yield_constr.constraint( - sum_round_flags * not_final * (next_values.output_virt - local_values.output_virt - FE::from_canonical_u32(4)) + sum_round_flags + * not_final + * (next_values.output_virt - local_values.output_virt - FE::from_canonical_u32(4)), ); // If it's not the padding row, check the virtual addresses @@ -288,19 +322,31 @@ impl, const D: usize> Stark for ShaExtendSpon // add_w[i-15] = add_w[i-16] + 4 yield_constr.constraint( - sum_round_flags * (local_values.input_virt[0] - local_values.input_virt[2] - FE::from_canonical_u32(4)) + sum_round_flags + * (local_values.input_virt[0] + - local_values.input_virt[2] + - FE::from_canonical_u32(4)), ); // add_w[i-2] = add_w[i-16] + 56 yield_constr.constraint( - sum_round_flags * (local_values.input_virt[1] - local_values.input_virt[2] - FE::from_canonical_u32(56)) + sum_round_flags + * (local_values.input_virt[1] + - local_values.input_virt[2] + - FE::from_canonical_u32(56)), ); // add_w[i-7] = add_w[i-16] + 36 yield_constr.constraint( - sum_round_flags * (local_values.input_virt[3] - local_values.input_virt[2] - FE::from_canonical_u32(36)) + sum_round_flags + * (local_values.input_virt[3] + - local_values.input_virt[2] + - FE::from_canonical_u32(36)), ); // add_w[i] = add_w[i-16] + 64 yield_constr.constraint( - sum_round_flags * (local_values.output_virt - local_values.input_virt[2] - FE::from_canonical_u32(64)) + sum_round_flags + * (local_values.output_virt + - local_values.input_virt[2] + - FE::from_canonical_u32(64)), ); } @@ -308,9 +354,8 @@ impl, const D: usize> Stark for ShaExtendSpon &self, builder: &mut CircuitBuilder, vars: &Self::EvaluationFrameTarget, - yield_constr: &mut RecursiveConstraintConsumer + yield_constr: &mut RecursiveConstraintConsumer, ) { - let local_values: &[ExtensionTarget; NUM_SHA_EXTEND_SPONGE_COLUMNS] = vars.get_local_values().try_into().unwrap(); let local_values: &ShaExtendSpongeColumnsView> = local_values.borrow(); @@ -320,34 +365,52 @@ impl, const D: usize> Stark for ShaExtendSpon let one_ext = builder.one_extension(); let four_ext = builder.constant_extension(F::Extension::from_canonical_u32(4)); - let num_channel = builder.constant_extension(F::Extension::from_canonical_usize(2 * NUM_CHANNELS)); + let num_channel = + builder.constant_extension(F::Extension::from_canonical_usize(2 * NUM_CHANNELS)); // check the binary form for i in 0..32 { let constraint = builder.mul_sub_extension( - local_values.w_i_minus_15[i], local_values.w_i_minus_15[i], local_values.w_i_minus_15[i]); + local_values.w_i_minus_15[i], + local_values.w_i_minus_15[i], + local_values.w_i_minus_15[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.w_i_minus_2[i], local_values.w_i_minus_2[i], local_values.w_i_minus_2[i]); + local_values.w_i_minus_2[i], + local_values.w_i_minus_2[i], + local_values.w_i_minus_2[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.w_i_minus_16[i], local_values.w_i_minus_16[i], local_values.w_i_minus_16[i]); + local_values.w_i_minus_16[i], + local_values.w_i_minus_16[i], + local_values.w_i_minus_16[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.w_i_minus_7[i], local_values.w_i_minus_7[i], local_values.w_i_minus_7[i]); + local_values.w_i_minus_7[i], + local_values.w_i_minus_7[i], + local_values.w_i_minus_7[i], + ); yield_constr.constraint(builder, constraint); let constraint = builder.mul_sub_extension( - local_values.w_i[i], local_values.w_i[i], local_values.w_i[i]); + local_values.w_i[i], + local_values.w_i[i], + local_values.w_i[i], + ); yield_constr.constraint(builder, constraint); } // check the round for i in 0..NUM_ROUNDS { let constraint = builder.mul_sub_extension( - local_values.round[i], local_values.round[i], local_values.round[i] + local_values.round[i], + local_values.round[i], + local_values.round[i], ); yield_constr.constraint(builder, constraint); } @@ -371,36 +434,28 @@ impl, const D: usize> Stark for ShaExtendSpon // If this is not the final step or a padding row, // round index should be increased by one - let round_increment = round_increment_ext_circuit_constraint( - builder, - local_values.round, - next_values.round - ); - let constraint = builder.mul_many_extension( - [sum_round_flags, not_final, round_increment] - ); + let round_increment = + round_increment_ext_circuit_constraint(builder, local_values.round, next_values.round); + let constraint = builder.mul_many_extension([sum_round_flags, not_final, round_increment]); yield_constr.constraint(builder, constraint); // If this is not the final step or a padding row, // input and output addresses should be increased by 4 each (0..NUM_EXTEND_INPUT).for_each(|i| { - - let increment = builder.sub_extension(next_values.input_virt[i], local_values.input_virt[i]); + let increment = + builder.sub_extension(next_values.input_virt[i], local_values.input_virt[i]); let address_increment = builder.sub_extension(increment, four_ext); - let constraint = builder.mul_many_extension( - [sum_round_flags, not_final, address_increment] - ); + let constraint = + builder.mul_many_extension([sum_round_flags, not_final, address_increment]); yield_constr.constraint(builder, constraint); }); let increment = builder.sub_extension(next_values.output_virt, local_values.output_virt); let address_increment = builder.sub_extension(increment, four_ext); - let constraint = builder.mul_many_extension( - [sum_round_flags, not_final, address_increment] - ); + let constraint = + builder.mul_many_extension([sum_round_flags, not_final, address_increment]); yield_constr.constraint(builder, constraint); - // If it's not the padding row, check the virtual addresses // The list of input addresses are: w[i-15], w[i-2], w[i-16], w[i-7] @@ -410,7 +465,7 @@ impl, const D: usize> Stark for ShaExtendSpon sum_round_flags, local_values.input_virt[0], local_values.input_virt[2], - 4 + 4, ); yield_constr.constraint(builder, constraint); @@ -420,7 +475,7 @@ impl, const D: usize> Stark for ShaExtendSpon sum_round_flags, local_values.input_virt[1], local_values.input_virt[2], - 56 + 56, ); yield_constr.constraint(builder, constraint); @@ -430,7 +485,7 @@ impl, const D: usize> Stark for ShaExtendSpon sum_round_flags, local_values.input_virt[3], local_values.input_virt[2], - 36 + 36, ); yield_constr.constraint(builder, constraint); @@ -440,7 +495,7 @@ impl, const D: usize> Stark for ShaExtendSpon sum_round_flags, local_values.output_virt, local_values.input_virt[2], - 64 + 64, ); yield_constr.constraint(builder, constraint); } @@ -450,9 +505,20 @@ impl, const D: usize> Stark for ShaExtendSpon } } - #[cfg(test)] mod test { + use crate::config::StarkConfig; + use crate::cross_table_lookup::{ + Column, CtlData, CtlZData, Filter, GrandProductChallenge, GrandProductChallengeSet, + }; + use crate::memory::segments::Segment; + use crate::memory::NUM_CHANNELS; + use crate::prover::prove_single_table; + use crate::sha_extend_sponge::sha_extend_sponge_stark::{ + ShaExtendSpongeOp, ShaExtendSpongeStark, + }; + use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; + use crate::witness::memory::MemoryAddress; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use plonky2::field::goldilocks_field::GoldilocksField; use plonky2::field::polynomial::PolynomialValues; @@ -462,14 +528,6 @@ mod test { use plonky2::plonk::config::{GenericConfig, PoseidonGoldilocksConfig}; use plonky2::timed; use plonky2::util::timing::TimingTree; - use crate::config::StarkConfig; - use crate::cross_table_lookup::{Column, CtlData, CtlZData, Filter, GrandProductChallenge, GrandProductChallengeSet}; - use crate::memory::NUM_CHANNELS; - use crate::memory::segments::Segment; - use crate::prover::prove_single_table; - use crate::sha_extend_sponge::sha_extend_sponge_stark::{ShaExtendSpongeOp, ShaExtendSpongeStark}; - use crate::stark_testing::{test_stark_circuit_constraints, test_stark_low_degree}; - use crate::witness::memory::MemoryAddress; fn to_be_bits(value: u32) -> [u8; 32] { let mut result = [0; 32]; @@ -491,23 +549,28 @@ mod test { let input_values = input_values.into_iter().flatten().collect::>(); let op = ShaExtendSpongeOp { - base_address: vec![MemoryAddress { - context: 0, - segment: Segment::Code as usize, - virt: 4, - }, MemoryAddress { - context: 0, - segment: Segment::Code as usize, - virt: 56, - }, MemoryAddress { - context: 0, - segment: Segment::Code as usize, - virt: 0, - }, MemoryAddress { - context: 0, - segment: Segment::Code as usize, - virt: 36, - }], + base_address: vec![ + MemoryAddress { + context: 0, + segment: Segment::Code as usize, + virt: 4, + }, + MemoryAddress { + context: 0, + segment: Segment::Code as usize, + virt: 56, + }, + MemoryAddress { + context: 0, + segment: Segment::Code as usize, + virt: 0, + }, + MemoryAddress { + context: 0, + segment: Segment::Code as usize, + virt: 36, + }, + ], timestamp: 0, input: input_values, i: 0, @@ -557,18 +620,19 @@ mod test { w[i] = rand::random::(); } for i in 16..64 { - - let w_i_minus_15 = w[i-15]; - let s0 = w_i_minus_15.rotate_right(7) ^ w_i_minus_15.rotate_right(18) ^ (w_i_minus_15 >> 3); + let w_i_minus_15 = w[i - 15]; + let s0 = + w_i_minus_15.rotate_right(7) ^ w_i_minus_15.rotate_right(18) ^ (w_i_minus_15 >> 3); // Read w[i-2]. - let w_i_minus_2 = w[i-2]; + let w_i_minus_2 = w[i - 2]; // Compute `s1`. - let s1 = w_i_minus_2.rotate_right(17) ^ w_i_minus_2.rotate_right(19) ^ (w_i_minus_2 >> 10); + let s1 = + w_i_minus_2.rotate_right(17) ^ w_i_minus_2.rotate_right(19) ^ (w_i_minus_2 >> 10); // Read w[i-16]. - let w_i_minus_16 = w[i-16]; - let w_i_minus_7 = w[i-7]; + let w_i_minus_16 = w[i - 16]; + let w_i_minus_7 = w[i - 7]; // Compute `w_i`. w[i] = s1 @@ -579,10 +643,10 @@ mod test { let mut addresses = vec![]; for i in 0..64 { - addresses.push(MemoryAddress{ + addresses.push(MemoryAddress { context: 0, segment: Segment::Code as usize, - virt: i * 4 + virt: i * 4, }); } @@ -597,7 +661,12 @@ mod test { input_values.extend(to_be_bits(w[i - 7])); let op = ShaExtendSpongeOp { - base_address: vec![addresses[i - 15], addresses[i - 2], addresses[i - 16], addresses[i - 7]], + base_address: vec![ + addresses[i - 15], + addresses[i - 2], + addresses[i - 16], + addresses[i - 7], + ], timestamp: time, input: input_values, i: i - 16, @@ -609,7 +678,6 @@ mod test { } res - } #[test] fn sha_extend_sponge_benchmark() -> anyhow::Result<()> { @@ -679,4 +747,4 @@ mod test { fn init_logger() { let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); } -} \ No newline at end of file +} diff --git a/prover/src/witness/operation.rs b/prover/src/witness/operation.rs index df4c2fb7..72d35541 100644 --- a/prover/src/witness/operation.rs +++ b/prover/src/witness/operation.rs @@ -14,13 +14,13 @@ use plonky2::field::types::Field; use super::util::keccak_sponge_log; use crate::keccak_sponge::columns::{KECCAK_RATE_BYTES, KECCAK_RATE_U32S}; use crate::poseidon_sponge::columns::POSEIDON_RATE_BYTES; +use crate::sha_extend::logic::from_u32_to_be_bits; use itertools::Itertools; use keccak_hash::keccak; use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::plonk::config::GenericConfig; use std::fs; -use crate::sha_extend::logic::from_u32_to_be_bits; pub const WORD_SIZE: usize = core::mem::size_of::(); @@ -1222,7 +1222,6 @@ pub(crate) fn generate_sha_extend< input_addresses.push(addr); input_value_bit_be.push(from_u32_to_be_bits(w_i_minus_16)); - // Read w[i-7]. let addr = MemoryAddress::new(0, Segment::Code, w_ptr + (i - 7) * 4); let (w_i_minus_7, mem_op) = mem_read_gp_with_log_and_fill(3, addr, state, &mut cpu_row); @@ -1237,9 +1236,17 @@ pub(crate) fn generate_sha_extend< .wrapping_add(w_i_minus_7); // Write w[i]. - log::debug!("{:X}, {:X}, {:X} {:X} {:X} {:X}", s1, s0, w_i_minus_16, w_i_minus_7, w_i_minus_15, w_i_minus_2); + log::debug!( + "{:X}, {:X}, {:X} {:X} {:X} {:X}", + s1, + s0, + w_i_minus_16, + w_i_minus_7, + w_i_minus_15, + w_i_minus_2 + ); let addr = MemoryAddress::new(0, Segment::Code, w_ptr + i * 4); - log::debug!("extend write {:X} {:X}", w_ptr + i * 4, w_i); + log::debug!("extend write {:X} {:X}", w_ptr + i * 4, w_i); let mem_op = mem_write_gp_log_and_fill(4, addr, state, &mut cpu_row, w_i); state.traces.push_memory(mem_op); @@ -1314,7 +1321,10 @@ pub(crate) fn generate_sha_compress< cpu_row = CpuColumnsView::default(); cpu_row.clock = F::from_canonical_usize(state.traces.clock()); for i in 0..64 { - let input_state = [a, b, c, d, e, f, g, h].iter().map(|x| from_u32_to_be_bits(*x)).collect_vec(); + let input_state = [a, b, c, d, e, f, g, h] + .iter() + .map(|x| from_u32_to_be_bits(*x)) + .collect_vec(); state_values.push(input_state); let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25); @@ -1361,9 +1371,18 @@ pub(crate) fn generate_sha_compress< cpu_row.mem_channels[1].value = F::from_canonical_usize(Segment::Code as usize); cpu_row.mem_channels[2].value = F::from_canonical_usize(hx_addresses[0].virt); // start address of hx - let u32_result: Vec = [a, b, c, d, e, f, g, h].iter().enumerate().map(|(i, x)| hx[i].wrapping_add(*x)).collect_vec(); + let u32_result: Vec = [a, b, c, d, e, f, g, h] + .iter() + .enumerate() + .map(|(i, x)| hx[i].wrapping_add(*x)) + .collect_vec(); - cpu_row.general.shash_mut().value = u32_result.into_iter().map(F::from_canonical_u32).collect_vec().try_into().unwrap(); + cpu_row.general.shash_mut().value = u32_result + .into_iter() + .map(F::from_canonical_u32) + .collect_vec() + .try_into() + .unwrap(); // cpu_row.general.shash_mut().value.reverse(); sha_compress_sponge_log( state, @@ -1371,7 +1390,7 @@ pub(crate) fn generate_sha_compress< hx_addresses, w_i_value_bit_be, w_i_addresses, - state_values + state_values, ); state.traces.push_cpu(cpu_row); @@ -1383,7 +1402,7 @@ pub(crate) fn generate_sha_compress< let mem_op = mem_write_gp_log_and_fill(i, addr, state, &mut cpu_row, hx[i].wrapping_add(v[i])); state.traces.push_memory(mem_op); - log::debug!("write {:X} {:X}", h_ptr + i * 4, hx[i].wrapping_add(v[i])); + log::debug!("write {:X} {:X}", h_ptr + i * 4, hx[i].wrapping_add(v[i])); } state.traces.push_cpu(cpu_row); Ok(()) diff --git a/prover/src/witness/traces.rs b/prover/src/witness/traces.rs index 3cdab506..f775fc42 100644 --- a/prover/src/witness/traces.rs +++ b/prover/src/witness/traces.rs @@ -19,14 +19,14 @@ use crate::keccak_sponge::keccak_sponge_stark::KeccakSpongeOp; use crate::poseidon::constants::SPONGE_WIDTH; use crate::poseidon_sponge::columns::POSEIDON_RATE_BYTES; use crate::poseidon_sponge::poseidon_sponge_stark::PoseidonSpongeOp; -use crate::util::join; -use crate::util::trace_rows_to_poly_values; -use crate::witness::memory::MemoryOp; -use crate::{arithmetic, logic}; use crate::sha_compress::sha_compress_stark; use crate::sha_compress_sponge::sha_compress_sponge_stark::ShaCompressSpongeOp; use crate::sha_extend::sha_extend_stark; use crate::sha_extend_sponge::sha_extend_sponge_stark::ShaExtendSpongeOp; +use crate::util::join; +use crate::util::trace_rows_to_poly_values; +use crate::witness::memory::MemoryOp; +use crate::{arithmetic, logic}; #[derive(Clone, Copy, Debug)] pub struct TraceCheckpoint { @@ -106,11 +106,9 @@ impl Traces { .map(|op| op.input.len() / keccak_sponge::columns::KECCAK_RATE_BYTES + 1) .sum(), sha_extend_len: self.sha_extend_inputs.len(), - sha_extend_sponge_len: self - .sha_extend_sponge_ops.len(), + sha_extend_sponge_len: self.sha_extend_sponge_ops.len(), sha_compress_len: self.sha_compress_inputs.len(), - sha_compress_sponge_len: self - .sha_compress_sponge_ops.len(), + sha_compress_sponge_len: self.sha_compress_sponge_ops.len(), logic_len: self.logic_ops.len(), // This is technically a lower-bound, as we may fill gaps, // but this gives a relatively good estimate. @@ -148,7 +146,8 @@ impl Traces { self.sha_extend_inputs.truncate(checkpoint.sha_extend_len); self.sha_extend_sponge_ops .truncate(checkpoint.sha_extend_sponge_len); - self.sha_compress_inputs.truncate(checkpoint.sha_compress_len); + self.sha_compress_inputs + .truncate(checkpoint.sha_compress_len); self.sha_compress_sponge_ops .truncate(checkpoint.sha_compress_sponge_len); self.logic_ops.truncate(checkpoint.logic_len); diff --git a/prover/src/witness/util.rs b/prover/src/witness/util.rs index de4c3041..5173f23f 100644 --- a/prover/src/witness/util.rs +++ b/prover/src/witness/util.rs @@ -19,14 +19,14 @@ use crate::poseidon::constants::{SPONGE_RATE, SPONGE_WIDTH}; use crate::poseidon::poseidon_stark::poseidon_with_witness; use crate::poseidon_sponge::columns::POSEIDON_RATE_BYTES; use crate::poseidon_sponge::poseidon_sponge_stark::PoseidonSpongeOp; -use crate::witness::errors::ProgramError; -use crate::witness::memory::{MemoryAddress, MemoryChannel, MemoryOp, MemoryOpKind}; -use plonky2::field::extension::Extendable; -use plonky2::plonk::config::GenericConfig; use crate::sha_compress::logic::from_be_bits_to_u32; use crate::sha_compress_sponge::constants::SHA_COMPRESS_K_BINARY; use crate::sha_compress_sponge::sha_compress_sponge_stark::ShaCompressSpongeOp; use crate::sha_extend_sponge::sha_extend_sponge_stark::ShaExtendSpongeOp; +use crate::witness::errors::ProgramError; +use crate::witness::memory::{MemoryAddress, MemoryChannel, MemoryOp, MemoryOpKind}; +use plonky2::field::extension::Extendable; +use plonky2::plonk::config::GenericConfig; fn to_byte_checked(n: u32) -> u8 { let res: u8 = n.to_le_bytes()[0]; @@ -561,7 +561,7 @@ pub(crate) fn sha_extend_sponge_log< F: RichField + Extendable, C: GenericConfig, const D: usize, -> ( +>( state: &mut GenerationState, base_address: Vec, inputs: Vec<[u8; 32]>, // BE bits @@ -591,22 +591,25 @@ pub(crate) fn sha_extend_sponge_log< } addr_idx += 1; } - state.traces.push_sha_extend(extend_input.clone().try_into().unwrap(), clock * NUM_CHANNELS); + state.traces.push_sha_extend( + extend_input.clone().try_into().unwrap(), + clock * NUM_CHANNELS, + ); state.traces.push_sha_extend_sponge(ShaExtendSpongeOp { base_address, timestamp: clock * NUM_CHANNELS, input: extend_input, i: round, - output_address + output_address, }); } -pub(crate) fn sha_compress_sponge_log < +pub(crate) fn sha_compress_sponge_log< F: RichField + Extendable, C: GenericConfig, const D: usize, -> ( +>( state: &mut GenerationState, hx_values: Vec<[u8; 32]>, // BE bits hx_addresses: Vec, @@ -621,7 +624,6 @@ pub(crate) fn sha_compress_sponge_log < let mut n_gp = 0; for i in 0..64 { - // read hx as input for (j, hx) in hx_values.iter().enumerate() { let val = from_be_bits_to_u32(*hx); @@ -651,15 +653,31 @@ pub(crate) fn sha_compress_sponge_log < n_gp %= NUM_GP_CHANNELS - 1; } - let w_i = w_i_values[i]; let k_i = SHA_COMPRESS_K_BINARY[i]; - let base_address = hx_addresses.clone().into_iter().chain([w_i_addresses[i]]).collect_vec(); - let compress_sponge_input: Vec = hx_values.iter().chain(&[w_i]).flatten().cloned().collect(); - let compress_input: Vec = input_state_list[i].iter().chain(&[w_i, k_i]).flatten().cloned().collect(); - let input_states: Vec = input_state_list[i].clone().iter().flatten().cloned().collect(); + let base_address = hx_addresses + .clone() + .into_iter() + .chain([w_i_addresses[i]]) + .collect_vec(); + let compress_sponge_input: Vec = + hx_values.iter().chain(&[w_i]).flatten().cloned().collect(); + let compress_input: Vec = input_state_list[i] + .iter() + .chain(&[w_i, k_i]) + .flatten() + .cloned() + .collect(); + let input_states: Vec = input_state_list[i] + .clone() + .iter() + .flatten() + .cloned() + .collect(); - state.traces.push_sha_compress(compress_input.try_into().unwrap(), clock * NUM_CHANNELS); + state + .traces + .push_sha_compress(compress_input.try_into().unwrap(), clock * NUM_CHANNELS); state.traces.push_sha_compress_sponge(ShaCompressSpongeOp { base_address, @@ -668,7 +686,6 @@ pub(crate) fn sha_compress_sponge_log < i, input: compress_sponge_input, }); - } } diff --git a/runtime/entrypoint/src/syscalls/mod.rs b/runtime/entrypoint/src/syscalls/mod.rs index ca3c6dbf..cdf0fc2c 100644 --- a/runtime/entrypoint/src/syscalls/mod.rs +++ b/runtime/entrypoint/src/syscalls/mod.rs @@ -3,15 +3,15 @@ mod halt; mod io; mod keccak; -mod sha256; mod memory; +mod sha256; mod sys; pub use halt::*; pub use io::*; pub use keccak::*; -pub use sha256::*; pub use memory::*; +pub use sha256::*; pub use sys::*; /// These codes MUST match the codes in `core/src/runtime/syscall.rs`. There is a derived test diff --git a/runtime/precompiles/src/io.rs b/runtime/precompiles/src/io.rs index 346786b0..d3f7880c 100644 --- a/runtime/precompiles/src/io.rs +++ b/runtime/precompiles/src/io.rs @@ -5,7 +5,7 @@ use crate::syscall_keccak; use crate::syscall_verify; use crate::syscall_write; use crate::{syscall_hint_len, syscall_hint_read}; -use crate::{syscall_sha256_extend, syscall_sha256_compress}; +use crate::{syscall_sha256_compress, syscall_sha256_extend}; use serde::de::DeserializeOwned; use serde::Serialize; use sha2::{Digest, Sha256};