Skip to content

Commit

Permalink
refactor: Simplify logic for merkle_step
Browse files Browse the repository at this point in the history
changelog: ignore
  • Loading branch information
jan-ferdinand committed Jun 20, 2024
1 parent 84b5f48 commit a3c0f7f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 40 deletions.
2 changes: 1 addition & 1 deletion specification/src/arithmetization-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,5 @@ In order to gauge the runtime cost for this step, the following table provides e
<!-- auto-gen info start tasm_air_evaluation_cost -->
| Processor | Op Stack | RAM |
|----------:|---------:|------:|
| 34467 | 63963 | 22620 |
| 34469 | 63967 | 22617 |
<!-- auto-gen info stop tasm_air_evaluation_cost -->
8 changes: 4 additions & 4 deletions triton-vm/src/stark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1693,12 +1693,12 @@ pub(crate) mod tests {
}

#[test]
fn check_grand_cross_table_argument_for_test_program_for_merkle_step_no_switch() {
fn check_grand_cross_table_argument_for_test_program_for_merkle_step_right_sibling() {
check_grand_cross_table_argument(test_program_for_merkle_step_right_sibling())
}

#[test]
fn check_grand_cross_table_argument_for_test_program_for_merkle_step_switch() {
fn check_grand_cross_table_argument_for_test_program_for_merkle_step_left_sibling() {
check_grand_cross_table_argument(test_program_for_merkle_step_left_sibling())
}

Expand Down Expand Up @@ -2148,12 +2148,12 @@ pub(crate) mod tests {
}

#[test]
fn constraints_evaluate_to_zero_on_program_for_merkle_step_no_switch() {
fn constraints_evaluate_to_zero_on_program_for_merkle_step_right_sibling() {
triton_constraints_evaluate_to_zero(test_program_for_merkle_step_right_sibling())
}

#[test]
fn constraints_evaluate_to_zero_on_program_for_merkle_step_switch() {
fn constraints_evaluate_to_zero_on_program_for_merkle_step_left_sibling() {
triton_constraints_evaluate_to_zero(test_program_for_merkle_step_left_sibling())
}

Expand Down
21 changes: 10 additions & 11 deletions triton-vm/src/table/processor_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ impl ProcessorTable {
for row in base_table.rows() {
let ci = row[CI.base_table_index()];
if ci == Instruction::Hash.opcode_b() || ci == Instruction::MerkleStep.opcode_b() {
let is_left_sibling = row[HV5.base_table_index()].value() % 2 == 0;
let is_left_sibling = row[ST5.base_table_index()].value() % 2 == 0;
let hash_input = match Self::instruction_from_row(row) {
Some(Instruction::MerkleStep) if is_left_sibling => merkle_step_left_sibling,
Some(Instruction::MerkleStep) => merkle_step_right_sibling,
Expand Down Expand Up @@ -3435,7 +3435,7 @@ impl ExtProcessorTable {

// hash
let state_for_hash = [ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9].map(next_base_row);
let compressed_row_for_hash = weights
let compressed_hash_row = weights
.iter()
.zip_eq(state_for_hash)
.map(|(weight, state)| weight.clone() * state)
Expand All @@ -3458,24 +3458,23 @@ impl ExtProcessorTable {
merkle_step_state_element(HV3, ST3),
merkle_step_state_element(HV4, ST4),
];
let compressed_row_for_merkle_step = weights
let compressed_merkle_step_row = weights
.into_iter()
.zip_eq(state_for_merkle_step)
.map(|(weight, state)| weight * state)
.sum();

let running_evaluation_updates_for_hash = next_ext_row(HashInputEvalArg)
- challenge(HashInputIndeterminate) * curr_ext_row(HashInputEvalArg)
- compressed_row_for_hash;
let running_evaluation_updates_for_merkle_step = next_ext_row(HashInputEvalArg)
- challenge(HashInputIndeterminate) * curr_ext_row(HashInputEvalArg)
- compressed_row_for_merkle_step;
let running_evaluation_updates_with = |compressed_row| {
next_ext_row(HashInputEvalArg)
- challenge(HashInputIndeterminate) * curr_ext_row(HashInputEvalArg)
- compressed_row
};
let running_evaluation_remains =
next_ext_row(HashInputEvalArg) - curr_ext_row(HashInputEvalArg);

hash_and_merkle_step_selector * running_evaluation_remains
+ hash_deselector * running_evaluation_updates_for_hash
+ merkle_step_deselector * running_evaluation_updates_for_merkle_step
+ hash_deselector * running_evaluation_updates_with(compressed_hash_row)
+ merkle_step_deselector * running_evaluation_updates_with(compressed_merkle_step_row)
}

fn running_evaluation_hash_digest_updates_correctly(
Expand Down
41 changes: 17 additions & 24 deletions triton-vm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,35 +807,28 @@ impl VMState {
}

fn merkle_step(&mut self) -> Result<Vec<CoProcessorCall>> {
if self.secret_digests.is_empty() {
return Err(EmptySecretDigestInput);
}
self.op_stack.is_u32(ST5)?;

let accumulator_digest = self.op_stack.pop_multiple::<{ tip5::DIGEST_LENGTH }>()?;
let node_index = self.op_stack.pop_u32()?;

let node_index = self.op_stack[ST5];
let node_index = u32::try_from(node_index).map_err(|_| FailedU32Conversion(node_index))?;
let parent_node_index = node_index / 2;
self.op_stack.push(parent_node_index.into());

let stack_contains_left_node = node_index % 2 == 0;
let sibling_digest = self.pop_secret_digest()?;
let mut hash_input = Tip5::new(Domain::FixedLength);
if stack_contains_left_node {
hash_input.state[..tip5::DIGEST_LENGTH].copy_from_slice(&accumulator_digest);
hash_input.state[tip5::DIGEST_LENGTH..2 * tip5::DIGEST_LENGTH]
.copy_from_slice(&sibling_digest);
} else {
hash_input.state[..tip5::DIGEST_LENGTH].copy_from_slice(&sibling_digest);
hash_input.state[tip5::DIGEST_LENGTH..2 * tip5::DIGEST_LENGTH]
.copy_from_slice(&accumulator_digest);
}
let tip5_trace = hash_input.trace();
let accumulator_digest = &tip5_trace[tip5_trace.len() - 1][0..tip5::DIGEST_LENGTH];
let accumulator_digest = self.op_stack.pop_multiple::<{ tip5::DIGEST_LENGTH }>()?;
let (left_sibling, right_sibling) = match node_index % 2 {
0 => (&accumulator_digest, &sibling_digest),
1 => (&sibling_digest, &accumulator_digest),
_ => unreachable!(),
};

for i in (0..tip5::DIGEST_LENGTH).rev() {
self.op_stack.push(accumulator_digest[i]);
let mut tip5 = Tip5::new(Domain::FixedLength);
tip5.state[..tip5::DIGEST_LENGTH].copy_from_slice(left_sibling);
tip5.state[tip5::DIGEST_LENGTH..2 * tip5::DIGEST_LENGTH].copy_from_slice(right_sibling);
let tip5_trace = tip5.trace();
let accumulator_digest = &tip5_trace.last().unwrap()[0..tip5::DIGEST_LENGTH];

for &digest_element in accumulator_digest.iter().rev() {
self.op_stack.push(digest_element);
}
self.op_stack[ST5] = parent_node_index.into();

self.instruction_pointer += 1;

Expand Down

0 comments on commit a3c0f7f

Please sign in to comment.