1use core::ops::Index;
11use core::slice::SliceIndex;
12use core::str;
13
14use crate::{sha512, FromSliceError};
15
16#[derive(Clone)]
23pub struct HashEngine(sha512::HashEngine);
24
25impl Default for HashEngine {
26 #[rustfmt::skip]
27 fn default() -> Self {
28 HashEngine(sha512::HashEngine::sha512_256())
29 }
30}
31
32impl crate::HashEngine for HashEngine {
33 type MidState = [u8; 64];
34
35 fn midstate(&self) -> [u8; 64] { self.0.midstate() }
36
37 const BLOCK_SIZE: usize = sha512::BLOCK_SIZE;
38
39 fn n_bytes_hashed(&self) -> usize { self.0.n_bytes_hashed() }
40
41 fn input(&mut self, inp: &[u8]) { self.0.input(inp); }
42}
43
44crate::internal_macros::hash_type! {
45 256,
46 false,
47 "Output of the SHA512/256 hash function.\n\nSHA512/256 is a hash function that uses the sha512 alogrithm but it truncates the output to 256 bits. It has different initial constants than sha512 so it produces an entirely different hash compared to sha512. More information at <https://eprint.iacr.org/2010/548.pdf>. ",
48 "crate::util::json_hex_string::len_32"
49}
50
51fn from_engine(e: HashEngine) -> Hash {
52 let mut ret = [0; 32];
53 ret.copy_from_slice(&sha512::from_engine(e.0)[..32]);
54 Hash(ret)
55}
56
57#[cfg(test)]
58mod tests {
59 #[test]
60 #[cfg(feature = "alloc")]
61 fn test() {
62 use crate::{sha512_256, Hash, HashEngine};
63
64 #[derive(Clone)]
65 struct Test {
66 input: &'static str,
67 output: Vec<u8>,
68 output_str: &'static str,
69 }
70
71 #[rustfmt::skip]
72 let tests = vec![
73 Test {
75 input: "",
76 output: vec![
77 0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28,
78 0xab, 0x87, 0xc3, 0x62, 0x2c, 0x51, 0x14, 0x06,
79 0x9b, 0xdd, 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74,
80 0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a,
81 ],
82 output_str: "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a"
83 },
84 Test {
85 input: "abcdef",
86 output: vec![
87 0xe4, 0xfd, 0xcb, 0x11, 0xd1, 0xac, 0x14, 0xe6,
88 0x98, 0x74, 0x3a, 0xcd, 0x88, 0x05, 0x17, 0x4c,
89 0xea, 0x5d, 0xdc, 0x0d, 0x31, 0x2e, 0x3e, 0x47,
90 0xf6, 0x37, 0x20, 0x32, 0x57, 0x1b, 0xad, 0x84,
91 ],
92 output_str: "e4fdcb11d1ac14e698743acd8805174cea5ddc0d312e3e47f6372032571bad84",
93 },
94 Test {
95 input: "Discard medicine more than two years old.",
96 output: vec![
97 0x69, 0x0c, 0x8a, 0xd3, 0x91, 0x6c, 0xef, 0xd3,
98 0xad, 0x29, 0x22, 0x6d, 0x98, 0x75, 0x96, 0x5e,
99 0x3e, 0xe9, 0xec, 0x0d, 0x44, 0x82, 0xea, 0xcc,
100 0x24, 0x8f, 0x2f, 0xf4, 0xaa, 0x0d, 0x8e, 0x5b,
101 ],
102 output_str: "690c8ad3916cefd3ad29226d9875965e3ee9ec0d4482eacc248f2ff4aa0d8e5b",
103 },
104 Test {
105 input: "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977",
106 output: vec![
107 0xb5, 0xba, 0xf7, 0x47, 0xc3, 0x07, 0xf9, 0x88,
108 0x49, 0xec, 0x88, 0x1c, 0xf0, 0xd4, 0x86, 0x05,
109 0xae, 0x4e, 0xdd, 0x38, 0x63, 0x72, 0xae, 0xa9,
110 0xb2, 0x6e, 0x71, 0xdb, 0x51, 0x7e, 0x65, 0x0b,
111 ],
112 output_str: "b5baf747c307f98849ec881cf0d48605ae4edd386372aea9b26e71db517e650b",
113 },
114 Test {
115 input: "The major problem is with sendmail. -Mark Horton",
116 output: vec![
117 0x53, 0xed, 0x5f, 0x9b, 0x5c, 0x0b, 0x67, 0x4a,
118 0xc0, 0xf3, 0x42, 0x5d, 0x9f, 0x9a, 0x5d, 0x46,
119 0x26, 0x55, 0xb0, 0x7c, 0xc9, 0x0f, 0x5d, 0x0f,
120 0x69, 0x2e, 0xec, 0x09, 0x38, 0x84, 0xa6, 0x07,
121 ],
122 output_str: "53ed5f9b5c0b674ac0f3425d9f9a5d462655b07cc90f5d0f692eec093884a607",
123 },
124 ];
125
126 for test in tests {
127 let hash = sha512_256::Hash::hash(test.input.as_bytes());
129 assert_eq!(hash, test.output_str.parse::<sha512_256::Hash>().expect("parse hex"));
130 assert_eq!(&hash[..], &test.output[..]);
131 assert_eq!(&hash.to_string(), &test.output_str);
132
133 let mut engine = sha512_256::Hash::engine();
135 for ch in test.input.as_bytes() {
136 engine.0.input(&[*ch]);
137 }
138 let manual_hash = sha512_256::Hash::from_engine(engine);
139 assert_eq!(hash, manual_hash);
140 assert_eq!(hash.to_byte_array()[..].as_ref(), test.output.as_slice());
141 }
142 }
143}
144
145#[cfg(bench)]
146mod benches {
147 use test::Bencher;
148
149 use crate::{sha512_256, Hash, HashEngine};
150
151 #[bench]
152 pub fn sha512_256_10(bh: &mut Bencher) {
153 let mut engine = sha512_256::Hash::engine();
154 let bytes = [1u8; 10];
155 bh.iter(|| {
156 engine.input(&bytes);
157 });
158 bh.bytes = bytes.len() as u64;
159 }
160
161 #[bench]
162 pub fn sha512_256_1k(bh: &mut Bencher) {
163 let mut engine = sha512_256::Hash::engine();
164 let bytes = [1u8; 1024];
165 bh.iter(|| {
166 engine.input(&bytes);
167 });
168 bh.bytes = bytes.len() as u64;
169 }
170
171 #[bench]
172 pub fn sha512_256_64k(bh: &mut Bencher) {
173 let mut engine = sha512_256::Hash::engine();
174 let bytes = [1u8; 65536];
175 bh.iter(|| {
176 engine.input(&bytes);
177 });
178 bh.bytes = bytes.len() as u64;
179 }
180}