zebra_chain/serialization/
sha256d.rs
1use std::{fmt, io::prelude::*};
4
5use sha2::{Digest, Sha256};
6
7#[derive(Default)]
9pub struct Writer {
10 hash: Sha256,
11}
12
13impl Writer {
14 pub fn finish(self) -> [u8; 32] {
16 let result1 = self.hash.finalize();
17 let result2 = Sha256::digest(result1);
18 let mut buffer = [0u8; 32];
19 buffer[0..32].copy_from_slice(&result2[0..32]);
20 buffer
21 }
22}
23
24impl Write for Writer {
25 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
26 self.hash.update(buf);
27 Ok(buf.len())
28 }
29
30 fn flush(&mut self) -> std::io::Result<()> {
31 Ok(())
32 }
33}
34
35#[derive(Copy, Clone, Eq, PartialEq)]
37pub struct Checksum(pub [u8; 4]);
38
39impl<'a> From<&'a [u8]> for Checksum {
40 fn from(bytes: &'a [u8]) -> Self {
41 let hash1 = Sha256::digest(bytes);
42 let hash2 = Sha256::digest(hash1);
43 let mut checksum = [0u8; 4];
44 checksum[0..4].copy_from_slice(&hash2[0..4]);
45 Self(checksum)
46 }
47}
48
49impl fmt::Debug for Checksum {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 f.debug_tuple("Sha256dChecksum")
52 .field(&hex::encode(self.0))
53 .finish()
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn sha256d_checksum() {
63 let _init_guard = zebra_test::init();
64
65 let input = b"hello";
67 let checksum = Checksum::from(&input[..]);
68 let expected = Checksum([0x95, 0x95, 0xc9, 0xdf]);
69 assert_eq!(checksum, expected);
70 }
71
72 #[test]
73 fn sha256d_checksum_debug() {
74 let _init_guard = zebra_test::init();
75
76 let input = b"hello";
77 let checksum = Checksum::from(&input[..]);
78
79 assert_eq!(format!("{checksum:?}"), "Sha256dChecksum(\"9595c9df\")");
80 }
81}