|
| 1 | +#[cfg(feature = "serde")] |
| 2 | +use crate::error::SemaphoreError; |
1 | 3 | use crate::{ |
2 | 4 | MAX_TREE_DEPTH, MIN_TREE_DEPTH, |
3 | 5 | group::{EMPTY_ELEMENT, Element, Group, MerkleProof}, |
@@ -37,14 +39,68 @@ impl GroupOrMerkleProof { |
37 | 39 | } |
38 | 40 | } |
39 | 41 |
|
40 | | -#[derive(Debug, Clone)] |
| 42 | +#[derive(Debug, Clone, PartialEq)] |
41 | 43 | pub struct SemaphoreProof { |
42 | | - merkle_tree_depth: u16, |
43 | | - merkle_tree_root: BigUint, |
44 | | - message: BigUint, |
45 | | - nullifier: BigUint, |
46 | | - scope: BigUint, |
47 | | - points: PackedGroth16Proof, |
| 44 | + pub merkle_tree_depth: u16, |
| 45 | + pub merkle_tree_root: BigUint, |
| 46 | + pub message: BigUint, |
| 47 | + pub nullifier: BigUint, |
| 48 | + pub scope: BigUint, |
| 49 | + pub points: PackedGroth16Proof, |
| 50 | +} |
| 51 | + |
| 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 | + } |
48 | 104 | } |
49 | 105 |
|
50 | 106 | pub struct Proof {} |
@@ -231,6 +287,8 @@ mod tests { |
231 | 287 | .unwrap(); |
232 | 288 |
|
233 | 289 | assert_eq!(proof.merkle_tree_root, BigUint::from_bytes_le(&root)); |
| 290 | + assert_eq!(proof.message, to_big_uint(&MESSAGE.to_string())); |
| 291 | + assert_eq!(proof.scope, to_big_uint(&SCOPE.to_string())); |
234 | 292 | } |
235 | 293 |
|
236 | 294 | #[test] |
@@ -496,5 +554,26 @@ mod tests { |
496 | 554 |
|
497 | 555 | assert!(Proof::verify_proof(proof)); |
498 | 556 | } |
| 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 | + } |
499 | 578 | } |
500 | 579 | } |
0 commit comments