From 785ae182195203d2ef3573c1390d6f36fbdae222 Mon Sep 17 00:00:00 2001 From: Softcloud Date: Sat, 30 Mar 2024 16:43:06 +0800 Subject: [PATCH] ADD: gen trace. --- circuits/src/generation/poseidon.rs | 138 ++++++++++++++++++++++ circuits/src/generation/poseidon_chunk.rs | 89 ++++++++++++++ circuits/src/generation/sccall.rs | 61 ++++++++++ circuits/src/generation/tape.rs | 68 +++++++++++ 4 files changed, 356 insertions(+) diff --git a/circuits/src/generation/poseidon.rs b/circuits/src/generation/poseidon.rs index f394fbe2..937fcff9 100644 --- a/circuits/src/generation/poseidon.rs +++ b/circuits/src/generation/poseidon.rs @@ -137,3 +137,141 @@ pub fn generate_poseidon_trace(cells: &[PoseidonRow]) -> [Vec; ) }) } + +pub fn gen_poseidon_trace( + batch_cells: &Vec>, +) -> [Vec; NUM_POSEIDON_COLS] { + let num_filled_row_len: usize = batch_cells.iter().map(|inner_vec| inner_vec.len()).sum(); + let num_padded_rows = if !num_filled_row_len.is_power_of_two() || num_filled_row_len < 2 { + if num_filled_row_len < 2 { + 2 + } else { + num_filled_row_len.next_power_of_two() + } + } else { + num_filled_row_len + }; + + let mut trace: Vec> = vec![vec![F::ZERO; num_padded_rows]; NUM_POSEIDON_COLS]; + let mut i = 0; + for tx_steps in batch_cells.iter() { + for c in tx_steps.iter() { + trace[FILTER_LOOKED_NORMAL][i] = if c.filter_looked_normal { + F::ONE + } else { + F::ZERO + }; + trace[FILTER_LOOKED_TREEKEY][i] = if c.filter_looked_treekey { + F::ONE + } else { + F::ZERO + }; + trace[FILTER_LOOKED_STORAGE_LEAF][i] = if c.filter_looked_storage { + F::ONE + } else { + F::ZERO + }; + trace[FILTER_LOOKED_STORAGE_BRANCH][i] = if c.filter_looked_storage_branch { + F::ONE + } else { + F::ZERO + }; + + for j in 0..12 { + trace[COL_POSEIDON_INPUT_RANGE.start + j][i] = + F::from_canonical_u64(c.input[j].to_canonical_u64()); + } + for j in 0..12 { + trace[COL_POSEIDON_OUTPUT_RANGE.start + j][i] = + F::from_canonical_u64(c.output[j].to_canonical_u64()); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_0_1_STATE_RANGE.start + j][i] = + F::from_canonical_u64(c.full_0_1[j].to_canonical_u64()); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_0_2_STATE_RANGE.start + j][i] = + F::from_canonical_u64(c.full_0_2[j].to_canonical_u64()); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_0_3_STATE_RANGE.start + j][i] = + F::from_canonical_u64(c.full_0_3[j].to_canonical_u64()); + } + for j in 0..22 { + trace[COL_POSEIDON_PARTIAL_ROUND_ELEMENT_RANGE.start + j][i] = + F::from_canonical_u64(c.partial[j].to_canonical_u64()); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_1_0_STATE_RANGE.start + j][i] = + F::from_canonical_u64(c.full_1_0[j].to_canonical_u64()); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_1_1_STATE_RANGE.start + j][i] = + F::from_canonical_u64(c.full_1_1[j].to_canonical_u64()); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_1_2_STATE_RANGE.start + j][i] = + F::from_canonical_u64(c.full_1_2[j].to_canonical_u64()); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_1_3_STATE_RANGE.start + j][i] = + F::from_canonical_u64(c.full_1_3[j].to_canonical_u64()); + } + i += 1; + } + } + + // Pad trace to power of two. + if num_padded_rows != num_filled_row_len { + for i in num_filled_row_len..num_padded_rows { + for j in 0..12 { + trace[COL_POSEIDON_INPUT_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_INPUT[j]); + } + for j in 0..12 { + trace[COL_POSEIDON_OUTPUT_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_OUTPUT[j]); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_0_1_STATE_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_FULL_0_1[j]); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_0_2_STATE_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_FULL_0_2[j]); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_0_3_STATE_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_FULL_0_3[j]); + } + for j in 0..22 { + trace[COL_POSEIDON_PARTIAL_ROUND_ELEMENT_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_PARTIAL[j]); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_1_0_STATE_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_FULL_1_0[j]); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_1_1_STATE_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_FULL_1_1[j]); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_1_2_STATE_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_FULL_1_2[j]); + } + for j in 0..12 { + trace[COL_POSEIDON_FULL_ROUND_1_3_STATE_RANGE.start + j][i] = + F::from_canonical_u64(POSEIDON_ZERO_HASH_FULL_1_3[j]); + } + } + } + + trace.try_into().unwrap_or_else(|v: Vec>| { + panic!( + "Expected a Vec of length {} but it was {}", + NUM_POSEIDON_COLS, + v.len() + ) + }) +} diff --git a/circuits/src/generation/poseidon_chunk.rs b/circuits/src/generation/poseidon_chunk.rs index d4028a79..cacd7d9b 100644 --- a/circuits/src/generation/poseidon_chunk.rs +++ b/circuits/src/generation/poseidon_chunk.rs @@ -86,3 +86,92 @@ pub fn generate_poseidon_chunk_trace( ) }) } + +pub fn gen_poseidon_chunk_trace( + batch_cells: &Vec>, +) -> [Vec; NUM_POSEIDON_CHUNK_COLS] { + let num_filled_row_len: usize = batch_cells.iter().map(|inner_vec| inner_vec.len()).sum(); + let num_padded_rows = if !num_filled_row_len.is_power_of_two() || num_filled_row_len < 2 { + if num_filled_row_len < 2 { + 2 + } else { + num_filled_row_len.next_power_of_two() + } + } else { + num_filled_row_len + }; + let mut trace: Vec> = vec![vec![F::ZERO; num_padded_rows]; NUM_POSEIDON_CHUNK_COLS]; + let mut i = 0; + for (tx_idx, tx_steps) in batch_cells.iter().enumerate() { + for c in tx_steps.iter() { + trace[COL_POSEIDON_CHUNK_TX_IDX][i] = F::from_canonical_usize(tx_idx); + trace[COL_POSEIDON_CHUNK_ENV_IDX][i] = F::from_canonical_u64(c.env_idx.0); + trace[COL_POSEIDON_CHUNK_CLK][i] = F::from_canonical_u32(c.clk); + trace[COL_POSEIDON_CHUNK_OPCODE][i] = F::from_canonical_u64(c.opcode.0); + trace[COL_POSEIDON_CHUNK_OP0][i] = F::from_canonical_u64(c.op0.0); + trace[COL_POSEIDON_CHUNK_OP1][i] = F::from_canonical_u64(c.op1.0); + trace[COL_POSEIDON_CHUNK_DST][i] = F::from_canonical_u64(c.dst.0); + trace[COL_POSEIDON_CHUNK_ACC_CNT][i] = F::from_canonical_u64(c.acc_cnt.0); + for j in 0..8 { + trace[COL_POSEIDON_CHUNK_VALUE_RANGE.start + j][i] = + F::from_canonical_u64(c.value[j].0); + } + for j in 0..4 { + trace[COL_POSEIDON_CHUNK_CAP_RANGE.start + j][i] = + F::from_canonical_u64(c.cap[j].0); + } + for j in 0..12 { + trace[COL_POSEIDON_CHUNK_HASH_RANGE.start + j][i] = + F::from_canonical_u64(c.hash[j].0); + } + trace[COL_POSEIDON_CHUNK_IS_EXT_LINE][i] = F::from_canonical_u64(c.is_ext_line.0); + trace[COL_POSEIDON_CHUNK_IS_RESULT_LINE][i] = if c.op1.0 == c.acc_cnt.0 { + F::ONE + } else { + F::ZERO + }; + if c.op1.0 == c.acc_cnt.0 { + let first_padding_index = (c.op1.0 % 8) as usize; + if first_padding_index != 0 { + trace[COL_POSEIDON_CHUNK_IS_FIRST_PADDING_RANGE.start + first_padding_index] + [i] = F::ONE + } + } + trace[COL_POSEIDON_CHUNK_FILTER_LOOKED_CPU][i] = if c.is_ext_line.0 == 0 { + F::ONE + } else { + F::ZERO + }; + if c.is_ext_line.0 == 1 { + for j in 0..8 { + trace[COL_POSEIDON_CHUNK_FILTER_LOOKING_MEM_RANGE.start + j][i] = F::ONE; + } + if c.op1.0 == c.acc_cnt.0 { + let first_padding_index = (c.op1.0 % 8) as usize; + if first_padding_index != 0 { + for j in first_padding_index..8 { + trace[COL_POSEIDON_CHUNK_FILTER_LOOKING_MEM_RANGE.start + j][i] = + F::ZERO + } + } + } + } + trace[COL_POSEIDON_CHUNK_FILTER_LOOKING_POSEIDON][i] = + F::from_canonical_u64(c.is_ext_line.0); + } + i += 1; + } + if num_padded_rows != num_filled_row_len { + for i in num_filled_row_len..num_padded_rows { + trace[COL_POSEIDON_CHUNK_IS_PADDING_LINE][i] = F::ONE; + } + } + + trace.try_into().unwrap_or_else(|v: Vec>| { + panic!( + "Expected a Vec of length {} but it was {}", + NUM_POSEIDON_CHUNK_COLS, + v.len() + ) + }) +} diff --git a/circuits/src/generation/sccall.rs b/circuits/src/generation/sccall.rs index 47ab4422..49355861 100644 --- a/circuits/src/generation/sccall.rs +++ b/circuits/src/generation/sccall.rs @@ -62,3 +62,64 @@ pub fn generate_sccall_trace(cells: &[SCCallRow]) -> [Vec; NUM_ ) }) } + +pub fn gen_sccall_trace( + batch_cells: &Vec>, +) -> [Vec; NUM_COL_SCCALL] { + let num_filled_row_len: usize = batch_cells.iter().map(|inner_vec| inner_vec.len()).sum(); + let num_padded_rows = if !num_filled_row_len.is_power_of_two() || num_filled_row_len < 2 { + if num_filled_row_len < 2 { + 2 + } else { + num_filled_row_len.next_power_of_two() + } + } else { + num_filled_row_len + }; + + let mut trace: Vec> = vec![vec![F::ZERO; num_padded_rows]; NUM_COL_SCCALL]; + let mut i = 0; + for (tx_idx, tx_steps) in batch_cells.iter().enumerate() { + for c in tx_steps.iter() { + trace[COL_SCCALL_TX_IDX][i] = F::from_canonical_usize(tx_idx); + trace[COL_SCCALL_CALLER_ENV_IDX][i] = + F::from_canonical_u64(c.caller_env_idx.to_canonical_u64()); + for j in 0..CTX_REGISTER_NUM { + trace[COL_SCCALL_CALLER_EXE_CTX_RANGE.start + j][i] = + F::from_canonical_u64(c.addr_storage[j].0); + } + for j in 0..CTX_REGISTER_NUM { + trace[COL_SCCALL_CALLER_CODE_CTX_RANGE.start + j][i] = + F::from_canonical_u64(c.addr_code[j].0); + } + trace[COL_SCCALL_CALLER_OP1_IMM][i] = + F::from_canonical_u64(c.caller_op1_imm.to_canonical_u64()); + trace[COL_SCCALL_CLK_CALLER_CALL][i] = + F::from_canonical_u64(c.clk_caller_call.to_canonical_u64()); + trace[COL_SCCALL_CLK_CALLER_RET][i] = + F::from_canonical_u64(c.clk_caller_ret.to_canonical_u64()); + for j in 0..REGISTER_NUM { + trace[COL_SCCALL_CALLER_REG_RANGE.start + j][i] = + F::from_canonical_u64(c.regs[j].0); + } + trace[COL_SCCALL_CALLEE_ENV_IDX][i] = + F::from_canonical_u64(c.callee_env_idx.to_canonical_u64()); + trace[COL_SCCALL_CLK_CALLEE_END][i] = + F::from_canonical_u64(c.clk_callee_end.to_canonical_u64()); + i += 1; + } + } + if num_padded_rows != num_filled_row_len { + for i in num_filled_row_len..num_padded_rows { + trace[COL_SCCALL_IS_PADDING][i] = F::ONE; + } + } + + trace.try_into().unwrap_or_else(|v: Vec>| { + panic!( + "Expected a Vec of length {} but it was {}", + NUM_COL_SCCALL, + v.len() + ) + }) +} diff --git a/circuits/src/generation/tape.rs b/circuits/src/generation/tape.rs index ce3c2d59..767b695f 100644 --- a/circuits/src/generation/tape.rs +++ b/circuits/src/generation/tape.rs @@ -71,3 +71,71 @@ pub fn generate_tape_trace(cells: &[TapeRow]) -> [Vec; NUM_COL_ ) }) } + +pub fn gen_tape_trace(batch_cells: &Vec>) -> [Vec; NUM_COL_TAPE] { + let num_filled_row_len: usize = batch_cells.iter().map(|inner_vec| inner_vec.len()).sum(); + let num_padded_rows = if !num_filled_row_len.is_power_of_two() || num_filled_row_len < 2 { + if num_filled_row_len < 2 { + 2 + } else { + num_filled_row_len.next_power_of_two() + } + } else { + num_filled_row_len + }; + + let mut trace: Vec> = vec![vec![F::ZERO; num_padded_rows]; NUM_COL_TAPE]; + let mut i = 0; + for (tx_idx, tx_steps) in batch_cells.iter().enumerate() { + for c in tx_steps.iter() { + trace[COL_TAPE_TX_IDX][i] = F::from_canonical_usize(tx_idx); + trace[COL_TAPE_IS_INIT_SEG][i] = if c.is_init { F::ONE } else { F::ZERO }; + trace[COL_TAPE_OPCODE][i] = F::from_canonical_u64(c.opcode.to_canonical_u64()); + trace[COL_TAPE_ADDR][i] = F::from_canonical_u64(c.addr.to_canonical_u64()); + trace[COL_TAPE_VALUE][i] = F::from_canonical_u64(c.value.to_canonical_u64()); + trace[COL_FILTER_LOOKED][i] = F::from_canonical_u64(c.filter_looked.to_canonical_u64()); + i += 1; + } + } + let last_tx_idx = if num_filled_row_len == 0 { + F::ZERO + } else { + trace[COL_TAPE_TX_IDX][num_filled_row_len - 1] + }; + let last_is_init = if num_filled_row_len == 0 { + F::ZERO + } else { + trace[COL_TAPE_IS_INIT_SEG][num_filled_row_len - 1] + }; + let last_addr = if num_filled_row_len == 0 { + F::ZERO + } else { + trace[COL_TAPE_ADDR][num_filled_row_len - 1] + }; + let last_value = if num_filled_row_len == 0 { + F::ZERO + } else { + trace[COL_TAPE_VALUE][num_filled_row_len - 1] + }; + + let op_tload = F::from_canonical_u64(OlaOpcode::TLOAD.binary_bit_mask()); + + if num_padded_rows != num_filled_row_len { + for i in num_filled_row_len..num_padded_rows { + trace[COL_TAPE_TX_IDX][i] = last_tx_idx; + trace[COL_TAPE_IS_INIT_SEG][i] = last_is_init; + trace[COL_TAPE_OPCODE][i] = op_tload; + trace[COL_TAPE_ADDR][i] = last_addr; + trace[COL_TAPE_VALUE][i] = last_value; + trace[COL_FILTER_LOOKED][i] = F::ZERO; + } + } + + trace.try_into().unwrap_or_else(|v: Vec>| { + panic!( + "Expected a Vec of length {} but it was {}", + NUM_COL_TAPE, + v.len() + ) + }) +}