Skip to content

Commit d994e78

Browse files
authored
Feat: support multi_observe (#12)
* fix1 * fix2 * execution wip * fix 3 * fix 4
1 parent 5cf6625 commit d994e78

File tree

6 files changed

+533
-73
lines changed

6 files changed

+533
-73
lines changed

extensions/native/circuit/src/extension/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ impl<F: PrimeField32> VmExecutionExtension<F> for Native {
165165
VerifyBatchOpcode::VERIFY_BATCH.global_opcode(),
166166
Poseidon2Opcode::PERM_POS2.global_opcode(),
167167
Poseidon2Opcode::COMP_POS2.global_opcode(),
168+
Poseidon2Opcode::MULTI_OBSERVE.global_opcode(),
168169
],
169170
)?;
170171

extensions/native/circuit/src/poseidon2/air.rs

Lines changed: 60 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use openvm_circuit_primitives::utils::not;
88
use openvm_instructions::LocalOpcode;
99
use openvm_native_compiler::{
1010
conversion::AS,
11-
Poseidon2Opcode::{COMP_POS2, PERM_POS2, MULTI_OBSERVE},
11+
Poseidon2Opcode::{COMP_POS2, MULTI_OBSERVE, PERM_POS2},
1212
VerifyBatchOpcode::VERIFY_BATCH,
1313
};
1414
use openvm_poseidon2_air::{
@@ -26,8 +26,8 @@ use openvm_stark_backend::{
2626
use crate::poseidon2::{
2727
chip::{NUM_INITIAL_READS, NUM_SIMPLE_ACCESSES},
2828
columns::{
29-
InsideRowSpecificCols, NativePoseidon2Cols, SimplePoseidonSpecificCols,
30-
TopLevelSpecificCols, MultiObserveCols,
29+
InsideRowSpecificCols, MultiObserveCols, NativePoseidon2Cols, SimplePoseidonSpecificCols,
30+
TopLevelSpecificCols,
3131
},
3232
};
3333

@@ -118,7 +118,8 @@ impl<AB: InteractionBuilder, const SBOX_REGISTERS: usize> Air<AB>
118118
builder.assert_bool(inside_row);
119119
builder.assert_bool(simple);
120120
builder.assert_bool(multi_observe_row);
121-
let enabled = incorporate_row + incorporate_sibling + inside_row + simple + multi_observe_row;
121+
let enabled =
122+
incorporate_row + incorporate_sibling + inside_row + simple + multi_observe_row;
122123
builder.assert_bool(enabled.clone());
123124
builder.assert_bool(end_inside_row);
124125
builder.when(end_inside_row).assert_one(inside_row);
@@ -730,18 +731,12 @@ impl<AB: InteractionBuilder, const SBOX_REGISTERS: usize> Air<AB>
730731
input_register_1,
731732
input_register_2,
732733
input_register_3,
733-
output_register
734+
output_register,
734735
} = multi_observe_specific;
735736

736-
builder
737-
.when(multi_observe_row)
738-
.assert_bool(is_first);
739-
builder
740-
.when(multi_observe_row)
741-
.assert_bool(is_last);
742-
builder
743-
.when(multi_observe_row)
744-
.assert_bool(should_permute);
737+
builder.when(multi_observe_row).assert_bool(is_first);
738+
builder.when(multi_observe_row).assert_bool(is_last);
739+
builder.when(multi_observe_row).assert_bool(should_permute);
745740

746741
self.execution_bridge
747742
.execute_and_increment_pc(
@@ -799,19 +794,19 @@ impl<AB: InteractionBuilder, const SBOX_REGISTERS: usize> Air<AB>
799794
let i_var = AB::F::from_canonical_usize(i);
800795
self.memory_bridge
801796
.read(
802-
MemoryAddress::new(self.address_space, input_ptr + curr_len + i_var - start_idx),
797+
MemoryAddress::new(
798+
self.address_space,
799+
input_ptr + curr_len + i_var - start_idx,
800+
),
803801
[data[i]],
804802
start_timestamp + i_var * AB::F::TWO - start_idx * AB::F::TWO,
805-
&read_data[i]
803+
&read_data[i],
806804
)
807805
.eval(builder, aux_after_start[i] * aux_before_end[i]);
808-
806+
809807
self.memory_bridge
810808
.write(
811-
MemoryAddress::new(
812-
self.address_space,
813-
state_ptr + i_var,
814-
),
809+
MemoryAddress::new(self.address_space, state_ptr + i_var),
815810
[data[i]],
816811
start_timestamp + i_var * AB::F::TWO - start_idx * AB::F::TWO + AB::F::ONE,
817812
&write_data[i],
@@ -835,59 +830,56 @@ impl<AB: InteractionBuilder, const SBOX_REGISTERS: usize> Air<AB>
835830
.when(multi_observe_row)
836831
.when(not(is_first))
837832
.assert_eq(
838-
aux_after_start[0]
839-
+ aux_after_start[1]
840-
+ aux_after_start[2]
841-
+ aux_after_start[3]
842-
+ aux_after_start[4]
843-
+ aux_after_start[5]
844-
+ aux_after_start[6]
845-
+ aux_after_start[7],
846-
AB::Expr::from_canonical_usize(CHUNK) - start_idx.into()
833+
aux_after_start[0]
834+
+ aux_after_start[1]
835+
+ aux_after_start[2]
836+
+ aux_after_start[3]
837+
+ aux_after_start[4]
838+
+ aux_after_start[5]
839+
+ aux_after_start[6]
840+
+ aux_after_start[7],
841+
AB::Expr::from_canonical_usize(CHUNK) - start_idx.into(),
847842
);
848843

849844
builder
850845
.when(multi_observe_row)
851846
.when(not(is_first))
852847
.assert_eq(
853848
aux_before_end[0]
854-
+ aux_before_end[1]
855-
+ aux_before_end[2]
856-
+ aux_before_end[3]
857-
+ aux_before_end[4]
858-
+ aux_before_end[5]
859-
+ aux_before_end[6]
860-
+ aux_before_end[7],
861-
end_idx
849+
+ aux_before_end[1]
850+
+ aux_before_end[2]
851+
+ aux_before_end[3]
852+
+ aux_before_end[4]
853+
+ aux_before_end[5]
854+
+ aux_before_end[6]
855+
+ aux_before_end[7],
856+
end_idx,
862857
);
863858

864-
let full_sponge_input = from_fn::<_, {CHUNK * 2}, _>(|i| local.inner.inputs[i]);
865-
let full_sponge_output = from_fn::<_, {CHUNK * 2}, _>(|i| local.inner.ending_full_rounds[BABY_BEAR_POSEIDON2_HALF_FULL_ROUNDS - 1].post[i]);
859+
let full_sponge_input = from_fn::<_, { CHUNK * 2 }, _>(|i| local.inner.inputs[i]);
860+
let full_sponge_output = from_fn::<_, { CHUNK * 2 }, _>(|i| {
861+
local.inner.ending_full_rounds[BABY_BEAR_POSEIDON2_HALF_FULL_ROUNDS - 1].post[i]
862+
});
866863

867864
self.memory_bridge
868865
.read(
869-
MemoryAddress::new(
870-
self.address_space,
871-
state_ptr,
872-
),
866+
MemoryAddress::new(self.address_space, state_ptr),
873867
full_sponge_input,
874-
start_timestamp + end_idx * AB::F::TWO - start_idx * AB::F::TWO,
868+
start_timestamp + (end_idx - start_idx) * AB::F::TWO,
875869
&read_sponge_state,
876870
)
877871
.eval(builder, multi_observe_row * should_permute);
878-
872+
879873
self.memory_bridge
880874
.write(
881-
MemoryAddress::new(
882-
self.address_space,
883-
state_ptr
884-
),
875+
MemoryAddress::new(self.address_space, state_ptr),
885876
full_sponge_output,
886-
start_timestamp + end_idx * AB::F::TWO - start_idx * AB::F::TWO + AB::F::ONE,
877+
start_timestamp + (end_idx - start_idx) * AB::F::TWO + AB::F::ONE,
887878
&write_sponge_state,
888879
)
889880
.eval(builder, multi_observe_row * should_permute);
890881

882+
/*
891883
self.memory_bridge
892884
.write(
893885
MemoryAddress::new(
@@ -899,13 +891,14 @@ impl<AB: InteractionBuilder, const SBOX_REGISTERS: usize> Air<AB>
899891
&write_final_idx
900892
)
901893
.eval(builder, multi_observe_row * is_last);
894+
*/
902895

903896
// Field transitions
904897
builder
905898
.when(next.multi_observe_row)
906899
.when(not(next_multi_observe_specific.is_first))
907900
.assert_eq(next_multi_observe_specific.curr_len, multi_observe_specific.curr_len + end_idx - start_idx);
908-
901+
909902
// Boundary conditions
910903
builder
911904
.when(multi_observe_row)
@@ -927,7 +920,7 @@ impl<AB: InteractionBuilder, const SBOX_REGISTERS: usize> Air<AB>
927920
.when(not(is_last))
928921
.assert_one(next.multi_observe_row);
929922

930-
// Field consistency
923+
// Fields remain same across same instance
931924
builder
932925
.when(next.multi_observe_row)
933926
.when(not(next_multi_observe_specific.is_first))
@@ -951,17 +944,26 @@ impl<AB: InteractionBuilder, const SBOX_REGISTERS: usize> Air<AB>
951944
builder
952945
.when(next.multi_observe_row)
953946
.when(not(next_multi_observe_specific.is_first))
954-
.assert_eq(input_register_1, next_multi_observe_specific.input_register_1);
947+
.assert_eq(
948+
input_register_1,
949+
next_multi_observe_specific.input_register_1,
950+
);
955951

956952
builder
957953
.when(next.multi_observe_row)
958954
.when(not(next_multi_observe_specific.is_first))
959-
.assert_eq(input_register_2, next_multi_observe_specific.input_register_2);
955+
.assert_eq(
956+
input_register_2,
957+
next_multi_observe_specific.input_register_2,
958+
);
960959

961960
builder
962961
.when(next.multi_observe_row)
963962
.when(not(next_multi_observe_specific.is_first))
964-
.assert_eq(input_register_3, next_multi_observe_specific.input_register_3);
963+
.assert_eq(
964+
input_register_3,
965+
next_multi_observe_specific.input_register_3,
966+
);
965967

966968
builder
967969
.when(next.multi_observe_row)
@@ -974,10 +976,12 @@ impl<AB: InteractionBuilder, const SBOX_REGISTERS: usize> Air<AB>
974976
.when(not(next_multi_observe_specific.is_first))
975977
.assert_eq(very_first_timestamp, next.very_first_timestamp);
976978

979+
/*
977980
builder
978981
.when(next.multi_observe_row)
979982
.when(not(next_multi_observe_specific.is_first))
980983
.assert_eq(next.start_timestamp, start_timestamp + is_first * AB::F::from_canonical_usize(4) + (end_idx - start_idx) * AB::F::TWO + should_permute * AB::F::TWO);
984+
*/
981985
}
982986
}
983987

0 commit comments

Comments
 (0)