1+ /// Represents an openvm program commitments and public values.
2+ #[ derive(
3+ Clone ,
4+ Debug ,
5+ rkyv:: Archive ,
6+ rkyv:: Deserialize ,
7+ rkyv:: Serialize ,
8+ serde:: Deserialize ,
9+ serde:: Serialize ,
10+ ) ]
11+ #[ rkyv( derive( Debug ) ) ]
12+ pub struct AggregationInput {
13+ /// Public values.
14+ pub public_values : Vec < u32 > ,
15+ /// Represent the commitment needed to verify a root proof
16+ pub commitment : ProgramCommitment ,
17+ }
18+
19+ /// Represent the commitment needed to verify a [`RootProof`].
20+ #[ derive(
21+ Clone ,
22+ Debug ,
23+ Default ,
24+ rkyv:: Archive ,
25+ rkyv:: Deserialize ,
26+ rkyv:: Serialize ,
27+ serde:: Deserialize ,
28+ serde:: Serialize ,
29+ ) ]
30+ #[ rkyv( derive( Debug ) ) ]
31+ pub struct ProgramCommitment {
32+ /// The commitment to the child program exe.
33+ pub exe : [ u32 ; 8 ] ,
34+ /// The commitment to the child program leaf.
35+ pub leaf : [ u32 ; 8 ] ,
36+ }
37+
38+ impl ProgramCommitment {
39+ pub fn deserialize ( commitment_bytes : & [ u8 ] ) -> Self {
40+ // TODO: temporary skip deserialize if no vk is provided
41+ if commitment_bytes. is_empty ( ) {
42+ return Default :: default ( ) ;
43+ }
44+
45+ let archived_data =
46+ rkyv:: access :: < ArchivedProgramCommitment , rkyv:: rancor:: BoxedError > ( commitment_bytes)
47+ . unwrap ( ) ;
48+
49+ Self {
50+ exe : archived_data. exe . map ( |u32_le| u32_le. to_native ( ) ) ,
51+ leaf : archived_data. leaf . map ( |u32_le| u32_le. to_native ( ) ) ,
52+ }
53+ }
54+
55+ pub fn serialize ( & self ) -> Vec < u8 > {
56+ rkyv:: to_bytes :: < rkyv:: rancor:: BoxedError > ( self )
57+ . map ( |v| v. to_vec ( ) )
58+ . unwrap ( )
59+ }
60+ }
61+
62+ impl From < & ArchivedProgramCommitment > for ProgramCommitment {
63+ fn from ( archived : & ArchivedProgramCommitment ) -> Self {
64+ Self {
65+ exe : archived. exe . map ( |u32_le| u32_le. to_native ( ) ) ,
66+ leaf : archived. leaf . map ( |u32_le| u32_le. to_native ( ) ) ,
67+ }
68+ }
69+ }
70+
71+ /// Number of public-input values, i.e. [u32; N].
72+ ///
73+ /// Note that the actual value for each u32 is a byte.
74+ const NUM_PUBLIC_VALUES : usize = 32 ;
75+
76+ /// Verify a root proof. The real "proof" will be loaded from StdIn.
77+ pub fn verify_proof ( commitment : & ProgramCommitment , public_inputs : & [ u32 ] ) {
78+ // Sanity check for the number of public-input values.
79+ assert_eq ! ( public_inputs. len( ) , NUM_PUBLIC_VALUES ) ;
80+
81+ // Extend the public-input values by prepending the commitments to the root verifier's exe and
82+ // leaf.
83+ let mut extended_public_inputs = vec ! [ ] ;
84+ extended_public_inputs. extend ( commitment. exe ) ;
85+ extended_public_inputs. extend ( commitment. leaf ) ;
86+ extended_public_inputs. extend_from_slice ( public_inputs) ;
87+ // Pass through kernel and verify against root verifier's ASM.
88+ exec_kernel ( extended_public_inputs. as_ptr ( ) ) ;
89+ }
90+
91+ fn exec_kernel ( _pi_ptr : * const u32 ) {
92+ // reserve x29, x30, x31 for kernel
93+ let mut _buf1: u32 = 0 ;
94+ let mut _buf2: u32 = 0 ;
95+ #[ cfg( all( target_os = "zkvm" , target_arch = "riscv32" ) ) ]
96+ unsafe {
97+ std:: arch:: asm!(
98+ include_str!( "../../../build-guest/root_verifier.asm" ) ,
99+ in( "x29" ) _pi_ptr,
100+ inout( "x30" ) _buf1,
101+ inout( "x31" ) _buf2,
102+ )
103+ }
104+ }
105+
106+ /// Witness for an [`AggregationCircuit`][AggCircuit] that also carries proofs that are being
107+ /// aggregated.
108+ pub trait ProofCarryingWitness {
109+ /// Get the root proofs from the witness.
110+ fn get_proofs ( & self ) -> Vec < AggregationInput > ;
111+ }
0 commit comments