diff --git a/Cargo.toml b/Cargo.toml index 9e7a0e55..8d4564c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,8 @@ rust-version = "1.66" [dependencies] rand = "0.8.5" -lambdaworks-math = { git = "https://github.com/lambdaclass/lambdaworks", rev = "a21d2c5" } -lambdaworks-crypto = { git = "https://github.com/lambdaclass/lambdaworks", rev = "a21d2c5" } +lambdaworks-math = { git = "https://github.com/lambdaclass/lambdaworks", branch = "fft_with_twiddles_param" } +lambdaworks-crypto = { git = "https://github.com/lambdaclass/lambdaworks", branch = "fft_with_twiddles_param" } thiserror = "1.0.38" log = "0.4.17" bincode = { version = "2.0.0-rc.2", tag = "v2.0.0-rc.2", git = "https://github.com/bincode-org/bincode.git" } diff --git a/src/cairo/air.rs b/src/cairo/air.rs index 46f02885..79ba2c7f 100644 --- a/src/cairo/air.rs +++ b/src/cairo/air.rs @@ -197,12 +197,12 @@ impl PublicInputs { let mut public_memory = HashMap::with_capacity(public_memory_size); for i in 1..=program_size as u64 { - public_memory.insert(FE::from(i), memory.get(&i).unwrap().clone()); + public_memory.insert(FE::from(i), *memory.get(&i).unwrap()); } if let Some(output_range) = output_range { for addr in output_range.clone() { - public_memory.insert(FE::from(addr), memory.get(&addr).unwrap().clone()); + public_memory.insert(FE::from(addr), *memory.get(&addr).unwrap()); } }; let last_step = ®ister_states.rows[register_states.steps() - 1]; @@ -330,7 +330,7 @@ fn add_pub_memory_in_public_input_section( a_aux.splice(public_input_section.., pub_memory_addrs); for i in public_input_section..a_aux.len() { let address = &a_aux[i]; - v_aux[i] = public_input.public_memory.get(address).unwrap().clone(); + v_aux[i] = *public_input.public_memory.get(address).unwrap(); } (a_aux, v_aux) @@ -390,10 +390,10 @@ fn generate_memory_permutation_argument_column( .collect(); let mut ret = Vec::with_capacity(num.len()); - ret.push(num[0].clone()); + ret.push(num[0]); for i in 1..num.len() { - ret.push(&ret[i - 1] * &num[i]); + ret.push(ret[i - 1] * num[i]); } ret @@ -415,10 +415,10 @@ fn generate_range_check_permutation_argument_column( .collect(); let mut ret = Vec::with_capacity(num.len()); - ret.push(num[0].clone()); + ret.push(num[0]); for i in 1..num.len() { - ret.push(&ret[i - 1] * &num[i]); + ret.push(ret[i - 1] * num[i]); } ret @@ -478,24 +478,24 @@ impl AIR for CairoAIR { // Convert from long-format to wide-format again let mut aux_table = Vec::new(); for i in 0..main_trace.n_rows() { - aux_table.push(offsets_sorted[3 * i].clone()); - aux_table.push(offsets_sorted[3 * i + 1].clone()); - aux_table.push(offsets_sorted[3 * i + 2].clone()); - aux_table.push(addresses[4 * i].clone()); - aux_table.push(addresses[4 * i + 1].clone()); - aux_table.push(addresses[4 * i + 2].clone()); - aux_table.push(addresses[4 * i + 3].clone()); - aux_table.push(values[4 * i].clone()); - aux_table.push(values[4 * i + 1].clone()); - aux_table.push(values[4 * i + 2].clone()); - aux_table.push(values[4 * i + 3].clone()); - aux_table.push(permutation_col[4 * i].clone()); - aux_table.push(permutation_col[4 * i + 1].clone()); - aux_table.push(permutation_col[4 * i + 2].clone()); - aux_table.push(permutation_col[4 * i + 3].clone()); - aux_table.push(range_check_permutation_col[3 * i].clone()); - aux_table.push(range_check_permutation_col[3 * i + 1].clone()); - aux_table.push(range_check_permutation_col[3 * i + 2].clone()); + aux_table.push(offsets_sorted[3 * i]); + aux_table.push(offsets_sorted[3 * i + 1]); + aux_table.push(offsets_sorted[3 * i + 2]); + aux_table.push(addresses[4 * i]); + aux_table.push(addresses[4 * i + 1]); + aux_table.push(addresses[4 * i + 2]); + aux_table.push(addresses[4 * i + 3]); + aux_table.push(values[4 * i]); + aux_table.push(values[4 * i + 1]); + aux_table.push(values[4 * i + 2]); + aux_table.push(values[4 * i + 3]); + aux_table.push(permutation_col[4 * i]); + aux_table.push(permutation_col[4 * i + 1]); + aux_table.push(permutation_col[4 * i + 2]); + aux_table.push(permutation_col[4 * i + 3]); + aux_table.push(range_check_permutation_col[3 * i]); + aux_table.push(range_check_permutation_col[3 * i + 1]); + aux_table.push(range_check_permutation_col[3 * i + 2]); } TraceTable::new(aux_table, self.number_auxiliary_rap_columns()) @@ -552,20 +552,18 @@ impl AIR for CairoAIR { rap_challenges: &Self::RAPChallenges, public_input: &Self::PublicInput, ) -> BoundaryConstraints { - let initial_pc = - BoundaryConstraint::new(MEM_A_TRACE_OFFSET, 0, public_input.pc_init.clone()); - let initial_ap = - BoundaryConstraint::new(MEM_P_TRACE_OFFSET, 0, public_input.ap_init.clone()); + let initial_pc = BoundaryConstraint::new(MEM_A_TRACE_OFFSET, 0, public_input.pc_init); + let initial_ap = BoundaryConstraint::new(MEM_P_TRACE_OFFSET, 0, public_input.ap_init); let final_pc = BoundaryConstraint::new( MEM_A_TRACE_OFFSET, self.public_inputs.num_steps - 1, - public_input.pc_final.clone(), + public_input.pc_final, ); let final_ap = BoundaryConstraint::new( MEM_P_TRACE_OFFSET, self.public_inputs.num_steps - 1, - public_input.ap_final.clone(), + public_input.ap_final, ); // Auxiliary constraint: permutation argument final value @@ -576,7 +574,7 @@ impl AIR for CairoAIR { let mut cumulative_product = FieldElement::one(); for (address, value) in &public_input.public_memory { cumulative_product = cumulative_product - * (&rap_challenges.z_memory - (address + &rap_challenges.alpha_memory * value)); + * (rap_challenges.z_memory - (address + rap_challenges.alpha_memory * value)); } let permutation_final = rap_challenges .z_memory @@ -642,7 +640,7 @@ fn compute_instr_constraints(constraints: &mut [FE], frame: &Frame flag * (flag - FE::one()), - 15 => flag.clone(), + 15 => *flag, _ => panic!("Unknown flag offset"), }; } @@ -657,11 +655,11 @@ fn compute_instr_constraints(constraints: &mut [FE], frame: &Frame) { @@ -676,19 +674,19 @@ fn compute_operand_constraints(constraints: &mut [FE], frame: &Frame) { @@ -699,56 +697,53 @@ fn compute_register_constraints(constraints: &mut [FE], frame: &Frame) { let curr = frame.get_row(0); let one = FE::one(); - constraints[MUL_1] = &curr[FRAME_MUL] - (&curr[FRAME_OP0] * &curr[FRAME_OP1]); + constraints[MUL_1] = curr[FRAME_MUL] - (curr[FRAME_OP0] * curr[FRAME_OP1]); - constraints[MUL_2] = &curr[F_RES_ADD] * (&curr[FRAME_OP0] + &curr[FRAME_OP1]) - + &curr[F_RES_MUL] * &curr[FRAME_MUL] - + (&one - &curr[F_RES_ADD] - &curr[F_RES_MUL] - &curr[F_PC_JNZ]) * &curr[FRAME_OP1] - - (&one - &curr[F_PC_JNZ]) * &curr[FRAME_RES]; + constraints[MUL_2] = curr[F_RES_ADD] * (curr[FRAME_OP0] + curr[FRAME_OP1]) + + curr[F_RES_MUL] * curr[FRAME_MUL] + + (one - curr[F_RES_ADD] - curr[F_RES_MUL] - curr[F_PC_JNZ]) * curr[FRAME_OP1] + - (one - curr[F_PC_JNZ]) * curr[FRAME_RES]; - constraints[CALL_1] = &curr[F_OPC_CALL] * (&curr[FRAME_DST] - &curr[FRAME_FP]); + constraints[CALL_1] = curr[F_OPC_CALL] * (curr[FRAME_DST] - curr[FRAME_FP]); constraints[CALL_2] = - &curr[F_OPC_CALL] * (&curr[FRAME_OP0] - (&curr[FRAME_PC] + frame_inst_size(curr))); + curr[F_OPC_CALL] * (curr[FRAME_OP0] - (curr[FRAME_PC] + frame_inst_size(curr))); - constraints[ASSERT_EQ] = &curr[F_OPC_AEQ] * (&curr[FRAME_DST] - &curr[FRAME_RES]); + constraints[ASSERT_EQ] = curr[F_OPC_AEQ] * (curr[FRAME_DST] - curr[FRAME_RES]); } fn enforce_selector(constraints: &mut [FE], frame: &Frame) { let curr = frame.get_row(0); for result_cell in constraints.iter_mut().take(ASSERT_EQ + 1).skip(INST) { - *result_cell = result_cell.clone() * curr[FRAME_SELECTOR].clone(); + *result_cell = *result_cell * curr[FRAME_SELECTOR]; } } @@ -761,53 +756,53 @@ fn memory_is_increasing( let next = frame.get_row(1); let one = FieldElement::one(); - constraints[MEMORY_INCREASING_0] = (&curr[MEMORY_ADDR_SORTED_0 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_1 - builtin_offset]) - * (&curr[MEMORY_ADDR_SORTED_1 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_0 - builtin_offset] - - &one); - - constraints[MEMORY_INCREASING_1] = (&curr[MEMORY_ADDR_SORTED_1 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_2 - builtin_offset]) - * (&curr[MEMORY_ADDR_SORTED_2 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_1 - builtin_offset] - - &one); - - constraints[MEMORY_INCREASING_2] = (&curr[MEMORY_ADDR_SORTED_2 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_3 - builtin_offset]) - * (&curr[MEMORY_ADDR_SORTED_3 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_2 - builtin_offset] - - &one); - - constraints[MEMORY_INCREASING_3] = (&curr[MEMORY_ADDR_SORTED_3 - builtin_offset] - - &next[MEMORY_ADDR_SORTED_0 - builtin_offset]) - * (&next[MEMORY_ADDR_SORTED_0 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_3 - builtin_offset] - - &one); - - constraints[MEMORY_CONSISTENCY_0] = (&curr[MEMORY_VALUES_SORTED_0 - builtin_offset] - - &curr[MEMORY_VALUES_SORTED_1 - builtin_offset]) - * (&curr[MEMORY_ADDR_SORTED_1 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_0 - builtin_offset] - - &one); - - constraints[MEMORY_CONSISTENCY_1] = (&curr[MEMORY_VALUES_SORTED_1 - builtin_offset] - - &curr[MEMORY_VALUES_SORTED_2 - builtin_offset]) - * (&curr[MEMORY_ADDR_SORTED_2 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_1 - builtin_offset] - - &one); - - constraints[MEMORY_CONSISTENCY_2] = (&curr[MEMORY_VALUES_SORTED_2 - builtin_offset] - - &curr[MEMORY_VALUES_SORTED_3 - builtin_offset]) - * (&curr[MEMORY_ADDR_SORTED_3 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_2 - builtin_offset] - - &one); - - constraints[MEMORY_CONSISTENCY_3] = (&curr[MEMORY_VALUES_SORTED_3 - builtin_offset] - - &next[MEMORY_VALUES_SORTED_0 - builtin_offset]) - * (&next[MEMORY_ADDR_SORTED_0 - builtin_offset] - - &curr[MEMORY_ADDR_SORTED_3 - builtin_offset] - - &one); + constraints[MEMORY_INCREASING_0] = (curr[MEMORY_ADDR_SORTED_0 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_1 - builtin_offset]) + * (curr[MEMORY_ADDR_SORTED_1 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_0 - builtin_offset] + - one); + + constraints[MEMORY_INCREASING_1] = (curr[MEMORY_ADDR_SORTED_1 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_2 - builtin_offset]) + * (curr[MEMORY_ADDR_SORTED_2 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_1 - builtin_offset] + - one); + + constraints[MEMORY_INCREASING_2] = (curr[MEMORY_ADDR_SORTED_2 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_3 - builtin_offset]) + * (curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_2 - builtin_offset] + - one); + + constraints[MEMORY_INCREASING_3] = (curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - next[MEMORY_ADDR_SORTED_0 - builtin_offset]) + * (next[MEMORY_ADDR_SORTED_0 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - one); + + constraints[MEMORY_CONSISTENCY_0] = (curr[MEMORY_VALUES_SORTED_0 - builtin_offset] + - curr[MEMORY_VALUES_SORTED_1 - builtin_offset]) + * (curr[MEMORY_ADDR_SORTED_1 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_0 - builtin_offset] + - one); + + constraints[MEMORY_CONSISTENCY_1] = (curr[MEMORY_VALUES_SORTED_1 - builtin_offset] + - curr[MEMORY_VALUES_SORTED_2 - builtin_offset]) + * (curr[MEMORY_ADDR_SORTED_2 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_1 - builtin_offset] + - one); + + constraints[MEMORY_CONSISTENCY_2] = (curr[MEMORY_VALUES_SORTED_2 - builtin_offset] + - curr[MEMORY_VALUES_SORTED_3 - builtin_offset]) + * (curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_2 - builtin_offset] + - one); + + constraints[MEMORY_CONSISTENCY_3] = (curr[MEMORY_VALUES_SORTED_3 - builtin_offset] + - next[MEMORY_VALUES_SORTED_0 - builtin_offset]) + * (next[MEMORY_ADDR_SORTED_0 - builtin_offset] + - curr[MEMORY_ADDR_SORTED_3 - builtin_offset] + - one); } fn permutation_argument( @@ -868,21 +863,21 @@ fn permutation_argument_range_check( let one = FieldElement::one(); let z = &rap_challenges.z_range_check; - constraints[RANGE_CHECK_INCREASING_0] = (&curr[RANGE_CHECK_COL_1 - builtin_offset] - - &curr[RANGE_CHECK_COL_2 - builtin_offset]) - * (&curr[RANGE_CHECK_COL_2 - builtin_offset] - - &curr[RANGE_CHECK_COL_1 - builtin_offset] - - &one); - constraints[RANGE_CHECK_INCREASING_1] = (&curr[RANGE_CHECK_COL_2 - builtin_offset] - - &curr[RANGE_CHECK_COL_3 - builtin_offset]) - * (&curr[RANGE_CHECK_COL_3 - builtin_offset] - - &curr[RANGE_CHECK_COL_2 - builtin_offset] - - &one); - constraints[RANGE_CHECK_INCREASING_2] = (&curr[RANGE_CHECK_COL_3 - builtin_offset] - - &next[RANGE_CHECK_COL_1 - builtin_offset]) - * (&next[RANGE_CHECK_COL_1 - builtin_offset] - - &curr[RANGE_CHECK_COL_3 - builtin_offset] - - &one); + constraints[RANGE_CHECK_INCREASING_0] = (curr[RANGE_CHECK_COL_1 - builtin_offset] + - curr[RANGE_CHECK_COL_2 - builtin_offset]) + * (curr[RANGE_CHECK_COL_2 - builtin_offset] + - curr[RANGE_CHECK_COL_1 - builtin_offset] + - one); + constraints[RANGE_CHECK_INCREASING_1] = (curr[RANGE_CHECK_COL_2 - builtin_offset] + - curr[RANGE_CHECK_COL_3 - builtin_offset]) + * (curr[RANGE_CHECK_COL_3 - builtin_offset] + - curr[RANGE_CHECK_COL_2 - builtin_offset] + - one); + constraints[RANGE_CHECK_INCREASING_2] = (curr[RANGE_CHECK_COL_3 - builtin_offset] + - next[RANGE_CHECK_COL_1 - builtin_offset]) + * (next[RANGE_CHECK_COL_1 - builtin_offset] + - curr[RANGE_CHECK_COL_3 - builtin_offset] + - one); let p0 = &curr[PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1 - builtin_offset]; let p0_next = &next[PERMUTATION_ARGUMENT_RANGE_CHECK_COL_1 - builtin_offset]; @@ -903,7 +898,7 @@ fn permutation_argument_range_check( } fn frame_inst_size(frame_row: &[FE]) -> FE { - &frame_row[F_OP_1_VAL] + FE::one() + frame_row[F_OP_1_VAL] + FE::one() } fn range_check_builtin( @@ -916,15 +911,15 @@ fn range_check_builtin( } fn evaluate_range_check_builtin_constraint(curr: &[FE]) -> FE { - &curr[RC_0] - + &curr[RC_1] * &FE::from_hex("10000").unwrap() - + &curr[RC_2] * &FE::from_hex("100000000").unwrap() - + &curr[RC_3] * &FE::from_hex("1000000000000").unwrap() - + &curr[RC_4] * &FE::from_hex("10000000000000000").unwrap() - + &curr[RC_5] * &FE::from_hex("100000000000000000000").unwrap() - + &curr[RC_6] * &FE::from_hex("1000000000000000000000000").unwrap() - + &curr[RC_7] * &FE::from_hex("10000000000000000000000000000").unwrap() - - &curr[RC_VALUE] + curr[RC_0] + + curr[RC_1] * FE::from_hex("10000").unwrap() + + curr[RC_2] * FE::from_hex("100000000").unwrap() + + curr[RC_3] * FE::from_hex("1000000000000").unwrap() + + curr[RC_4] * FE::from_hex("10000000000000000").unwrap() + + curr[RC_5] * FE::from_hex("100000000000000000000").unwrap() + + curr[RC_6] * FE::from_hex("1000000000000000000000000").unwrap() + + curr[RC_7] * FE::from_hex("10000000000000000000000000000").unwrap() + - curr[RC_VALUE] } #[cfg(test)] diff --git a/src/cairo/decode/instruction_flags.rs b/src/cairo/decode/instruction_flags.rs index 826e85cd..6c69f86f 100644 --- a/src/cairo/decode/instruction_flags.rs +++ b/src/cairo/decode/instruction_flags.rs @@ -1,5 +1,4 @@ use crate::{cairo::errors::InstructionDecodingError, FE}; -use lambdaworks_math::traits::ByteConversion; // Constants for instructions decoding const DST_REG_MASK: u64 = 0x0001; diff --git a/src/cairo/execution_trace.rs b/src/cairo/execution_trace.rs index a0cf7852..f89b549e 100644 --- a/src/cairo/execution_trace.rs +++ b/src/cairo/execution_trace.rs @@ -210,7 +210,7 @@ fn get_memory_holes(sorted_addrs: &[FE], codelen: usize) -> Vec { while hole_addr.representative() < addr.representative() { if hole_addr.representative() > (codelen as u64).into() { - memory_holes.push(hole_addr.clone()); + memory_holes.push(hole_addr); } hole_addr += FE::one(); } @@ -246,7 +246,7 @@ fn fill_memory_holes(trace: &mut TraceTable, memory_holes: & // columns. addr_cols.iter().for_each(|a_col| { if let Some(hole) = memory_holes_iter.next() { - padding_row[*a_col] = hole.clone(); + padding_row[*a_col] = *hole; } }); @@ -303,7 +303,7 @@ pub fn build_cairo_execution_trace( let instructions: Vec = raw_trace .rows .iter() - .map(|t| memory.get(&t.pc).unwrap().clone()) + .map(|t| *memory.get(&t.pc).unwrap()) .collect(); // t0, t1 and mul derived values are constructed. For details refer to @@ -311,7 +311,7 @@ pub fn build_cairo_execution_trace( let t0: Vec = trace_repr_flags .iter() .zip(&dsts) - .map(|(repr_flags, dst)| repr_flags[9].clone() * dst) + .map(|(repr_flags, dst)| repr_flags[9] * dst) .collect(); let t1: Vec = t0.iter().zip(&res).map(|(t, r)| t * r).collect(); let mul: Vec = op0s.iter().zip(&op1s).map(|(op0, op1)| op0 * op1).collect(); @@ -372,8 +372,7 @@ fn add_rc_builtin_columns( trace_cols.push(column.to_vec()) }); - let mut rc_values_dereferenced: Vec = - range_checked_values.iter().map(|&x| x.clone()).collect(); + let mut rc_values_dereferenced: Vec = range_checked_values.iter().map(|&&x| x).collect(); rc_values_dereferenced.resize(trace_cols[0].len(), FE::zero()); trace_cols.push(rc_values_dereferenced); @@ -417,7 +416,7 @@ fn compute_res(flags: &[CairoInstructionFlags], op0s: &[FE], op1s: &[FE], dsts: // values later on. // See section 9.5 of the Cairo whitepaper, page 53. if dst == &FE::zero() { - dst.clone() + *dst } else { dst.inv() } @@ -428,7 +427,7 @@ fn compute_res(flags: &[CairoInstructionFlags], op0s: &[FE], op1s: &[FE], dsts: } } PcUpdate::Regular | PcUpdate::Jump | PcUpdate::JumpRel => match f.res_logic { - ResLogic::Op1 => op1.clone(), + ResLogic::Op1 => *op1, ResLogic::Add => op0 + op1, ResLogic::Mul => op0 * op1, ResLogic::Unconstrained => { @@ -464,11 +463,11 @@ fn compute_dst( .map(|((f, o), t)| match f.dst_reg { DstReg::AP => { let addr = t.ap.checked_add_signed(o.off_dst.into()).unwrap(); - (FE::from(addr), memory.get(&addr).unwrap().clone()) + (FE::from(addr), memory.get(&addr).unwrap()) } DstReg::FP => { let addr = t.fp.checked_add_signed(o.off_dst.into()).unwrap(); - (FE::from(addr), memory.get(&addr).unwrap().clone()) + (FE::from(addr), memory.get(&addr).unwrap()) } }) .unzip() @@ -498,11 +497,11 @@ fn compute_op0( .map(|((f, o), t)| match f.op0_reg { Op0Reg::AP => { let addr = t.ap.checked_add_signed(o.off_op0.into()).unwrap(); - (FE::from(addr), memory.get(&addr).unwrap().clone()) + (FE::from(addr), memory.get(&addr).unwrap()) } Op0Reg::FP => { let addr = t.fp.checked_add_signed(o.off_op0.into()).unwrap(); - (FE::from(addr), memory.get(&addr).unwrap().clone()) + (FE::from(addr), memory.get(&addr).unwrap()) } }) .unzip() @@ -547,22 +546,22 @@ fn compute_op1( let addr = aux_get_last_nim_of_field_element(op0) .checked_add_signed(offset.off_op1.into()) .unwrap(); - (FE::from(addr), memory.get(&addr).unwrap().clone()) + (FE::from(addr), memory.get(&addr).unwrap()) } Op1Src::Imm => { let pc = trace_state.pc; let addr = pc.checked_add_signed(offset.off_op1.into()).unwrap(); - (FE::from(addr), memory.get(&addr).unwrap().clone()) + (FE::from(addr), memory.get(&addr).unwrap()) } Op1Src::AP => { let ap = trace_state.ap; let addr = ap.checked_add_signed(offset.off_op1.into()).unwrap(); - (FE::from(addr), memory.get(&addr).unwrap().clone()) + (FE::from(addr), memory.get(&addr).unwrap()) } Op1Src::FP => { let fp = trace_state.fp; let addr = fp.checked_add_signed(offset.off_op1.into()).unwrap(); - (FE::from(addr), memory.get(&addr).unwrap().clone()) + (FE::from(addr), memory.get(&addr).unwrap()) } }) .unzip() @@ -587,7 +586,7 @@ fn update_values( op0s[i] = (register_states.rows[i].pc + instruction_size).into(); dst[i] = register_states.rows[i].fp.into(); } else if f.opcode == CairoOpcode::AssertEq { - res[i] = dst[i].clone(); + res[i] = dst[i]; } } } @@ -601,7 +600,7 @@ fn rows_to_cols(rows: &[[FE; N]]) -> Vec> { for col_idx in 0..n_cols { let mut col = Vec::new(); for row in rows { - col.push(row[col_idx].clone()); + col.push(row[col_idx]); } cols.push(col); } diff --git a/src/starks/constraints/boundary.rs b/src/starks/constraints/boundary.rs index 42d4b0b0..3250bc2a 100644 --- a/src/starks/constraints/boundary.rs +++ b/src/starks/constraints/boundary.rs @@ -133,8 +133,8 @@ mod test { // * a0 = 1 // * a1 = 1 // * a7 = 32 - let a0 = BoundaryConstraint::new_simple(0, one.clone()); - let a1 = BoundaryConstraint::new_simple(1, one.clone()); + let a0 = BoundaryConstraint::new_simple(0, one); + let a1 = BoundaryConstraint::new_simple(1, one); let result = BoundaryConstraint::new_simple(7, FieldElement::::from(32)); let constraints = BoundaryConstraints::from_constraints(vec![a0, a1, result]); @@ -142,9 +142,9 @@ mod test { let primitive_root = PrimeField::get_primitive_root_of_unity(3).unwrap(); // P_0(x) = (x - 1) - let a0_zerofier = Polynomial::new(&[-one.clone(), one.clone()]); + let a0_zerofier = Polynomial::new(&[-one, one]); // P_1(x) = (x - w^1) - let a1_zerofier = Polynomial::new(&[-primitive_root.pow(1u32), one.clone()]); + let a1_zerofier = Polynomial::new(&[-primitive_root.pow(1u32), one]); // P_res(x) = (x - w^7) let res_zerofier = Polynomial::new(&[-primitive_root.pow(7u32), one]); diff --git a/src/starks/constraints/evaluator.rs b/src/starks/constraints/evaluator.rs index 63403559..d9b6e5a0 100644 --- a/src/starks/constraints/evaluator.rs +++ b/src/starks/constraints/evaluator.rs @@ -7,11 +7,10 @@ use lambdaworks_math::{ #[cfg(debug_assertions)] use crate::starks::debug::check_boundary_polys_divisibility; -use crate::starks::domain::Domain; use crate::starks::frame::Frame; -use crate::starks::prover::evaluate_polynomial_on_lde_domain; use crate::starks::trace::TraceTable; use crate::starks::traits::AIR; +use crate::starks::{domain::Domain, prover::evaluate_polynomial_on_lde_domain_with_twiddles}; use super::{boundary::BoundaryConstraints, evaluation_table::ConstraintEvaluationTable}; use std::iter::zip; @@ -54,7 +53,7 @@ impl<'poly, F: IsFFTField, A: AIR + AIR> ConstraintEvaluator<'poly, F // The + 1 is for the boundary constraints column let mut evaluation_table = ConstraintEvaluationTable::new( self.air.context().num_transition_constraints() + 1, - &domain.lde_roots_of_unity_coset, + &domain.twiddles, ); let n_trace_colums = self.trace_polys.len(); let boundary_constraints = &self.boundary_constraints; @@ -76,11 +75,12 @@ impl<'poly, F: IsFFTField, A: AIR + AIR> ConstraintEvaluator<'poly, F #[cfg(debug_assertions)] boundary_polys.push(boundary_poly.clone()); - evaluate_polynomial_on_lde_domain( + evaluate_polynomial_on_lde_domain_with_twiddles( &boundary_poly, domain.blowup_factor, domain.interpolation_domain_size, &domain.coset_offset, + &domain.twiddles, ) .unwrap() }) @@ -98,11 +98,12 @@ impl<'poly, F: IsFFTField, A: AIR + AIR> ConstraintEvaluator<'poly, F #[cfg(debug_assertions)] boundary_zerofiers.push(zerofier.clone()); - let mut evals = evaluate_polynomial_on_lde_domain( + let mut evals = evaluate_polynomial_on_lde_domain_with_twiddles( &zerofier, domain.blowup_factor, domain.interpolation_domain_size, &domain.coset_offset, + &domain.twiddles, ) .unwrap(); FieldElement::inplace_batch_inverse(&mut evals); @@ -126,11 +127,12 @@ impl<'poly, F: IsFFTField, A: AIR + AIR> ConstraintEvaluator<'poly, F let transition_exemptions_evaluations: Vec<_> = transition_exemptions .iter() .map(|exemption| { - evaluate_polynomial_on_lde_domain( + evaluate_polynomial_on_lde_domain_with_twiddles( exemption, domain.blowup_factor, domain.interpolation_domain_size, &domain.coset_offset, + &domain.twiddles, ) .unwrap() }) diff --git a/src/starks/domain.rs b/src/starks/domain.rs index d35b2f60..ebd09561 100644 --- a/src/starks/domain.rs +++ b/src/starks/domain.rs @@ -1,6 +1,9 @@ use lambdaworks_math::{ - fft::cpu::roots_of_unity::get_powers_of_primitive_root_coset, - field::{element::FieldElement, traits::IsFFTField}, + fft::cpu::roots_of_unity::{get_powers_of_primitive_root, get_powers_of_primitive_root_coset}, + field::{ + element::FieldElement, + traits::{IsFFTField, RootsConfig}, + }, }; use super::traits::AIR; @@ -14,6 +17,7 @@ pub struct Domain { pub(crate) coset_offset: FieldElement, pub(crate) blowup_factor: usize, pub(crate) interpolation_domain_size: usize, + pub(crate) twiddles: Vec>, } impl Domain { @@ -35,11 +39,15 @@ impl Domain { ) .unwrap(); - let lde_root_order = (air.trace_length() * blowup_factor).trailing_zeros(); - let lde_roots_of_unity_coset = get_powers_of_primitive_root_coset( + let lde_size = air.trace_length() * blowup_factor; + let lde_root_order = lde_size.trailing_zeros(); + let lde_roots_of_unity_coset = + get_powers_of_primitive_root_coset(lde_root_order as u64, lde_size, &coset_offset) + .unwrap(); + let twiddles = get_powers_of_primitive_root( lde_root_order as u64, - air.trace_length() * blowup_factor, - &coset_offset, + lde_size / 2, + RootsConfig::BitReverse, ) .unwrap(); @@ -52,6 +60,7 @@ impl Domain { blowup_factor, coset_offset, interpolation_domain_size, + twiddles, } } } diff --git a/src/starks/example/dummy_air.rs b/src/starks/example/dummy_air.rs index 89c4aeda..25b8b6f6 100644 --- a/src/starks/example/dummy_air.rs +++ b/src/starks/example/dummy_air.rs @@ -51,9 +51,9 @@ impl AIR for DummyAIR { let second_row = frame.get_row(1); let third_row = frame.get_row(2); - let f_constraint = &first_row[0] * (&first_row[0] - FieldElement::one()); + let f_constraint = first_row[0] * (first_row[0] - FieldElement::one()); - let fib_constraint = &third_row[1] - &second_row[1] - &first_row[1]; + let fib_constraint = third_row[1] - second_row[1] - first_row[1]; vec![f_constraint, fib_constraint] } diff --git a/src/starks/example/fibonacci_2_columns.rs b/src/starks/example/fibonacci_2_columns.rs index 77413558..c421385f 100644 --- a/src/starks/example/fibonacci_2_columns.rs +++ b/src/starks/example/fibonacci_2_columns.rs @@ -54,8 +54,8 @@ impl AIR for Fibonacci2ColsAIR { // constraints of Fibonacci sequence (2 terms per step): // s_{0, i+1} = s_{0, i} + s_{1, i} // s_{1, i+1} = s_{1, i} + s_{0, i+1} - let first_transition = &second_row[0] - &first_row[0] - &first_row[1]; - let second_transition = &second_row[1] - &first_row[1] - &second_row[0]; + let first_transition = second_row[0] - first_row[0] - first_row[1]; + let second_transition = second_row[1] - first_row[1] - second_row[0]; vec![first_transition, second_transition] } diff --git a/src/starks/example/fibonacci_rap.rs b/src/starks/example/fibonacci_rap.rs index b977ca7e..913d1e9a 100644 --- a/src/starks/example/fibonacci_rap.rs +++ b/src/starks/example/fibonacci_rap.rs @@ -56,8 +56,8 @@ impl AIR for FibonacciRAP { aux_col.push(FieldElement::::one()); } else { let z_i = &aux_col[i - 1]; - let n_p_term = not_perm[i - 1].clone() + gamma; - let p_term = &perm[i - 1] + gamma; + let n_p_term = not_perm[i - 1] + gamma; + let p_term = perm[i - 1] + gamma; aux_col.push(z_i * n_p_term.div(p_term)); } @@ -83,8 +83,7 @@ impl AIR for FibonacciRAP { let second_row = frame.get_row(1); let third_row = frame.get_row(2); - let mut constraints = - vec![third_row[0].clone() - second_row[0].clone() - first_row[0].clone()]; + let mut constraints = vec![third_row[0] - second_row[0] - first_row[0]]; // Auxiliary constraints let z_i = &frame.get_row(0)[2]; diff --git a/src/starks/example/quadratic_air.rs b/src/starks/example/quadratic_air.rs index 81b2a393..e02da6ec 100644 --- a/src/starks/example/quadratic_air.rs +++ b/src/starks/example/quadratic_air.rs @@ -51,7 +51,7 @@ impl AIR for QuadraticAIR { let first_row = frame.get_row(0); let second_row = frame.get_row(1); - vec![&second_row[0] - &first_row[0] * &first_row[0]] + vec![second_row[0] - first_row[0] * first_row[0]] } fn number_auxiliary_rap_columns(&self) -> usize { diff --git a/src/starks/example/simple_fibonacci.rs b/src/starks/example/simple_fibonacci.rs index 7ffe5d3c..8f003318 100644 --- a/src/starks/example/simple_fibonacci.rs +++ b/src/starks/example/simple_fibonacci.rs @@ -55,7 +55,7 @@ impl AIR for FibonacciAIR { let second_row = frame.get_row(1); let third_row = frame.get_row(2); - vec![third_row[0].clone() - second_row[0].clone() - first_row[0].clone()] + vec![third_row[0] - second_row[0] - first_row[0]] } fn boundary_constraints( diff --git a/src/starks/prover.rs b/src/starks/prover.rs index 05230e05..7b144d7f 100644 --- a/src/starks/prover.rs +++ b/src/starks/prover.rs @@ -117,6 +117,28 @@ where } } +pub fn evaluate_polynomial_on_lde_domain_with_twiddles( + p: &Polynomial>, + blowup_factor: usize, + domain_size: usize, + offset: &FieldElement, + twiddles: &[FieldElement], +) -> Result>, FFTError> +where + F: IsFFTField, + Polynomial>: FFTPoly, +{ + // Evaluate those polynomials t_j on the large domain D_LDE. + let evaluations = p + .evaluate_offset_fft_with_twiddles(blowup_factor, Some(domain_size), offset, twiddles) + .unwrap(); + let step = evaluations.len() / (domain_size * blowup_factor); + match step { + 1 => Ok(evaluations), + _ => Ok(evaluations.into_iter().step_by(step).collect()), + } +} + #[allow(clippy::type_complexity)] fn interpolate_and_commit( trace: &TraceTable, @@ -139,11 +161,12 @@ where let lde_trace_evaluations = trace_polys .iter() .map(|poly| { - evaluate_polynomial_on_lde_domain( + evaluate_polynomial_on_lde_domain_with_twiddles( poly, domain.blowup_factor, domain.interpolation_domain_size, &domain.coset_offset, + &domain.twiddles, ) }) .collect::>>, FFTError>>() @@ -744,9 +767,11 @@ mod tests { use super::*; use lambdaworks_math::{ + fft::cpu::roots_of_unity::get_powers_of_primitive_root, field::{ - element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, - traits::IsFFTField, + element::FieldElement, + fields::fft_friendly::stark_252_prime_field::Stark252PrimeField, + traits::{IsFFTField, RootsConfig}, }, polynomial::Polynomial, }; @@ -822,7 +847,7 @@ mod tests { for (i, evaluation) in lde_evaluation.iter().enumerate() { assert_eq!( *evaluation, - poly.evaluate(&(&coset_offset * primitive_root.pow(i))) + poly.evaluate(&(coset_offset * primitive_root.pow(i))) ); } } @@ -843,7 +868,36 @@ mod tests { ) .unwrap(); for (i, eval) in evaluations.iter().enumerate() { - assert_eq!(*eval, poly.evaluate(&(&offset * &primitive_root.pow(i)))); + assert_eq!(*eval, poly.evaluate(&(offset * primitive_root.pow(i)))); + } + } + + #[test] + fn test_evaluate_polynomial_with_and_without_twiddles() { + let trace = simple_fibonacci::fibonacci_trace([FE::from(1), FE::from(1)], 8); + let trace_polys = trace.compute_trace_polys(); + let coset_offset = FE::from(3); + let blowup_factor: usize = 2; + let domain_size = 8; + let lde_size = domain_size * blowup_factor; + let lde_root_order = lde_size.trailing_zeros().into(); + let twiddles = + get_powers_of_primitive_root(lde_root_order, lde_size / 2, RootsConfig::BitReverse) + .unwrap(); + + for poly in trace_polys.iter() { + let lde_evaluation = + evaluate_polynomial_on_lde_domain(poly, blowup_factor, domain_size, &coset_offset) + .unwrap(); + let lde_evaluation_twiddles = evaluate_polynomial_on_lde_domain_with_twiddles( + poly, + blowup_factor, + domain_size, + &coset_offset, + &twiddles, + ) + .unwrap(); + assert_eq!(lde_evaluation, lde_evaluation_twiddles); } } } diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 6fe0c355..052d7028 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -348,7 +348,7 @@ fn test_verifier_rejects_proof_with_overflowing_range_check_value() { assert!(!verify(&proof, &cairo_air, &pub_inputs)); } -#[test_log::test] +#[test] fn test_verifier_rejects_proof_with_changed_output() { let program_content = std::fs::read(cairo0_program_path("output_program.json")).unwrap(); let (main_trace, cairo_air, mut public_input) =