1+ #[ cfg( feature = "serde" ) ]
2+ use crate :: error:: SemaphoreError ;
13use crate :: {
24 MAX_TREE_DEPTH , MIN_TREE_DEPTH ,
35 group:: { EMPTY_ELEMENT , Element , Group , MerkleProof } ,
@@ -37,7 +39,7 @@ impl GroupOrMerkleProof {
3739 }
3840}
3941
40- #[ derive( Debug , Clone ) ]
42+ #[ derive( Debug , Clone , PartialEq ) ]
4143pub struct SemaphoreProof {
4244 pub merkle_tree_depth : u16 ,
4345 pub merkle_tree_root : BigUint ,
@@ -47,6 +49,60 @@ pub struct SemaphoreProof {
4749 pub points : PackedGroth16Proof ,
4850}
4951
52+ #[ cfg( feature = "serde" ) ]
53+ impl SemaphoreProof {
54+ pub fn export ( & self ) -> Result < String , SemaphoreError > {
55+ let mut json = serde_json:: Map :: new ( ) ;
56+ json. insert (
57+ "merkle_tree_depth" . to_string ( ) ,
58+ self . merkle_tree_depth . into ( ) ,
59+ ) ;
60+ json. insert (
61+ "merkle_tree_root" . to_string ( ) ,
62+ self . merkle_tree_root . to_string ( ) . into ( ) ,
63+ ) ;
64+ json. insert ( "message" . to_string ( ) , self . message . to_string ( ) . into ( ) ) ;
65+ json. insert ( "nullifier" . to_string ( ) , self . nullifier . to_string ( ) . into ( ) ) ;
66+ json. insert ( "scope" . to_string ( ) , self . scope . to_string ( ) . into ( ) ) ;
67+ json. insert (
68+ "points" . to_string ( ) ,
69+ self . points
70+ . to_vec ( )
71+ . into_iter ( )
72+ . map ( |p| p. to_string ( ) )
73+ . collect :: < Vec < String > > ( )
74+ . into ( ) ,
75+ ) ;
76+ serde_json:: to_string ( & json) . map_err ( |e| SemaphoreError :: SerializationError ( e. to_string ( ) ) )
77+ }
78+
79+ pub fn import ( json : & str ) -> Result < Self , SemaphoreError > {
80+ let json: serde_json:: Map < String , serde_json:: Value > = serde_json:: from_str ( json)
81+ . map_err ( |e| SemaphoreError :: SerializationError ( e. to_string ( ) ) ) ?;
82+ Ok ( SemaphoreProof {
83+ merkle_tree_depth : json. get ( "merkle_tree_depth" ) . unwrap ( ) . as_u64 ( ) . unwrap ( ) as u16 ,
84+ merkle_tree_root : BigUint :: from_str (
85+ json. get ( "merkle_tree_root" ) . unwrap ( ) . as_str ( ) . unwrap ( ) ,
86+ )
87+ . unwrap ( ) ,
88+ message : BigUint :: from_str ( json. get ( "message" ) . unwrap ( ) . as_str ( ) . unwrap ( ) ) . unwrap ( ) ,
89+ nullifier : BigUint :: from_str ( json. get ( "nullifier" ) . unwrap ( ) . as_str ( ) . unwrap ( ) ) . unwrap ( ) ,
90+ scope : BigUint :: from_str ( json. get ( "scope" ) . unwrap ( ) . as_str ( ) . unwrap ( ) ) . unwrap ( ) ,
91+ points : json
92+ . get ( "points" )
93+ . unwrap ( )
94+ . as_array ( )
95+ . unwrap ( )
96+ . iter ( )
97+ . map ( |p| BigUint :: from_str ( p. as_str ( ) . unwrap ( ) ) . unwrap ( ) )
98+ . collect :: < Vec < BigUint > > ( )
99+ . try_into ( )
100+ . unwrap ( ) ,
101+ } )
102+ . map_err ( |e| SemaphoreError :: SerializationError ( e. to_string ( ) ) )
103+ }
104+ }
105+
50106pub struct Proof { }
51107
52108impl Proof {
@@ -498,5 +554,26 @@ mod tests {
498554
499555 assert ! ( Proof :: verify_proof( proof) ) ;
500556 }
557+
558+ #[ cfg( feature = "serde" ) ]
559+ #[ test]
560+ fn test_proof_export_import ( ) {
561+ let identity = Identity :: new ( "secret" . as_bytes ( ) ) ;
562+ let group =
563+ Group :: new ( & [ MEMBER1 , MEMBER2 , to_element ( * identity. commitment ( ) ) ] ) . unwrap ( ) ;
564+ let proof = Proof :: generate_proof (
565+ identity,
566+ GroupOrMerkleProof :: Group ( group) ,
567+ MESSAGE . to_string ( ) ,
568+ SCOPE . to_string ( ) ,
569+ TREE_DEPTH as u16 ,
570+ )
571+ . unwrap ( ) ;
572+ let proof_json = proof. export ( ) . unwrap ( ) ;
573+ let proof_imported = SemaphoreProof :: import ( & proof_json) . unwrap ( ) ;
574+ assert_eq ! ( proof, proof_imported) ;
575+ let valid = Proof :: verify_proof ( proof_imported) ;
576+ assert ! ( valid) ;
577+ }
501578 }
502579}
0 commit comments