11use std:: {
22 collections:: HashMap ,
3- fs:: File ,
4- io:: { stdin, stdout, Read , Write } ,
5- path:: { Path , PathBuf } ,
3+ io:: { stdin, stdout, Write } ,
64} ;
75
86use clap:: { Parser , Subcommand } ;
97use rln:: prelude:: {
10- hash_to_field_le, keygen, poseidon_hash, recover_id_secret, Fr , IdSecret , PmtreeConfigBuilder ,
11- RLNProofValues , RLNWitnessInput , DEFAULT_TREE_DEPTH , RLN ,
8+ default_graph_multi, default_zkey_multi, hash_to_field_le, keygen, poseidon_hash,
9+ ArkGroth16Backend , Fr , IdSecret , PmTree , PmTreeConfig , PoseidonHash , RLNBuilder ,
10+ RLNProofValuesV3 , RLNWitnessInputV3 , RecoverSecret , Stateful , RLNV3 ,
1211} ;
13- use zerokit_utils:: pm_tree :: Mode ;
12+ use zerokit_utils:: merkle_tree :: { Hasher , ZerokitMerkleProof , ZerokitMerkleTree } ;
1413
1514const MESSAGE_LIMIT : u32 = 4 ;
1615
17- const TREE_DEPTH : usize = DEFAULT_TREE_DEPTH ;
16+ const TREE_DEPTH : usize = 20 ;
17+
18+ const MAX_OUT : usize = 4 ;
1819
1920type Result < T > = std:: result:: Result < T , Box < dyn std:: error:: Error > > ;
2021
@@ -60,39 +61,33 @@ impl Identity {
6061}
6162
6263struct RLNSystem {
63- rln : RLN ,
64- used_nullifiers : HashMap < Fr , RLNProofValues > ,
64+ rln : RLNV3 < Stateful < PmTree > , ArkGroth16Backend > ,
65+ used_nullifiers : HashMap < Fr , RLNProofValuesV3 > ,
6566 local_identities : HashMap < usize , Identity > ,
6667}
6768
6869impl RLNSystem {
6970 fn new ( ) -> Result < Self > {
70- let mut resources: Vec < Vec < u8 > > = Vec :: new ( ) ;
71- let resources_path: PathBuf =
72- format ! ( "../rln/resources/tree_depth_{TREE_DEPTH}/multi_message_id/max_out_4" ) . into ( ) ;
73- let filenames = [ "rln_final.arkzkey" , "graph.bin" ] ;
74- for filename in filenames {
75- let fullpath = resources_path. join ( Path :: new ( filename) ) ;
76- let mut file = File :: open ( & fullpath) ?;
77- let metadata = std:: fs:: metadata ( & fullpath) ?;
78- let mut output_buffer = vec ! [ 0 ; metadata. len( ) as usize ] ;
79- file. read_exact ( & mut output_buffer) ?;
80- resources. push ( output_buffer) ;
81- }
82- let tree_config = PmtreeConfigBuilder :: new ( )
83- . path ( "./database" )
84- . temporary ( false )
85- . cache_capacity ( 1073741824 )
86- . flush_every_ms ( 500 )
87- . mode ( Mode :: HighThroughput )
88- . use_compression ( false )
89- . build ( ) ?;
90- let rln = RLN :: new_with_params (
71+ let pm_tree_config: PmTreeConfig = r#"{
72+ "path": "./database",
73+ "temporary": false,
74+ "cache_capacity": 1073741824,
75+ "flush_every_ms": 500,
76+ "mode": "HighThroughput",
77+ "use_compression": false,
78+ "tree_depth": 20
79+ }"#
80+ . parse ( ) ?;
81+ let pm_tree = <PmTree as ZerokitMerkleTree >:: new (
9182 TREE_DEPTH ,
92- resources[ 0 ] . clone ( ) ,
93- resources[ 1 ] . clone ( ) ,
94- tree_config,
83+ PoseidonHash :: default_leaf ( ) ,
84+ pm_tree_config,
9585 ) ?;
86+ let rln = RLNBuilder :: stateful ( )
87+ . tree ( pm_tree)
88+ . graph ( default_graph_multi ( ) . clone ( ) )
89+ . zkey ( default_zkey_multi ( ) . clone ( ) )
90+ . build ( ) ;
9691 println ! ( "RLN multi-message-id instance initialized successfully" ) ;
9792 Ok ( RLNSystem {
9893 rln,
@@ -144,13 +139,8 @@ impl RLNSystem {
144139 Ok ( Fr :: from ( id) )
145140 } )
146141 . collect :: < Result < Vec < Fr > > > ( ) ?;
147- if ids. len ( ) != self . rln . max_out ( ) {
148- return Err ( format ! (
149- "expected {} message IDs, got {}" ,
150- self . rln. max_out( ) ,
151- ids. len( )
152- )
153- . into ( ) ) ;
142+ if ids. len ( ) != MAX_OUT {
143+ return Err ( format ! ( "expected {} message IDs, got {}" , MAX_OUT , ids. len( ) ) . into ( ) ) ;
154144 }
155145 Ok ( ids)
156146 }
@@ -164,10 +154,10 @@ impl RLNSystem {
164154 other => Err ( format ! ( "invalid selector value: '{other}'" ) ) ,
165155 } )
166156 . collect :: < std:: result:: Result < Vec < bool > , String > > ( ) ?;
167- if selector. len ( ) != self . rln . max_out ( ) {
157+ if selector. len ( ) != MAX_OUT {
168158 return Err ( format ! (
169159 "expected {} selector values, got {}" ,
170- self . rln . max_out ( ) ,
160+ MAX_OUT ,
171161 selector. len( )
172162 )
173163 . into ( ) ) ;
@@ -182,76 +172,79 @@ impl RLNSystem {
182172 selector_used : Vec < bool > ,
183173 signal : & str ,
184174 external_nullifier : Fr ,
185- ) -> Result < RLNProofValues > {
175+ ) -> Result < RLNProofValuesV3 > {
186176 let identity = match self . local_identities . get ( & user_index) {
187177 Some ( identity) => identity,
188178 None => return Err ( format ! ( "User {user_index} not found" ) . into ( ) ) ,
189179 } ;
190180
191- let ( path_elements , identity_path_index ) = self . rln . get_merkle_proof ( user_index) ?;
181+ let merkle_proof = self . rln . get_merkle_proof ( user_index) ?;
192182 let x = hash_to_field_le ( signal. as_bytes ( ) ) ;
193183
194- let witness = RLNWitnessInput :: new_multi (
195- identity. identity_secret . clone ( ) ,
196- Fr :: from ( MESSAGE_LIMIT ) ,
197- message_ids . clone ( ) ,
198- path_elements ,
199- identity_path_index ,
200- x ,
201- external_nullifier ,
202- selector_used. clone ( ) ,
203- ) ?;
184+ let witness = RLNWitnessInputV3 :: new_multi ( )
185+ . identity_secret ( identity. identity_secret . clone ( ) )
186+ . user_message_limit ( Fr :: from ( MESSAGE_LIMIT ) )
187+ . path_elements ( merkle_proof . get_path_elements ( ) )
188+ . identity_path_index ( merkle_proof . get_path_index ( ) )
189+ . x ( x )
190+ . external_nullifier ( external_nullifier )
191+ . message_ids ( message_ids )
192+ . selector_used ( selector_used . clone ( ) )
193+ . build ( ) ?;
204194
205- let ( proof, proof_values) = self . rln . generate_rln_proof ( & witness) ?;
195+ let ( proof, proof_values) = self . rln . generate_proof ( & witness) ?;
206196 let active_count = selector_used. iter ( ) . filter ( |& & s| s) . count ( ) ;
207197 println ! ( "Proof generated successfully:" ) ;
208198 println ! ( "+ User: {user_index}" ) ;
209- println ! (
210- "+ Active message slots: {active_count}/{}" ,
211- self . rln. max_out( )
212- ) ;
199+ println ! ( "+ Active message slots: {active_count}/{}" , MAX_OUT ) ;
213200 println ! ( "+ Signal: {signal}" ) ;
214201
215- let verified = self . rln . verify_rln_proof ( & proof, & proof_values, & x ) ?;
202+ let verified = self . rln . verify ( & proof, & proof_values) ?;
216203 if verified {
217204 println ! ( "Proof verified successfully" ) ;
218205 }
219206
220207 Ok ( proof_values)
221208 }
222209
223- fn check_nullifier ( & mut self , proof_values : RLNProofValues ) -> Result < ( ) > {
224- let nullifiers: Vec < Fr > = proof_values. nullifiers ( ) . to_vec ( ) ;
225- let selector: Vec < bool > = proof_values. selector_used ( ) . to_vec ( ) ;
210+ fn check_nullifier ( & mut self , proof_values : RLNProofValuesV3 ) -> Result < ( ) > {
211+ if let ( Some ( nullifiers) , Some ( selector) ) =
212+ ( proof_values. nullifiers ( ) , proof_values. selector_used ( ) )
213+ {
214+ for ( i, ( nullifier, active) ) in nullifiers. iter ( ) . zip ( selector. iter ( ) ) . enumerate ( ) {
215+ if !active {
216+ continue ;
217+ }
226218
227- for ( i, ( nullifier, active) ) in nullifiers. iter ( ) . zip ( selector. iter ( ) ) . enumerate ( ) {
228- if !active {
229- continue ;
219+ if let Some ( previous_proof_values) = self . used_nullifiers . get ( nullifier) {
220+ self . handle_duplicate_nullifier (
221+ previous_proof_values. clone ( ) ,
222+ proof_values,
223+ i,
224+ ) ?;
225+ return Ok ( ( ) ) ;
226+ }
230227 }
231228
232- if let Some ( previous_proof_values) = self . used_nullifiers . get ( nullifier) {
233- self . handle_duplicate_nullifier ( previous_proof_values. clone ( ) , proof_values, i) ?;
234- return Ok ( ( ) ) ;
229+ for ( nullifier, active) in nullifiers. iter ( ) . zip ( selector. iter ( ) ) {
230+ if * active {
231+ self . used_nullifiers
232+ . insert ( * nullifier, proof_values. clone ( ) ) ;
233+ }
235234 }
235+ println ! ( "Message verified and accepted" ) ;
236236 }
237237
238- for ( nullifier, active) in nullifiers. iter ( ) . zip ( selector. iter ( ) ) {
239- if * active {
240- self . used_nullifiers
241- . insert ( * nullifier, proof_values. clone ( ) ) ;
242- }
243- }
244- println ! ( "Message verified and accepted" ) ;
245238 Ok ( ( ) )
246239 }
247240
248241 fn handle_duplicate_nullifier (
249242 & mut self ,
250- previous_proof_values : RLNProofValues ,
251- current_proof_values : RLNProofValues ,
243+ previous_proof_values : RLNProofValuesV3 ,
244+ current_proof_values : RLNProofValuesV3 ,
252245 duplicated_slot : usize ,
253246 ) -> Result < ( ) > {
254- match recover_id_secret ( & previous_proof_values, & current_proof_values) {
247+ match previous_proof_values. recover_secret ( & current_proof_values) {
255248 Ok ( leaked_identity_secret) => {
256249 if let Some ( ( user_index, identity) ) = self
257250 . local_identities
@@ -290,7 +283,7 @@ fn main() -> Result<()> {
290283 let external_nullifier = poseidon_hash ( & [ rln_epoch, rln_identifier] ) ;
291284 println ! ( "RLN Multi-Message-ID Example:" ) ;
292285 println ! ( "Message Limit: {MESSAGE_LIMIT}" ) ;
293- println ! ( "Message Slots: {} - MAX_OUT" , rln_system . rln . max_out ( ) ) ;
286+ println ! ( "Message Slots: 1 - { MAX_OUT}" ) ;
294287 println ! ( "----------------------------------" ) ;
295288 println ! ( ) ;
296289 show_commands ( ) ;
0 commit comments