forked from
lewis.moe/bspds-sandbox
PDS software with bells & whistles you didn’t even know you needed. will move this to its own account when ready.
1use cid::Cid;
2use jacquard::types::{integer::LimitedU32, string::Tid};
3use jacquard_repo::commit::Commit;
4use k256::ecdsa::SigningKey;
5use std::str::FromStr;
6
7#[test]
8fn test_commit_signing_produces_valid_signature() {
9 let signing_key = SigningKey::random(&mut rand::thread_rng());
10
11 let did = "did:plc:testuser123456789abcdef";
12 let data_cid =
13 Cid::from_str("bafyreib2rxk3ryblouj3fxza5jvx6psmwewwessc4m6g6e7pqhhkwqomfi").unwrap();
14 let rev = Tid::now(LimitedU32::MIN);
15
16 let did_typed = jacquard::types::string::Did::new(did).unwrap();
17 let unsigned = Commit::new_unsigned(did_typed, data_cid, rev, None);
18 let signed = unsigned.sign(&signing_key).unwrap();
19
20 let pubkey_bytes = signing_key.verifying_key().to_encoded_point(true);
21 let pubkey = jacquard::types::crypto::PublicKey {
22 codec: jacquard::types::crypto::KeyCodec::Secp256k1,
23 bytes: std::borrow::Cow::Owned(pubkey_bytes.as_bytes().to_vec()),
24 };
25
26 signed.verify(&pubkey).expect("signature should verify");
27}
28
29#[test]
30fn test_commit_signing_with_prev() {
31 let signing_key = SigningKey::random(&mut rand::thread_rng());
32
33 let did = "did:plc:testuser123456789abcdef";
34 let data_cid =
35 Cid::from_str("bafyreib2rxk3ryblouj3fxza5jvx6psmwewwessc4m6g6e7pqhhkwqomfi").unwrap();
36 let prev_cid =
37 Cid::from_str("bafyreigxmvutyl3k5m4guzwxv3xf34gfxjlykgfdqkjmf32vwb5vcjxlui").unwrap();
38 let rev = Tid::now(LimitedU32::MIN);
39
40 let did_typed = jacquard::types::string::Did::new(did).unwrap();
41 let unsigned = Commit::new_unsigned(did_typed, data_cid, rev, Some(prev_cid));
42 let signed = unsigned.sign(&signing_key).unwrap();
43
44 let pubkey_bytes = signing_key.verifying_key().to_encoded_point(true);
45 let pubkey = jacquard::types::crypto::PublicKey {
46 codec: jacquard::types::crypto::KeyCodec::Secp256k1,
47 bytes: std::borrow::Cow::Owned(pubkey_bytes.as_bytes().to_vec()),
48 };
49
50 signed.verify(&pubkey).expect("signature should verify");
51}
52
53#[test]
54fn test_unsigned_commit_has_5_fields() {
55 let did = "did:plc:test";
56 let data_cid =
57 Cid::from_str("bafyreib2rxk3ryblouj3fxza5jvx6psmwewwessc4m6g6e7pqhhkwqomfi").unwrap();
58 let rev = Tid::from_str("3masrxv55po22").unwrap();
59
60 let did_typed = jacquard::types::string::Did::new(did).unwrap();
61 let unsigned = Commit::new_unsigned(did_typed, data_cid, rev, None);
62
63 let unsigned_bytes = serde_ipld_dagcbor::to_vec(&unsigned).unwrap();
64
65 let decoded: ciborium::Value = ciborium::from_reader(&unsigned_bytes[..]).unwrap();
66 if let ciborium::Value::Map(map) = decoded {
67 assert_eq!(
68 map.len(),
69 5,
70 "Unsigned commit must have exactly 5 fields (data, did, prev, rev, version) - no sig field"
71 );
72 let keys: Vec<String> = map
73 .iter()
74 .filter_map(|(k, _)| {
75 if let ciborium::Value::Text(s) = k {
76 Some(s.clone())
77 } else {
78 None
79 }
80 })
81 .collect();
82 assert!(keys.contains(&"data".to_string()));
83 assert!(keys.contains(&"did".to_string()));
84 assert!(keys.contains(&"prev".to_string()));
85 assert!(keys.contains(&"rev".to_string()));
86 assert!(keys.contains(&"version".to_string()));
87 assert!(
88 !keys.contains(&"sig".to_string()),
89 "Unsigned commit must NOT contain sig field"
90 );
91 } else {
92 panic!("Expected CBOR map");
93 }
94}
95
96#[test]
97fn test_create_signed_commit_helper() {
98 use tranquil_pds::api::repo::record::utils::create_signed_commit;
99
100 let signing_key = SigningKey::random(&mut rand::thread_rng());
101 let did = "did:plc:testuser123456789abcdef";
102 let data_cid =
103 Cid::from_str("bafyreib2rxk3ryblouj3fxza5jvx6psmwewwessc4m6g6e7pqhhkwqomfi").unwrap();
104 let rev = Tid::now(LimitedU32::MIN).to_string();
105
106 let (signed_bytes, sig) = create_signed_commit(did, data_cid, &rev, None, &signing_key)
107 .expect("signing should succeed");
108
109 assert!(!signed_bytes.is_empty());
110 assert_eq!(sig.len(), 64);
111
112 let commit = Commit::from_cbor(&signed_bytes).expect("should parse as valid commit");
113
114 let pubkey_bytes = signing_key.verifying_key().to_encoded_point(true);
115 let pubkey = jacquard::types::crypto::PublicKey {
116 codec: jacquard::types::crypto::KeyCodec::Secp256k1,
117 bytes: std::borrow::Cow::Owned(pubkey_bytes.as_bytes().to_vec()),
118 };
119
120 commit.verify(&pubkey).expect("signature should verify");
121}