@@ -15,6 +15,7 @@ use canonical::Canon;
1515#[ cfg( feature = "canon" ) ]
1616use canonical_derive:: Canon ;
1717use dusk_bls12_381:: BlsScalar ;
18+ use dusk_bytes:: { DeserializableSlice , Serializable , Write } ;
1819use dusk_jubjub:: { JubJubAffine , JubJubScalar } ;
1920
2021#[ derive( Default , Debug , Clone ) ]
@@ -41,6 +42,68 @@ impl From<JubJubAffine> for PublicInputValue {
4142 }
4243}
4344
45+ #[ derive( Debug , Clone ) ]
46+ /// Collection of structs/objects that the Verifier will use in order to
47+ /// de/serialize data needed for Circuit proof verification.
48+ /// This structure can be seen as a link between the [`Circuit`] public input
49+ /// positions and the [`VerifierKey`] that the Verifier needs to use.
50+ pub struct VerifierData {
51+ key : VerifierKey ,
52+ pi_pos : Vec < usize > ,
53+ }
54+
55+ impl VerifierData {
56+ /// Creates a new [`VerifierData`] from a [`VerifierKey`] and the public
57+ /// input positions of the circuit that it represents.
58+ pub const fn new ( key : VerifierKey , pi_pos : Vec < usize > ) -> Self {
59+ Self { key, pi_pos }
60+ }
61+
62+ /// Returns a reference to the contained [`VerifierKey`].
63+ pub const fn key ( & self ) -> & VerifierKey {
64+ & self . key
65+ }
66+
67+ /// Returns a reference to the contained Public Input positions.
68+ pub const fn pi_pos ( & self ) -> & Vec < usize > {
69+ & self . pi_pos
70+ }
71+
72+ /// Deserializes the [`VerifierData`] into a vector of bytes.
73+ #[ allow( unused_must_use) ]
74+ pub fn to_var_bytes ( & self ) -> Vec < u8 > {
75+ let mut buff =
76+ vec ! [
77+ 0u8 ;
78+ VerifierKey :: SIZE + u32 :: SIZE + self . pi_pos. len( ) * u32 :: SIZE
79+ ] ;
80+ let mut writer = & mut buff[ ..] ;
81+
82+ writer. write ( & self . key . to_bytes ( ) ) ;
83+ writer. write ( & ( self . pi_pos . len ( ) as u32 ) . to_bytes ( ) ) ;
84+ self . pi_pos . iter ( ) . copied ( ) . for_each ( |pos| {
85+ // Omit the result since disk_bytes write can't fail here
86+ // due to the fact that we're writing into a vector basically.
87+ let _ = writer. write ( & ( pos as u32 ) . to_bytes ( ) ) ;
88+ } ) ;
89+
90+ buff
91+ }
92+
93+ /// Serializes [`VerifierData`] from a slice of bytes.
94+ pub fn from_slice ( mut buf : & [ u8 ] ) -> Result < Self , Error > {
95+ let key = VerifierKey :: from_reader ( & mut buf) ?;
96+ let pos_num = u32:: from_reader ( & mut buf) ? as usize ;
97+
98+ let mut pi_pos = vec ! [ ] ;
99+ for _ in 0 ..pos_num {
100+ pi_pos. push ( u32:: from_reader ( & mut buf) ? as usize ) ;
101+ }
102+
103+ Ok ( Self { key, pi_pos } )
104+ }
105+ }
106+
44107/// Circuit representation for a gadget with all of the tools that it
45108/// should implement.
46109pub trait Circuit
56119 fn compile (
57120 & mut self ,
58121 pub_params : & PublicParameters ,
59- ) -> Result < ( ProverKey , VerifierKey , Vec < usize > ) , Error > {
122+ ) -> Result < ( ProverKey , VerifierData ) , Error > {
60123 use crate :: proof_system:: { Prover , Verifier } ;
61124 // Setup PublicParams
62125 let ( ck, _) = pub_params. trim ( self . padded_circuit_size ( ) ) ?;
@@ -74,10 +137,12 @@ where
74137 prover
75138 . prover_key
76139 . expect ( "Unexpected error. Missing ProverKey in compilation" ) ,
77- verifier
78- . verifier_key
79- . expect ( "Unexpected error. Missing VerifierKey in compilation" ) ,
80- pi_pos,
140+ VerifierData :: new (
141+ verifier. verifier_key . expect (
142+ "Unexpected error. Missing VerifierKey in compilation" ,
143+ ) ,
144+ pi_pos,
145+ ) ,
81146 ) )
82147 }
83148
@@ -149,8 +214,7 @@ fn build_pi(
149214mod tests {
150215 use super :: * ;
151216 use crate :: constraint_system:: { ecc:: * , StandardComposer } ;
152- use crate :: proof_system:: { ProverKey , VerifierKey } ;
153- use dusk_bytes:: { DeserializableSlice , Serializable } ;
217+ use crate :: proof_system:: ProverKey ;
154218
155219 // Implements a circuit that checks:
156220 // 1) a + b = c where C is a PI
@@ -229,46 +293,52 @@ mod tests {
229293 use std:: io:: Write ;
230294 use tempdir:: TempDir ;
231295
232- let tmp = TempDir :: new ( "plonk-keys-test-full" ) . unwrap ( ) . into_path ( ) ;
296+ let tmp = TempDir :: new ( "plonk-keys-test-full" )
297+ . expect ( "IO error" )
298+ . into_path ( ) ;
233299 let pp_path = tmp. clone ( ) . join ( "pp_testcirc" ) ;
234300 let pk_path = tmp. clone ( ) . join ( "pk_testcirc" ) ;
235- let vk_path = tmp. clone ( ) . join ( "vk_testcirc " ) ;
301+ let vd_path = tmp. clone ( ) . join ( "vd_testcirc " ) ;
236302
237303 // Generate CRS
238304 let pp_p = PublicParameters :: setup ( 1 << 12 , & mut rand:: thread_rng ( ) ) ?;
239305 File :: create ( & pp_path)
240306 . and_then ( |mut f| f. write ( pp_p. to_raw_var_bytes ( ) . as_slice ( ) ) )
241- . unwrap ( ) ;
307+ . expect ( "IO error" ) ;
242308
243309 // Read PublicParameters
244- let pp = fs:: read ( pp_path) . unwrap ( ) ;
310+ let pp = fs:: read ( pp_path) . expect ( "IO error" ) ;
245311 let pp =
246312 unsafe { PublicParameters :: from_slice_unchecked ( pp. as_slice ( ) ) } ;
247313
248314 // Initialize the circuit
249315 let mut circuit = TestCircuit :: default ( ) ;
250316
251317 // Compile the circuit
252- let ( pk_p, vk_p , pi_pos ) = circuit. compile ( & pp) ?;
318+ let ( pk_p, og_verifier_data ) = circuit. compile ( & pp) ?;
253319
254320 // Write the keys
255321 File :: create ( & pk_path)
256322 . and_then ( |mut f| f. write ( pk_p. to_var_bytes ( ) . as_slice ( ) ) )
257- . unwrap ( ) ;
258- File :: create ( & vk_path)
259- . and_then ( |mut f| f. write ( & vk_p. to_bytes ( ) ) )
260- . unwrap ( ) ;
323+ . expect ( "IO error" ) ;
261324
262325 // Read ProverKey
263- let pk = fs:: read ( pk_path) . unwrap ( ) ;
326+ let pk = fs:: read ( pk_path) . expect ( "IO error" ) ;
264327 let pk = ProverKey :: from_slice ( pk. as_slice ( ) ) ?;
265328
266- // Read VerifierKey
267- let vk = fs:: read ( vk_path) . unwrap ( ) ;
268- let vk = VerifierKey :: from_slice ( vk. as_slice ( ) ) ?;
269-
270329 assert_eq ! ( pk, pk_p) ;
271- assert_eq ! ( vk, vk_p) ;
330+
331+ // Store the VerifierData just for the verifier side:
332+ // (You could also store pi_pos and VerifierKey sepparatedly).
333+ File :: create ( & vd_path)
334+ . and_then ( |mut f| {
335+ f. write ( og_verifier_data. to_var_bytes ( ) . as_slice ( ) )
336+ } )
337+ . expect ( "IO error" ) ;
338+ let vd = fs:: read ( vd_path) . expect ( "IO error" ) ;
339+ let verif_data = VerifierData :: from_slice ( vd. as_slice ( ) ) ?;
340+ assert_eq ! ( og_verifier_data. key( ) , verif_data. key( ) ) ;
341+ assert_eq ! ( og_verifier_data. pi_pos( ) , verif_data. pi_pos( ) ) ;
272342
273343 // Prover POV
274344 let proof = {
@@ -297,6 +367,13 @@ mod tests {
297367 . into( ) ,
298368 ] ;
299369
300- verify_proof ( & pp, & vk, & proof, & public_inputs2, & pi_pos, b"Test" )
370+ verify_proof (
371+ & pp,
372+ & verif_data. key ( ) ,
373+ & proof,
374+ & public_inputs2,
375+ & verif_data. pi_pos ( ) ,
376+ b"Test" ,
377+ )
301378 }
302379}
0 commit comments