core_crypto_keystore/
hash.rs1use std::fmt;
2
3use sha2::{Digest, Sha256};
4
5use crate::CryptoKeystoreResult;
6
7pub(crate) fn sha256(data: &[u8]) -> String {
9 Sha256Hash::hash_from(data).to_string()
10}
11
12#[derive(
19 Debug,
20 Default,
21 Clone,
22 Copy,
23 PartialEq,
24 Eq,
25 PartialOrd,
26 Ord,
27 Hash,
28 derive_more::Deref,
29 derive_more::AsRef,
30 derive_more::From,
31 derive_more::Into,
32 serde::Serialize,
33 serde::Deserialize,
34)]
35#[as_ref(forward)]
36pub struct Sha256Hash([u8; 32]);
37
38impl Sha256Hash {
39 pub fn hash_from(input: impl AsRef<[u8]>) -> Self {
41 Self::hash_from_many([input])
42 }
43
44 pub fn hash_from_many(inputs: impl IntoIterator<Item = impl AsRef<[u8]>>) -> Self {
49 let mut hasher = Sha256::new();
50 for input in inputs {
51 hasher.update(input);
52 }
53 Self(hasher.finalize().into())
54 }
55
56 pub fn from_existing_hash(hash: impl AsRef<[u8]>) -> CryptoKeystoreResult<Self> {
60 let array = hash.as_ref().try_into()?;
61 Ok(Self(array))
62 }
63}
64
65impl fmt::Display for Sha256Hash {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 let mut hex_bytes = [0; 64];
68 hex::encode_to_slice(self.0, hex_bytes.as_mut_slice())
69 .expect("infallible given inputs and outputs of fixed correct length");
70 let hex_str = str::from_utf8(&hex_bytes).expect("hex crate always produces valid utf8 data");
71 write!(f, "{hex_str}")
72 }
73}
74
75impl rusqlite::ToSql for Sha256Hash {
76 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
77 self.as_ref().to_sql()
78 }
79}