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