Coverage Report

Created: 2024-02-20 21:15

/builds/xfbs/cindy/src/hash.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::config::HashAlgorithm;
2
pub use cindy_common::{ArcHash, BoxHash, Hash};
3
use digest::DynDigest;
4
use std::io::{Read, Result as IoResult};
5
6
pub trait Digester: std::fmt::Debug {
7
    /// Create new Hasher
8
    fn create(&self) -> Box<dyn DynDigest + Send>;
9
10
    /// Determine Hash output size.
11
2
    fn output_size(&self) -> usize {
12
2
        self.create().output_size()
13
2
    }
14
}
15
16
impl Digester for HashAlgorithm {
17
48
    fn create(&self) -> Box<dyn DynDigest + Send> {
18
48
        use HashAlgorithm::*;
19
48
        match self {
20
35
            Blake2b512 => Box::<blake2::Blake2b512>::default() as _,
21
13
            Blake2s256 => Box::<blake2::Blake2s256>::default() as _,
22
        }
23
48
    }
24
}
25
26
/// Trait to hash data.
27
pub trait DataHasher {
28
    fn hash_data(&self, data: &[u8]) -> BoxHash;
29
}
30
31
impl<T: Digester + ?Sized> DataHasher for T {
32
17
    fn hash_data(&self, data: &[u8]) -> BoxHash {
33
17
        let mut hasher = self.create();
34
17
        hasher.update(data);
35
17
        hasher.finalize().into()
36
17
    }
37
}
38
39
const DEFAULT_BUFFER_SIZE: usize = 8 * 1024;
40
41
pub trait ReadDigester {
42
24
    fn hash_read(&self, reader: &mut dyn Read) -> IoResult<BoxHash> {
43
24
        self.hash_read_bufsize(reader, DEFAULT_BUFFER_SIZE)
44
24
    }
45
46
    fn hash_read_bufsize(&self, reader: &mut dyn Read, bufsize: usize) -> IoResult<BoxHash>;
47
}
48
49
impl<T: Digester + ?Sized> ReadDigester for T {
50
29
    fn hash_read_bufsize(&self, reader: &mut dyn Read, buffer_size: usize) -> IoResult<BoxHash> {
51
29
        let mut hasher = self.create();
52
29
        let mut buffer = vec![0; buffer_size];
53
        loop {
54
37.2k
            let read = reader.read(&mut buffer[..])
?0
;
55
37.2k
            if read == 0 {
56
29
                return Ok(hasher.finalize().into());
57
37.2k
            }
58
37.2k
            hasher.update(&buffer[0..read]);
59
        }
60
29
    }
61
}
62
63
#[cfg(test)]
64
mod tests {
65
    use super::*;
66
67
    /// Test vector that is longer than the default buffer size
68
    const LONG_DATA: &[u8] = &[17; 5 * DEFAULT_BUFFER_SIZE / 2];
69
70
    const BLAKE2B512_HASH_EMPTY: [u8; 64] = [
71
        120, 106, 2, 247, 66, 1, 89, 3, 198, 198, 253, 133, 37, 82, 210, 114, 145, 47, 71, 64, 225,
72
        88, 71, 97, 138, 134, 226, 23, 247, 31, 84, 25, 210, 94, 16, 49, 175, 238, 88, 83, 19, 137,
73
        100, 68, 147, 78, 176, 75, 144, 58, 104, 91, 20, 72, 183, 85, 213, 111, 112, 26, 254, 155,
74
        226, 206,
75
    ];
76
77
    const BLAKE2B512_HASH_HELLO: [u8; 64] = [
78
        228, 207, 163, 154, 61, 55, 190, 49, 197, 150, 9, 232, 7, 151, 7, 153, 202, 166, 138, 25,
79
        191, 170, 21, 19, 95, 22, 80, 133, 224, 29, 65, 166, 91, 161, 225, 177, 70, 174, 182, 189,
80
        0, 146, 180, 158, 172, 33, 76, 16, 60, 207, 163, 163, 101, 149, 75, 187, 229, 47, 116, 162,
81
        179, 98, 12, 148,
82
    ];
83
84
    const BLAKE2B512_HASH_WORLD: [u8; 64] = [
85
        38, 123, 46, 2, 182, 175, 61, 91, 255, 82, 57, 127, 35, 140, 58, 36, 14, 93, 19, 25, 55,
86
        93, 197, 198, 14, 249, 240, 223, 90, 233, 81, 23, 97, 150, 143, 51, 162, 206, 23, 160, 149,
87
        45, 133, 254, 210, 49, 230, 16, 60, 134, 127, 4, 50, 194, 80, 221, 82, 186, 249, 89, 199,
88
        252, 71, 89,
89
    ];
90
91
1
    #[test]
92
1
    fn can_hash_data_blake2b() {
93
1
        let algorithm = HashAlgorithm::Blake2b512;
94
1
        assert_eq!(algorithm.hash_data(b""), BLAKE2B512_HASH_EMPTY);
95
1
        assert_eq!(algorithm.hash_data(b"hello"), BLAKE2B512_HASH_HELLO);
96
1
        assert_eq!(algorithm.hash_data(b"world"), BLAKE2B512_HASH_WORLD);
97
1
    }
98
99
1
    #[test]
100
1
    fn can_hash_read_blake2b() {
101
1
        let algorithm = HashAlgorithm::Blake2b512;
102
1
        assert_eq!(
103
1
            algorithm.hash_read(&mut &b""[..]).unwrap(),
104
1
            BLAKE2B512_HASH_EMPTY
105
1
        );
106
1
        assert_eq!(
107
1
            algorithm.hash_read(&mut &b"hello"[..]).unwrap(),
108
1
            BLAKE2B512_HASH_HELLO
109
1
        );
110
1
        assert_eq!(
111
1
            algorithm.hash_read(&mut &b"world"[..]).unwrap(),
112
1
            BLAKE2B512_HASH_WORLD
113
1
        );
114
1
    }
115
116
    const BLAKE2S256_HASH_EMPTY: [u8; 32] = [
117
        105, 33, 122, 48, 121, 144, 128, 148, 225, 17, 33, 208, 66, 53, 74, 124, 31, 85, 182, 72,
118
        44, 161, 165, 30, 27, 37, 13, 253, 30, 208, 238, 249,
119
    ];
120
121
    const BLAKE2S256_HASH_HELLO: [u8; 32] = [
122
        25, 33, 59, 172, 197, 141, 238, 109, 189, 227, 206, 185, 164, 124, 187, 51, 11, 61, 134,
123
        248, 204, 168, 153, 126, 176, 11, 228, 86, 241, 64, 202, 37,
124
    ];
125
126
    const BLAKE2S256_HASH_WORLD: [u8; 32] = [
127
        127, 150, 209, 144, 232, 9, 183, 35, 140, 129, 86, 240, 30, 42, 128, 83, 137, 184, 155, 88,
128
        73, 48, 7, 253, 182, 177, 185, 244, 179, 247, 23, 153,
129
    ];
130
131
1
    #[test]
132
1
    fn can_hash_data_blake2s() {
133
1
        let algorithm = HashAlgorithm::Blake2s256;
134
1
        assert_eq!(algorithm.hash_data(b""), BLAKE2S256_HASH_EMPTY);
135
1
        assert_eq!(algorithm.hash_data(b"hello"), BLAKE2S256_HASH_HELLO);
136
1
        assert_eq!(algorithm.hash_data(b"world"), BLAKE2S256_HASH_WORLD);
137
1
    }
138
139
1
    #[test]
140
1
    fn can_hash_read_blake2s() {
141
1
        let algorithm = HashAlgorithm::Blake2s256;
142
1
        assert_eq!(
143
1
            algorithm.hash_read(&mut &b""[..]).unwrap(),
144
1
            BLAKE2S256_HASH_EMPTY
145
1
        );
146
1
        assert_eq!(
147
1
            algorithm.hash_read(&mut &b"hello"[..]).unwrap(),
148
1
            BLAKE2S256_HASH_HELLO
149
1
        );
150
1
        assert_eq!(
151
1
            algorithm.hash_read(&mut &b"world"[..]).unwrap(),
152
1
            BLAKE2S256_HASH_WORLD
153
1
        );
154
1
    }
155
156
    const BLAKE2B512_HASH_LONG: [u8; 32] = [
157
        18, 214, 217, 86, 171, 0, 180, 29, 148, 114, 255, 53, 23, 224, 195, 229, 220, 224, 216, 2,
158
        180, 26, 53, 191, 14, 248, 23, 160, 113, 224, 84, 21,
159
    ];
160
161
1
    #[test]
162
1
    fn can_hash_read() {
163
1
        let algorithm = HashAlgorithm::Blake2s256;
164
1
        assert_eq!(
165
1
            algorithm.hash_read(&mut &LONG_DATA[..]).unwrap(),
166
1
            BLAKE2B512_HASH_LONG
167
1
        );
168
6
        for 
bufsize5
in [1, 2, 5, 12, 33] {
169
5
            assert_eq!(
170
5
                algorithm
171
5
                    .hash_read_bufsize(&mut &LONG_DATA[..], bufsize)
172
5
                    .unwrap(),
173
5
                BLAKE2B512_HASH_LONG
174
5
            );
175
        }
176
1
    }
177
178
1
    #[test]
179
1
    fn blake2b_output_size() {
180
1
        let algorithm = HashAlgorithm::Blake2b512;
181
1
        assert_eq!(algorithm.output_size(), 64);
182
1
    }
183
184
1
    #[test]
185
1
    fn blake2s_output_size() {
186
1
        let algorithm = HashAlgorithm::Blake2s256;
187
1
        assert_eq!(algorithm.output_size(), 32);
188
1
    }
189
}