Skip to content

Commit 8acf43e

Browse files
committed
remove POSEIDON_16_NULL_HASH_PTR from public input (move it to witness memory)
1 parent c68be47 commit 8acf43e

10 files changed

Lines changed: 34 additions & 32 deletions

File tree

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/target
22
.vscode
33
/docs/benchmark_graphs/.venv
4-
minimal_zkVM.synctex.gz
5-
.claude
4+
minimal_zkVM.synctex.gz

crates/lean_compiler/snark_lib.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,10 @@ def pop(self):
7070
ZERO_VEC_PTR = 0
7171
SAMPLING_DOMAIN_SEPARATOR_PTR = 16
7272
ONE_EF_PTR = 24
73-
POSEIDON_16_NULL_HASH_PTR = 29
74-
REPEATED_ONES_PTR = 37
73+
REPEATED_ONES_PTR = 29
7574
NUM_REPEATED_ONES_IN_RESERVED_MEMORY = 16
76-
EQ_MLE_COEFFS_PTR = 53
77-
NONRESERVED_PROGRAM_INPUT_START = 60
75+
EQ_MLE_COEFFS_PTR = 45
76+
NONRESERVED_PROGRAM_INPUT_START = 50
7877

7978

8079
def poseidon16(left, right, output, mode):

crates/lean_compiler/src/parser/parsers/literal.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use backend::*;
22
use lean_vm::{
33
EQ_MLE_COEFFS_PTR, NONRESERVED_PROGRAM_INPUT_START, NUM_REPEATED_ONES_IN_RESERVED_MEMORY, ONE_EF_PTR,
4-
POSEIDON_16_NULL_HASH_PTR, REPEATED_ONES_PTR, SAMPLING_DOMAIN_SEPARATOR_PTR, ZERO_VEC_PTR,
4+
REPEATED_ONES_PTR, SAMPLING_DOMAIN_SEPARATOR_PTR, ZERO_VEC_PTR,
55
};
66

