identity_storage/key_id_storage/
method_digest.rs1use identity_verification::MethodData;
5use identity_verification::VerificationMethod;
6use seahash::SeaHasher;
7use std::fmt::Display;
8use std::hash::Hasher;
9
10use super::KeyIdStorageError;
11
12pub type MethodDigestConstructionError = identity_core::common::SingleStructError<MethodDigestConstructionErrorKind>;
14
15#[derive(Debug)]
17#[non_exhaustive]
18pub enum MethodDigestConstructionErrorKind {
19 MissingIdFragment,
23 DataDecodingFailure,
25}
26
27impl Display for MethodDigestConstructionErrorKind {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 f.write_str("method digest construction failure: ")?;
30 match self {
31 MethodDigestConstructionErrorKind::MissingIdFragment => f.write_str("missing id fragment"),
32 MethodDigestConstructionErrorKind::DataDecodingFailure => f.write_str("data decoding failure"),
33 }
34 }
35}
36
37#[derive(Clone, Debug, PartialEq, Eq, Hash)]
39pub struct MethodDigest {
40 version: u8,
42 value: u64,
44}
45
46impl MethodDigest {
47 pub fn new(verification_method: &VerificationMethod) -> Result<Self, MethodDigestConstructionError> {
49 use MethodDigestConstructionErrorKind::*;
51 let mut hasher: SeaHasher = SeaHasher::new();
52 let fragment: &str = verification_method.id().fragment().ok_or(MissingIdFragment)?;
53 let method_data: &MethodData = verification_method.data();
54
55 hasher.write(fragment.as_bytes());
56
57 match method_data {
58 MethodData::PublicKeyJwk(jwk) => hasher.write(jwk.thumbprint_sha256().as_ref()),
59 _ => hasher.write(
60 &method_data
61 .try_decode()
62 .map_err(|err| MethodDigestConstructionError::new(DataDecodingFailure).with_source(err))?,
63 ),
64 };
65
66 let key_hash: u64 = hasher.finish();
67
68 Ok(Self {
69 version: 0,
70 value: key_hash,
71 })
72 }
73
74 pub fn pack(&self) -> Vec<u8> {
76 let mut pack: Vec<u8> = vec![self.version];
77 pack.append(&mut self.value.to_le_bytes().to_vec());
78 pack
79 }
80
81 pub fn unpack(bytes: Vec<u8>) -> crate::key_id_storage::KeyIdStorageResult<Self> {
83 if bytes.len() != 9 {
84 return Err(KeyIdStorageError::new(super::KeyIdStorageErrorKind::SerializationError));
85 }
86 let version: u8 = bytes[0];
87 if version != 0 {
88 return Err(KeyIdStorageError::new(super::KeyIdStorageErrorKind::SerializationError));
89 }
90 let value_le_bytes: [u8; 8] = bytes[1..9]
91 .try_into()
92 .map_err(|_| KeyIdStorageError::new(super::KeyIdStorageErrorKind::SerializationError))?;
93 let value: u64 = u64::from_le_bytes(value_le_bytes);
94 Ok(Self { version, value })
95 }
96}
97
98#[cfg(test)]
99mod test {
100 use crate::key_id_storage::KeyIdStorageError;
101 use crate::key_id_storage::KeyIdStorageErrorKind;
102 use identity_core::convert::FromJson;
103 use identity_core::json;
104 use identity_verification::VerificationMethod;
105 use serde_json::Value;
106
107 use super::MethodDigest;
108
109 #[test]
110 fn hash() {
111 let a: Value = json!(
113 {
114 "id": "did:example:HHoh9NQC9AUsK15Jyyq53VTujxEUizKDXRXd7zbT1B5u#frag_1",
115 "controller": "did:example:HHoh9NQC9AUsK15Jyyq53VTujxEUizKDXRXd7zbT1B5u",
116 "type": "Ed25519VerificationKey2018",
117 "publicKeyMultibase": "zHHoh9NQC9AUsK15Jyyq53VTujxEUizKDXRXd7zbT1B5u"
118 }
119 );
120 let verification_method: VerificationMethod = VerificationMethod::from_json_value(a).unwrap();
121 let method_digest: MethodDigest = MethodDigest::new(&verification_method).unwrap();
122 let method_digest_expected: MethodDigest = MethodDigest {
123 version: 0,
124 value: 9634551232492878922,
125 };
126 assert_eq!(method_digest, method_digest_expected);
127
128 let packed: Vec<u8> = method_digest.pack();
129 let packed_expected: Vec<u8> = vec![0, 74, 60, 10, 199, 76, 205, 180, 133];
130 assert_eq!(packed, packed_expected);
131 }
132
133 #[test]
134 fn pack() {
135 let verification_method: VerificationMethod = crate::storage::tests::test_utils::create_verification_method();
136 let method_digest: MethodDigest = MethodDigest::new(&verification_method).unwrap();
137 let packed: Vec<u8> = method_digest.pack();
138 let method_digest_unpacked: MethodDigest = MethodDigest::unpack(packed).unwrap();
139 assert_eq!(method_digest, method_digest_unpacked);
140 }
141
142 #[test]
143 fn unpack() {
144 let packed: Vec<u8> = vec![0, 255, 212, 82, 63, 57, 19, 134, 193];
145 let method_digest_unpacked: MethodDigest = MethodDigest::unpack(packed).unwrap();
146 let method_digest_expected: MethodDigest = MethodDigest {
147 version: 0,
148 value: 13944854432795776255,
149 };
150 assert_eq!(method_digest_unpacked, method_digest_expected);
151 }
152
153 #[test]
154 fn invalid_unpack() {
155 let packed: Vec<u8> = vec![1, 255, 212, 82, 63, 57, 19, 134, 193];
156 let method_digest_unpacked = MethodDigest::unpack(packed).unwrap_err();
157 let _expected_error = KeyIdStorageError::new(KeyIdStorageErrorKind::SerializationError);
158 assert!(matches!(method_digest_unpacked, _expected_error));
159
160 let packed: Vec<u8> = vec![1, 255, 212, 82, 63, 57, 19, 134, 193, 200];
162 let method_digest_unpacked = MethodDigest::unpack(packed).unwrap_err();
163 let _expected_error = KeyIdStorageError::new(KeyIdStorageErrorKind::SerializationError);
164 assert!(matches!(method_digest_unpacked, _expected_error));
165
166 let packed: Vec<u8> = vec![1, 255, 212, 82, 63, 57, 19, 134];
168 let method_digest_unpacked = MethodDigest::unpack(packed).unwrap_err();
169 let _expected_error = KeyIdStorageError::new(KeyIdStorageErrorKind::SerializationError);
170 assert!(matches!(method_digest_unpacked, _expected_error));
171
172 let packed: Vec<u8> = vec![];
174 let method_digest_unpacked = MethodDigest::unpack(packed).unwrap_err();
175 let _expected_error = KeyIdStorageError::new(KeyIdStorageErrorKind::SerializationError);
176 assert!(matches!(method_digest_unpacked, _expected_error));
177 }
178}