opentitanlib/crypto/
sha256.rs1use serde::{Deserialize, Serialize};
6use sha2::Digest;
7use std::fmt;
8use std::str::FromStr;
9
10use crate::crypto::Error;
11
12#[derive(Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(transparent)]
14pub struct Sha256Digest {
15 #[serde(with = "serde_bytes")]
16 pub digest: [u8; 32],
17}
18
19impl Sha256Digest {
20 pub fn hash(data: impl AsRef<[u8]>) -> Self {
21 let mut hasher = sha2::Sha256::new();
22 hasher.update(data);
23 Self {
24 digest: hasher.finalize().into(),
25 }
26 }
27
28 pub fn to_vec(&self) -> Vec<u8> {
29 self.digest.to_vec()
30 }
31
32 pub fn to_vec_rev(&self) -> Vec<u8> {
33 let mut result = self.to_vec();
34 result.reverse();
35 result
36 }
37}
38
39impl AsRef<[u8]> for Sha256Digest {
40 fn as_ref(&self) -> &[u8] {
41 &self.digest
42 }
43}
44
45impl TryFrom<&[u8]> for Sha256Digest {
46 type Error = Error;
47 fn try_from(data: &[u8]) -> std::result::Result<Self, Self::Error> {
48 Ok(Sha256Digest {
49 digest: data
50 .try_into()
51 .map_err(|_| Error::InvalidHash(hex::encode(data)))?,
52 })
53 }
54}
55
56impl FromStr for Sha256Digest {
57 type Err = anyhow::Error;
58 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
59 let s = s.trim_start_matches("0x");
60 let data = hex::decode(s)?;
61 Ok(Sha256Digest {
62 digest: data.try_into().map_err(|_| Error::InvalidHash(s.into()))?,
63 })
64 }
65}
66
67impl fmt::Display for Sha256Digest {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 write!(f, "{}", hex::encode(self))
70 }
71}
72
73impl fmt::Debug for Sha256Digest {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 f.debug_struct("Sha256Digest")
76 .field("digest", &self.to_string())
77 .finish()
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_sha256() {
87 fn check(msg: &str, digest: &str) {
88 assert_eq!(Sha256Digest::hash(msg).to_string(), digest);
89 }
90 check(
94 "",
95 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
96 );
97 check(
98 "abc",
99 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
100 );
101 check(
102 "1111",
103 "0ffe1abd1a08215353c233d6e009613e95eec4253832a761af28ff37ac5a150c",
104 );
105 }
106}