77
use super::expression::ExpressionParser;
@@ -135,7 +135,6 @@ impl VarOrConstantParser {
135135
NONRESERVED_PROGRAM_INPUT_START,
136136
))),
137137
"ZERO_VEC_PTR" => Ok(SimpleExpr::Constant(ConstExpression::from(ZERO_VEC_PTR))),
138-
"POSEIDON_16_NULL_HASH_PTR" => Ok(SimpleExpr::Constant(ConstExpression::from(POSEIDON_16_NULL_HASH_PTR))),
139138
"ONE_EF_PTR" => Ok(SimpleExpr::Constant(ConstExpression::from(ONE_EF_PTR))),
140139
"REPEATED_ONES_PTR" => Ok(SimpleExpr::Constant(ConstExpression::from(REPEATED_ONES_PTR))),
141140
"NUM_REPEATED_ONES_IN_RESERVED_MEMORY" => Ok(SimpleExpr::Constant(ConstExpression::from(

crates/lean_prover/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub const WHIR_SUBSEQUENT_FOLDING_FACTOR: usize = 5;
2525
pub const RS_DOMAIN_INITIAL_REDUCTION_FACTOR: usize = 5;
2626

2727
pub const SNARK_DOMAIN_SEP: [F; 8] = F::new_array([
28-
459434519, 297494976, 1722838545, 1130849508, 622859451, 1840279103, 16871075, 1399912153,
28+
130704175, 1303721200, 493664240, 1035493700, 2063844858, 1410214009, 1938905908, 1696767928,
2929
]);
3030

3131
pub fn default_whir_config(starting_log_inv_rate: usize) -> WhirConfigBuilder {

crates/lean_prover/src/trace_gen.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use backend::*;
22
use lean_vm::*;
33
use std::{array, collections::BTreeMap, iter::repeat_n};
4-
use utils::{ToUsize, transposed_par_iter_mut};
4+
use utils::{ToUsize, get_poseidon_16_of_zero, transposed_par_iter_mut};
55

66
#[derive(Debug)]
77
pub struct ExecutionTrace {
@@ -92,8 +92,13 @@ pub fn get_execution_trace(bytecode: &Bytecode, execution_result: ExecutionResul
9292
});
9393

9494
let mut memory_padded = memory.0.par_iter().map(|&v| v.unwrap_or(F::ZERO)).collect::<Vec<F>>();
95+
96+
// Write poseidon(0) at the end of used memory for poseidon table padding rows
97+
let null_poseidon_16_hash_ptr = memory_padded.len();
98+
memory_padded.extend_from_slice(get_poseidon_16_of_zero());
99+
95100
// IMPORTANT: memory size should always be >= number of VM cycles
96-
let padded_memory_len = (memory.0.len().max(n_cycles).max(1 << MIN_LOG_N_ROWS_PER_TABLE)).next_power_of_two();
101+
let padded_memory_len = (memory_padded.len().max(n_cycles).max(1 << MIN_LOG_N_ROWS_PER_TABLE)).next_power_of_two();
97102
memory_padded.resize(padded_memory_len, F::ZERO);
98103

99104
let ExecutionResult { mut traces, .. } = execution_result;
@@ -113,7 +118,7 @@ pub fn get_execution_trace(bytecode: &Bytecode, execution_result: ExecutionResul
113118
},
114119
);
115120
for table in traces.keys().copied().collect::<Vec<_>>() {
116-
pad_table(&table, &mut traces);
121+
pad_table(&table, &mut traces, null_poseidon_16_hash_ptr);
117122
}
118123

119124
ExecutionTrace {
@@ -124,7 +129,7 @@ pub fn get_execution_trace(bytecode: &Bytecode, execution_result: ExecutionResul
124129
}
125130
}
126131

127-
fn pad_table(table: &Table, traces: &mut BTreeMap<Table, TableTrace>) {
132+
fn pad_table(table: &Table, traces: &mut BTreeMap<Table, TableTrace>, null_hash_ptr: usize) {
128133
let trace = traces.get_mut(table).unwrap();
129134
let h = trace.base[0].len();
130135
trace
@@ -136,7 +141,11 @@ fn pad_table(table: &Table, traces: &mut BTreeMap<Table, TableTrace>) {
136141
trace.non_padded_n_rows = h;
137142
trace.log_n_rows = log2_ceil_usize(h + 1).max(MIN_LOG_N_ROWS_PER_TABLE);
138143
let padding_len = (1 << trace.log_n_rows) - h;
139-
let padding_row = table.padding_row();
144+
let padding_row = if *table == Table::poseidon16() {
145+
default_poseidon_row(null_hash_ptr)
146+
} else {
147+
table.padding_row()
148+
};
140149
trace.base.par_iter_mut().enumerate().for_each(|(i, col)| {
141150
col.extend(repeat_n(padding_row[i], padding_len));
142151
});

crates/lean_vm/src/core/constants.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ pub const ENDING_PC: usize = 0;
4040
///
4141
/// [public_data] = [reserved_area] [program_input]
4242
///
43-
/// reserved_area: reserved for special constants (size = 48 field elements)
43+
/// reserved_area: reserved for special constants (size = 40 field elements)
4444
/// program_input: the input of the program we want to prove
4545
///
46-
/// [reserved_area] = [00000000] [00000000] [10000000] [10000] [poseidon_16(0) (8 FE)] [111..111 (16 FE)] [2 -1 -1 1]
46+
/// [reserved_area] = [00000000] [00000000] [10000000] [10000] [111..111 (16 FE)] [2 -1 -1 1]
4747
///
4848
/// pointing to 16 zeros
4949
pub const ZERO_VEC_PTR: usize = 0;
@@ -54,12 +54,9 @@ pub const SAMPLING_DOMAIN_SEPARATOR_PTR: usize = ZERO_VEC_PTR + 2 * DIGEST_LEN;
5454
/// pointing to [10000] (the multiplicative identity of EF, as DIMENSION base field elements)
5555
pub const ONE_EF_PTR: usize = SAMPLING_DOMAIN_SEPARATOR_PTR + DIGEST_LEN;
5656

57-
/// pointing to the 8 elements of poseidon_16(0)
58-
pub const POSEIDON_16_NULL_HASH_PTR: usize = ONE_EF_PTR + DIMENSION;
59-
6057
/// POINTING TO 111..111 (`NUM_REPEATED_ONES_IN_RESERVED_MEMORY` times)
6158
pub const NUM_REPEATED_ONES_IN_RESERVED_MEMORY: usize = 16;
62-
pub const REPEATED_ONES_PTR: usize = POSEIDON_16_NULL_HASH_PTR + DIGEST_LEN;
59+
pub const REPEATED_ONES_PTR: usize = ONE_EF_PTR + DIMENSION;
6360

6461
/// [2, -1, -1, 1] is useful to compute (xy + (1-x)(1-y)) = 2xy - x - y + 1 = dot_product([xy, x, y, 1], [2, -1, -1, 1])
6562
pub const EQ_MLE_COEFFS_LEN: usize = 4;

crates/lean_vm/src/execution/runner.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! VM execution runner
22
3-
use crate::core::{DIGEST_LEN, DIMENSION, F, NONRESERVED_PROGRAM_INPUT_START, POSEIDON_16_NULL_HASH_PTR, ZERO_VEC_PTR};
3+
use crate::core::{DIGEST_LEN, DIMENSION, F, NONRESERVED_PROGRAM_INPUT_START, ZERO_VEC_PTR};
44
use crate::diagnostics::{ExecutionMetadata, ExecutionResult, MemoryProfile, RunnerError};
55
use crate::execution::{ExecutionHistory, Memory};
66
use crate::isa::Bytecode;
@@ -12,7 +12,7 @@ use crate::{
1212
};
1313
use backend::*;
1414
use std::collections::{BTreeMap, BTreeSet};
15-
use utils::{ToUsize, get_poseidon_16_of_zero};
15+
use utils::ToUsize;
1616
use xmss::Poseidon16History;
1717

1818
#[derive(Debug)]
@@ -60,7 +60,6 @@ pub fn build_public_memory(non_reserved_public_input: &[F]) -> Vec<F> {
6060
// ONE in the extension field = [1, 0, 0, 0, 0]
6161
public_memory[ONE_EF_PTR] = F::ONE;
6262

63-
public_memory[POSEIDON_16_NULL_HASH_PTR..][..DIGEST_LEN].copy_from_slice(get_poseidon_16_of_zero());
6463
public_memory[REPEATED_ONES_PTR..][..NUM_REPEATED_ONES_IN_RESERVED_MEMORY].fill(F::ONE);
6564

6665
public_memory[EQ_MLE_COEFFS_PTR..][..EQ_MLE_COEFFS_LEN].copy_from_slice(&[F::TWO, F::NEG_ONE, F::NEG_ONE, F::ONE]);

crates/lean_vm/src/tables/poseidon_16/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::any::TypeId;
22

3-
use crate::{tables::poseidon_16::trace_gen::default_poseidon_row, *};
3+
use crate::*;
44
use backend::*;
55
use utils::{ToUsize, poseidon16_compress};
66

77
mod trace_gen;
8-
pub use trace_gen::fill_trace_poseidon_16;
8+
pub use trace_gen::{default_poseidon_row, fill_trace_poseidon_16};
99

1010
pub(super) const WIDTH: usize = 16;
1111
const HALF_INITIAL_FULL_ROUNDS: usize = KOALABEAR_RC16_EXTERNAL_INITIAL.len() / 2;
@@ -65,7 +65,8 @@ impl<const BUS: bool> TableT for Poseidon16Precompile<BUS> {
6565
}
6666

6767
fn padding_row(&self) -> Vec<F> {
68-
default_poseidon_row()
68+
// depends on null_poseidon_16_hash_ptr (cf lean_prover/trace_gen.rs)
69+
unreachable!()
6970
}
7071

7172
#[inline(always)]

crates/lean_vm/src/tables/poseidon_16/trace_gen.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use tracing::instrument;
22

33
use crate::{
4-
F, POSEIDON_16_NULL_HASH_PTR, ZERO_VEC_PTR,
4+
F, ZERO_VEC_PTR,
55
tables::{Poseidon2Cols, WIDTH, num_cols_poseidon_16},
66
};
77
use backend::*;
@@ -41,7 +41,7 @@ pub fn fill_trace_poseidon_16(trace: &mut [Vec<F>]) {
4141
}
4242
}
4343

44-
pub fn default_poseidon_row() -> Vec<F> {
44+
pub fn default_poseidon_row(null_hash_ptr: usize) -> Vec<F> {
4545
let mut row = vec![F::ZERO; num_cols_poseidon_16()];
4646
let ptrs: [*mut F; num_cols_poseidon_16()] = std::array::from_fn(|i| unsafe { row.as_mut_ptr().add(i) });
4747

@@ -50,7 +50,7 @@ pub fn default_poseidon_row() -> Vec<F> {
5050
*perm.flag = F::ZERO;
5151
*perm.index_a = F::from_usize(ZERO_VEC_PTR);
5252
*perm.index_b = F::from_usize(ZERO_VEC_PTR);
53-
*perm.index_res = F::from_usize(POSEIDON_16_NULL_HASH_PTR);
53+
*perm.index_res = F::from_usize(null_hash_ptr);
5454

5555
generate_trace_rows_for_perm(perm);
5656
row

src/prove_poseidons.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use air::{check_air_validity, prove_air, verify_air};
22
use backend::*;
33
use lean_vm::{
44
EF, ExtraDataForBuses, F, POSEIDON_16_COL_A, POSEIDON_16_COL_B, POSEIDON_16_COL_FLAG, POSEIDON_16_COL_INPUT_START,
5-
POSEIDON_16_COL_RES, POSEIDON_16_NULL_HASH_PTR, Poseidon16Precompile, ZERO_VEC_PTR, fill_trace_poseidon_16,
6-
num_cols_poseidon_16,
5+
POSEIDON_16_COL_RES, Poseidon16Precompile, ZERO_VEC_PTR, fill_trace_poseidon_16, num_cols_poseidon_16,
76
};
87
use rand::{Rng, SeedableRng, rngs::StdRng};
98
use utils::{
@@ -29,7 +28,7 @@ pub fn benchmark_prove_poseidon_16(log_n_rows: usize, tracing: bool) {
2928
*t = (0..n_rows).map(|_| rng.random()).collect();
3029
}
3130
trace[POSEIDON_16_COL_FLAG] = (0..n_rows).map(|_| F::ONE).collect();
32-
trace[POSEIDON_16_COL_RES] = (0..n_rows).map(|_| F::from_usize(POSEIDON_16_NULL_HASH_PTR)).collect();
31+
trace[POSEIDON_16_COL_RES] = (0..n_rows).map(|_| F::ZERO).collect(); // useless
3332
trace[POSEIDON_16_COL_A] = (0..n_rows).map(|_| F::from_usize(ZERO_VEC_PTR)).collect();
3433
trace[POSEIDON_16_COL_B] = (0..n_rows).map(|_| F::from_usize(ZERO_VEC_PTR)).collect();
3534
fill_trace_poseidon_16(&mut trace);

0 commit comments

Comments
 (0)