bsv_wasm/hash/
hash160_digest.rs

1use crate::reverse_digest::ReversibleDigest;
2use digest::consts::U20;
3use digest::{consts::U64, BlockInput, Digest, FixedOutputDirty, Reset, Update};
4
5use ripemd160::Ripemd160;
6use sha2::Sha256;
7
8#[derive(Clone)]
9pub struct Hash160 {
10    engine: Sha256,
11    reverse: bool,
12}
13
14impl ReversibleDigest for Hash160 {
15    fn reverse(&self) -> Self {
16        let mut reversed = self.clone();
17        reversed.reverse = true;
18        reversed
19    }
20}
21
22impl Hash160 {
23    pub fn new(reverse: bool) -> Self {
24        let engine: Sha256 = Sha256::default();
25        Self { engine, reverse }
26    }
27}
28
29impl Default for Hash160 {
30    fn default() -> Self {
31        Self::new(false)
32    }
33}
34
35impl BlockInput for Hash160 {
36    type BlockSize = U64;
37}
38
39impl Update for Hash160 {
40    fn update(&mut self, input: impl AsRef<[u8]>) {
41        digest::Digest::update(&mut self.engine, input.as_ref())
42    }
43}
44
45impl FixedOutputDirty for Hash160 {
46    type OutputSize = U20;
47
48    fn finalize_into_dirty(&mut self, out: &mut digest::Output<Self>) {
49        let first_hash = self.clone().engine.finalize();
50        let finished_hash = &mut *Ripemd160::digest(&*first_hash);
51        if self.reverse {
52            finished_hash.reverse()
53        }
54
55        out.copy_from_slice(finished_hash);
56    }
57}
58
59impl Reset for Hash160 {
60    fn reset(&mut self) {
61        self.engine = Sha256::default();
62    }
63}
64
65digest::impl_write!(Hash160);