@@ -5,6 +5,7 @@ use crate::{
55 context:: run_context:: RunContext ,
66 errors:: vm:: VirtualMachineError ,
77 memory:: { address:: MemoryAddress , manager:: MemoryManager } ,
8+ witness:: poseidon:: WitnessPoseidon16 ,
89} ;
910
1011/// Poseidon2 permutation over 16 field elements (2 inputs, 2 outputs).
@@ -73,4 +74,44 @@ impl Poseidon2_16Instruction {
7374
7475 Ok ( ( ) )
7576 }
77+
78+ /// Generates the witness for a `Poseidon2_16` instruction execution.
79+ pub fn generate_witness (
80+ & self ,
81+ cycle : usize ,
82+ run_context : & RunContext ,
83+ memory_manager : & MemoryManager ,
84+ ) -> Result < WitnessPoseidon16 , VirtualMachineError > {
85+ // Read the four pointers (input_a, input_b, output_a, output_b) from memory.
86+ let base_ptr_addr = ( run_context. fp + self . shift ) ?;
87+ let [ addr_input_a, addr_input_b, addr_output_a, addr_output_b] : [ MemoryAddress ; 4 ] =
88+ memory_manager. memory . get_array_as ( base_ptr_addr) ?;
89+
90+ // Read the two 8-element input vectors from their respective addresses.
91+ let value_a = memory_manager
92+ . memory
93+ . get_array_as :: < F , DIMENSION > ( addr_input_a) ?;
94+ let value_b = memory_manager
95+ . memory
96+ . get_array_as :: < F , DIMENSION > ( addr_input_b) ?;
97+
98+ // Read the two 8-element output vectors.
99+ let output_a = memory_manager
100+ . memory
101+ . get_array_as :: < F , DIMENSION > ( addr_output_a) ?;
102+ let output_b = memory_manager
103+ . memory
104+ . get_array_as :: < F , DIMENSION > ( addr_output_b) ?;
105+
106+ // Construct and return the witness struct.
107+ Ok ( WitnessPoseidon16 {
108+ cycle : Some ( cycle) ,
109+ addr_input_a,
110+ addr_input_b,
111+ // The output address is the start of the first output vector.
112+ addr_output : addr_output_a,
113+ input : [ value_a, value_b] . concat ( ) . try_into ( ) . unwrap ( ) ,
114+ output : [ output_a, output_b] . concat ( ) . try_into ( ) . unwrap ( ) ,
115+ } )
116+ }
76117}
0 commit comments