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 {
14 Sha256Hash::hash_from(data).to_string()
15}
16
17#[derive(
24 Debug,
25 Default,
26 Clone,
27 Copy,
28 PartialEq,
29 Eq,
30 PartialOrd,
31 Ord,
32 Hash,
33 derive_more::Deref,
34 derive_more::AsRef,
35 derive_more::From,
36 derive_more::Into,
37 serde::Serialize,
38 serde::Deserialize,
39)]
40#[as_ref(forward)]
41pub struct Sha256Hash([u8; 32]);
42
43impl Sha256Hash {
44 pub fn hash_from(input: impl AsRef<[u8]>) -> Self {
46 let mut hasher = Sha256::new();
47 hasher.update(input);
48 Self(hasher.finalize().into())
49 }
50
51 pub fn from_existing_hash(hash: impl AsRef<[u8]>) -> CryptoKeystoreResult<Self> {
55 let array = hash.as_ref().try_into()?;
56 Ok(Self(array))
57 }
58}
59
60impl fmt::Display for Sha256Hash {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 let mut hex_bytes = [0; 64];
63 hex::encode_to_slice(self.0, hex_bytes.as_mut_slice())
64 .expect("infallible given inputs and outputs of fixed correct length");
65 let hex_str = str::from_utf8(&hex_bytes).expect("hex crate always produces valid utf8 data");
66 write!(f, "{hex_str}")
67 }
68}
69
70impl KeyType for Sha256Hash {
71 fn bytes(&self) -> std::borrow::Cow<'_, [u8]> {
72 (&self.0).into()
73 }
74}
75
76impl OwnedKeyType for Sha256Hash {
77 fn from_bytes(bytes: &[u8]) -> Option<Self> {
78 bytes.try_into().ok().map(Self)
79 }
80}
81
82impl rusqlite::ToSql for Sha256Hash {
83 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
84 self.as_ref().to_sql()
85 }
86}