encryption/hash/
streebog.rs1use streebog::{Digest, Streebog256, Streebog512};
7
8use crate::contract::{Hasher, Identified};
9use crate::error::Result;
10
11#[derive(Debug, Default, Clone, Copy)]
13pub struct Streebog256Hasher;
14
15impl Streebog256Hasher {
16 pub const IDENTIFIER: &'static str = "streebog-256";
17
18 pub fn new() -> Self {
19 Self
20 }
21}
22
23impl Identified for Streebog256Hasher {
24 fn identifier(&self) -> &str {
25 Self::IDENTIFIER
26 }
27}
28
29impl Hasher for Streebog256Hasher {
30 fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
31 Ok(Streebog256::digest(data).to_vec())
32 }
33}
34
35#[derive(Debug, Default, Clone, Copy)]
37pub struct Streebog512Hasher;
38
39impl Streebog512Hasher {
40 pub const IDENTIFIER: &'static str = "streebog-512";
41
42 pub fn new() -> Self {
43 Self
44 }
45}
46
47impl Identified for Streebog512Hasher {
48 fn identifier(&self) -> &str {
49 Self::IDENTIFIER
50 }
51}
52
53impl Hasher for Streebog512Hasher {
54 fn digest(&self, data: &[u8]) -> Result<Vec<u8>> {
55 Ok(Streebog512::digest(data).to_vec())
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 const M1: &[u8; 63] = b"012345678901234567890123456789012345678901234567890123456789012";
68
69 #[test]
70 fn matches_standard_m1_vector() {
71 assert_eq!(
72 Streebog256Hasher::new().digest_hex(M1).unwrap(),
73 "9d151eefd8590b89daa6ba6cb74af9275dd051026bb149a452fd84e5e57b5500"
74 );
75 assert_eq!(
76 Streebog512Hasher::new().digest_hex(M1).unwrap(),
77 "1b54d01a4af5b9d5cc3d86d68d285462b19abc2475222f35c085122be4ba1ffa\
78 00ad30f8767b3a82384c6574f024c311e2a481332b08ef7f41797891c1646f48"
79 );
80 assert_eq!(Streebog256Hasher::new().digest(M1).unwrap().len(), 32);
81 assert_eq!(Streebog512Hasher::new().digest(M1).unwrap().len(), 64);
82 }
83
84 #[test]
86 fn digest_hex_is_lowercase_hex() {
87 let hex = Streebog256Hasher::new().digest_hex(b"abc").unwrap();
88 assert_eq!(hex.len(), 64);
89 assert!(
90 hex.bytes()
91 .all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase())
92 );
93
94 let hex = Streebog512Hasher::new().digest_hex(b"abc").unwrap();
95 assert_eq!(hex.len(), 128);
96 assert!(
97 hex.bytes()
98 .all(|b| b.is_ascii_hexdigit() && !b.is_ascii_uppercase())
99 );
100 }
101
102 #[test]
104 fn distinct_inputs_distinct_digests() {
105 let hasher = Streebog256Hasher::new();
106 assert_ne!(hasher.digest(M1).unwrap(), hasher.digest(b"abc").unwrap());
107
108 let hasher = Streebog512Hasher::new();
109 assert_ne!(hasher.digest(M1).unwrap(), hasher.digest(b"abc").unwrap());
110 }
111}