bsv_wasm/hash/
sha256d_digest.rs1use digest::{
2 consts::{U32, U64},
3 BlockInput, Digest, FixedOutput, Reset, Update,
4};
5
6use sha2::Sha256;
7
8use crate::reverse_digest::ReversibleDigest;
9
10#[derive(Clone, Default)]
11pub struct Sha256d {
12 engine: Sha256,
13 reverse: bool,
14}
15
16impl ReversibleDigest for Sha256d {
17 fn reverse(&self) -> Self {
18 let mut reversed = self.clone();
19 reversed.reverse = true;
20 reversed
21 }
22}
23
24impl BlockInput for Sha256d {
25 type BlockSize = U64;
26}
27
28impl Update for Sha256d {
29 fn update(&mut self, data: impl AsRef<[u8]>) {
30 Digest::update(&mut self.engine, data)
31 }
32}
33
34impl FixedOutput for Sha256d {
35 type OutputSize = U32;
36
37 fn finalize_into(self, out: &mut digest::generic_array::GenericArray<u8, Self::OutputSize>) {
38 let first_hash = &*self.engine.finalize();
39 let mut finished_hash = Sha256::digest(first_hash);
40 if self.reverse {
43 finished_hash.reverse()
44 }
45
46 out.copy_from_slice(&*finished_hash)
47 }
48
49 fn finalize_into_reset(&mut self, out: &mut digest::generic_array::GenericArray<u8, Self::OutputSize>) {
50 self.clone().finalize_into(out);
51 digest::Reset::reset(self);
52 }
53
54 fn finalize_fixed(self) -> digest::generic_array::GenericArray<u8, Self::OutputSize>
55 where
56 Self: Sized,
57 {
58 let mut out = Default::default();
59 self.finalize_into(&mut out);
60 out
61 }
62
63 fn finalize_fixed_reset(&mut self) -> digest::generic_array::GenericArray<u8, Self::OutputSize> {
64 let mut out = Default::default();
65 self.finalize_into_reset(&mut out);
66 out
67 }
68}
69
70impl Reset for Sha256d {
71 fn reset(&mut self) {
72 self.engine = Sha256::default();
73 }
74}
75
76digest::impl_write!(Sha256d);