core_crypto_keystore/
hash.rs1use std::fmt;
2
3use sha2::{Digest, Sha256};
4
5use crate::{
6 CryptoKeystoreResult,
7 traits::{KeyType, OwnedKeyType},
8};
9
10pub(crate) fn sha256(data: &[u8]) -> String {
12 Sha256Hash::hash_from(data).to_string()
13}
14
15#[derive(
22 Debug,
23 Default,
24 Clone,
25 Copy,
26 PartialEq,
27 Eq,
28 PartialOrd,
29 Ord,
30 Hash,
31 derive_more::Deref,
32 derive_more::AsRef,
33 derive_more::From,
34 derive_more::Into,
35 serde::Serialize,
36 serde::Deserialize,
37)]
38#[as_ref(forward)]
39pub struct Sha256Hash([u8; 32]);
40
41impl Sha256Hash {
42 pub fn hash_from(input: impl AsRef<[u8]>) -> Self {
44 Self::hash_from_many([input])
45 }
46
47 pub fn hash_from_many(inputs: impl IntoIterator<Item = impl AsRef<[u8]>>) -> Self {
52 let mut hasher = Sha256::new();
53 for input in inputs {
54 hasher.update(input);
55 }
56 Self(hasher.finalize().into())
57 }
58
59 pub fn from_existing_hash(hash: impl AsRef<[u8]>) -> CryptoKeystoreResult<Self> {
63 let array = hash.as_ref().try_into()?;
64 Ok(Self(array))
65 }
66}
67
68impl fmt::Display for Sha256Hash {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 let mut hex_bytes = [0; 64];
71 hex::encode_to_slice(self.0, hex_bytes.as_mut_slice())
72 .expect("infallible given inputs and outputs of fixed correct length");
73 let hex_str = str::from_utf8(&hex_bytes).expect("hex crate always produces valid utf8 data");
74 write!(f, "{hex_str}")
75 }
76}
77
78impl KeyType for Sha256Hash {
79 fn bytes(&self) -> std::borrow::Cow<'_, [u8]> {
80 (&self.0).into()
81 }
82}
83
84impl OwnedKeyType for Sha256Hash {
85 fn from_bytes(bytes: &[u8]) -> Option<Self> {
86 bytes.try_into().ok().map(Self)
87 }
88}
89
90impl rusqlite::ToSql for Sha256Hash {
91 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
92 self.as_ref().to_sql()
93 }
94}