Procházet zdrojové kódy

chore: nut11 tests

thesimplekid před 1 rokem
rodič
revize
1161b3dac1
1 změnil soubory, kde provedl 90 přidání a 36 odebrání
  1. 90 36
      crates/cashu/src/nuts/nut11.rs

+ 90 - 36
crates/cashu/src/nuts/nut11.rs

@@ -247,7 +247,7 @@ impl TryFrom<Secret> for P2PKConditions {
             .secret_data
             .tags
             .into_iter()
-            .flat_map(Tag::try_from)
+            .map(|t| Tag::try_from(t).unwrap())
             .map(|t| (t.kind(), t))
             .collect();
 
@@ -344,12 +344,15 @@ impl Proof {
             return Ok(());
         }
 
+        println!("{:?}", spending_conditions.refund_keys);
+
         if let Some(locktime) = spending_conditions.locktime {
             // If lock time has passed check if refund witness signature is valid
             if locktime.lt(&unix_time()) && !spending_conditions.refund_keys.is_empty() {
                 for s in &self.witness.signatures {
                     for v in &spending_conditions.refund_keys {
-                        let sig = Signature::try_from(s.as_bytes())
+                        println!("{}", v);
+                        let sig = Signature::try_from(hex::decode(s)?.as_slice())
                             .map_err(|_| Error::InvalidSignature)?;
 
                         // As long as there is one valid refund signature it can be spent
@@ -488,43 +491,34 @@ where
     type Error = Error;
 
     fn try_from(tag: Vec<S>) -> Result<Self, Self::Error> {
-        let tag_len = tag.len();
         let tag_kind: TagKind = match tag.first() {
             Some(kind) => TagKind::from(kind),
             None => return Err(Error::KindNotFound),
         };
 
-        if tag_len.eq(&2) {
-            match tag_kind {
-                TagKind::SigFlag => Ok(Tag::SigFlag(SigFlag::from(tag[1].as_ref()))),
-                TagKind::NSigs => Ok(Tag::NSigs(tag[1].as_ref().parse()?)),
-                TagKind::Locktime => Ok(Tag::LockTime(tag[1].as_ref().parse()?)),
-                _ => Err(Error::UnknownTag),
+        match tag_kind {
+            TagKind::SigFlag => Ok(Tag::SigFlag(SigFlag::from(tag[1].as_ref()))),
+            TagKind::NSigs => Ok(Tag::NSigs(tag[1].as_ref().parse()?)),
+            TagKind::Locktime => Ok(Tag::LockTime(tag[1].as_ref().parse()?)),
+            TagKind::Refund => {
+                let pubkeys = tag
+                    .iter()
+                    .skip(1)
+                    .flat_map(|p| VerifyingKey::from_str(p.as_ref()))
+                    .collect();
+
+                Ok(Self::Refund(pubkeys))
             }
-        } else if tag_len.gt(&1) {
-            match tag_kind {
-                TagKind::Refund => {
-                    let pubkeys = tag
-                        .iter()
-                        .skip(1)
-                        .flat_map(|p| VerifyingKey::from_str(p.as_ref()))
-                        .collect();
-
-                    Ok(Self::Refund(pubkeys))
-                }
-                TagKind::Pubkeys => {
-                    let pubkeys = tag
-                        .iter()
-                        .skip(1)
-                        .flat_map(|p| VerifyingKey::from_str(p.as_ref()))
-                        .collect();
-
-                    Ok(Self::PubKeys(pubkeys))
-                }
-                _ => Err(Error::UnknownTag),
+            TagKind::Pubkeys => {
+                let pubkeys = tag
+                    .iter()
+                    .skip(1)
+                    .flat_map(|p| VerifyingKey::from_str(p.as_ref()))
+                    .collect();
+
+                Ok(Self::PubKeys(pubkeys))
             }
-        } else {
-            Err(Error::UnknownTag)
+            _ => Err(Error::UnknownTag),
         }
     }
 }
@@ -775,13 +769,24 @@ mod tests {
         )
         .unwrap();
 
+        let signing_key_two = SigningKey::from_str(
+            "0000000000000000000000000000000000000000000000000000000000000001",
+        )
+        .unwrap();
+
+        let signing_key_three = SigningKey::from_str(
+            "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
+        )
+        .unwrap();
         let v_key: VerifyingKey = secret_key.verifying_key();
+        let v_key_two: VerifyingKey = signing_key_two.verifying_key();
+        let v_key_three: VerifyingKey = signing_key_three.verifying_key();
 
         let conditions = P2PKConditions {
-            locktime: None,
-            pubkeys: vec![v_key],
-            refund_keys: vec![],
-            num_sigs: None,
+            locktime: Some(21),
+            pubkeys: vec![v_key.clone(), v_key_two, v_key_three],
+            refund_keys: vec![v_key],
+            num_sigs: Some(2),
             sig_flag: SigFlag::SigInputs,
         };
 
@@ -802,4 +807,53 @@ mod tests {
 
         assert!(proof.verify_p2pk().is_ok());
     }
+
+    #[test]
+    fn test_verify() {
+        // Proof with a valid signature
+        let valid_proof = r#"{"amount":1,"secret":"[\"P2PK\",{\"nonce\":\"859d4935c4907062a6297cf4e663e2835d90d97ecdd510745d32f6816323a41f\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"60f3c9b766770b46caac1d27e1ae6b77c8866ebaeba0b9489fe6a15a837eaa6fcd6eaa825499c72ac342983983fd3ba3a8a41f56677cc99ffd73da68b59e1383\"]}"}"#;
+
+        let valid_proof: Proof = serde_json::from_str(valid_proof).unwrap();
+
+        assert!(valid_proof.verify_p2pk().is_ok());
+
+        // Proof with a signature that is in a different secret
+        let invalid_proof = r#"{"amount":1,"secret":"[\"P2PK\",{\"nonce\":\"859d4935c4907062a6297cf4e663e2835d90d97ecdd510745d32f6816323a41f\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"3426df9730d365a9d18d79bed2f3e78e9172d7107c55306ac5ddd1b2d065893366cfa24ff3c874ebf1fc22360ba5888ddf6ff5dbcb9e5f2f5a1368f7afc64f15\"]}"}"#;
+
+        let invalid_proof: Proof = serde_json::from_str(invalid_proof).unwrap();
+
+        assert!(invalid_proof.verify_p2pk().is_err());
+    }
+
+    #[test]
+    fn verify_multi_sig() {
+        // Proof with 2 valid signatures to satifiy the condition
+        let valid_proof = r#"{"amount":0,"secret":"[\"P2PK\",{\"nonce\":\"0ed3fcb22c649dd7bbbdcca36e0c52d4f0187dd3b6a19efcc2bfbebb5f85b2a1\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"pubkeys\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"02142715675faf8da1ecc4d51e0b9e539fa0d52fdd96ed60dbe99adb15d6b05ad9\"],[\"n_sigs\",\"2\"],[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"83564aca48c668f50d022a426ce0ed19d3a9bdcffeeaee0dc1e7ea7e98e9eff1840fcc821724f623468c94f72a8b0a7280fa9ef5a54a1b130ef3055217f467b3\",\"9a72ca2d4d5075be5b511ee48dbc5e45f259bcf4a4e8bf18587f433098a9cd61ff9737dc6e8022de57c76560214c4568377792d4c2c6432886cc7050487a1f22\"]}"}"#;
+
+        let valid_proof: Proof = serde_json::from_str(valid_proof).unwrap();
+
+        assert!(valid_proof.verify_p2pk().is_ok());
+
+        // Proof with onlt one of the required signatures
+        let invalid_proof = r#"{"amount":0,"secret":"[\"P2PK\",{\"nonce\":\"0ed3fcb22c649dd7bbbdcca36e0c52d4f0187dd3b6a19efcc2bfbebb5f85b2a1\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"pubkeys\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"02142715675faf8da1ecc4d51e0b9e539fa0d52fdd96ed60dbe99adb15d6b05ad9\"],[\"n_sigs\",\"2\"],[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"83564aca48c668f50d022a426ce0ed19d3a9bdcffeeaee0dc1e7ea7e98e9eff1840fcc821724f623468c94f72a8b0a7280fa9ef5a54a1b130ef3055217f467b3\"]}"}"#;
+
+        let invalid_proof: Proof = serde_json::from_str(invalid_proof).unwrap();
+
+        // Verification should fail without the requires signatures
+        assert!(invalid_proof.verify_p2pk().is_err());
+    }
+
+    #[test]
+    fn verify_refund() {
+        let valid_proof = r#"{"amount":0,"secret":"[\"P2PK\",{\"nonce\":\"3eff971bb1ca70b16be3446a4d3feedf2f37f054c5c8621d832744df71b028f0\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"pubkeys\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"02142715675faf8da1ecc4d51e0b9e539fa0d52fdd96ed60dbe99adb15d6b05ad9\"],[\"locktime\",\"21\"],[\"n_sigs\",\"2\"],[\"refund\",\"49098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\"],[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"94c6355461ca88e5d22c4e65e920b2e8253ccb4dd084675453a7bba7044e580246bd05e2520691afeccb2a88784cc56064353aec8b6a61e172727ba9cb3054a1\"]}"}"#;
+
+        let valid_proof: Proof = serde_json::from_str(valid_proof).unwrap();
+        assert!(valid_proof.verify_p2pk().is_ok());
+
+        let invalid_proof = r#"{"amount":0,"secret":"[\"P2PK\",{\"nonce\":\"d14cf9be9d9438d548b6b9d29bf800611136d053421b0f48c38d1447a7a92fc8\",\"data\":\"0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"pubkeys\",\"0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798\",\"02142715675faf8da1ecc4d51e0b9e539fa0d52fdd96ed60dbe99adb15d6b05ad9\"],[\"locktime\",\"2100000000000\"],[\"n_sigs\",\"2\"],[\"refund\",\"49098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\"],[\"sigflag\",\"SIG_INPUTS\"]]}]","C":"02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904","id":"009a1f293253e41e","witness":"{\"signatures\":[\"c3079dccf828e9d38bbbb17edf19c7915ee11920cf271c36b8780fdeb88b16fbfbe0328c7dcbe80e56cdc8f85c5831c79df77b27e81e5630a4dd392601fab9eb\"]}"}"#;
+
+        let invalid_proof: Proof = serde_json::from_str(invalid_proof).unwrap();
+
+        assert!(invalid_proof.verify_p2pk().is_err());
+    }
 }