1use super::sha512::Sha512;
9use crate::Hasher;
10
11const H0_512_224: [u64; 8] = [
13 0x8C3D37C819544DA2,
14 0x73E1996689DCD4D6,
15 0x1DFAB7AE32FF9C82,
16 0x679DD514582F9FCF,
17 0x0F6D2B697BD44DA8,
18 0x77E36F7304C48942,
19 0x3F9D85A86A1D36C8,
20 0x1112E6AD91D692A1,
21];
22
23const H0_512_256: [u64; 8] = [
25 0x22312194FC2BF72C,
26 0x9F555FA3C84C64C2,
27 0x2393B86B6F53B151,
28 0x963877195940EABD,
29 0x96283EE2A88EFFE3,
30 0xBE5E1E2553863992,
31 0x2B0199FC2C85B8AA,
32 0x0EB72DDC81C52CA2,
33];
34
35#[derive(Clone)]
40pub struct Sha512_224 {
41 inner: Sha512,
42}
43
44impl Hasher for Sha512_224 {
45 const OUTPUT_LEN: usize = 28;
46 const BLOCK_LEN: usize = 128;
47
48 fn new() -> Self {
49 Self {
50 inner: Sha512::new_with_iv(H0_512_224),
51 }
52 }
53
54 fn update(&mut self, data: &[u8]) {
55 self.inner.update(data);
56 }
57
58 fn finalize(self) -> Vec<u8> {
59 let mut out = vec![0u8; 28];
60 self.finalize_into(&mut out);
61 out
62 }
63
64 fn finalize_into(self, out: &mut [u8]) {
65 let mut full = [0u8; 64];
66 self.inner.finalize_into(&mut full);
67 let len = out.len().min(28);
68 out[..len].copy_from_slice(&full[..len]);
69 }
70}
71
72#[derive(Clone)]
79pub struct Sha512_256 {
80 inner: Sha512,
81}
82
83impl Hasher for Sha512_256 {
84 const OUTPUT_LEN: usize = 32;
85 const BLOCK_LEN: usize = 128;
86
87 fn new() -> Self {
88 Self {
89 inner: Sha512::new_with_iv(H0_512_256),
90 }
91 }
92
93 fn update(&mut self, data: &[u8]) {
94 self.inner.update(data);
95 }
96
97 fn finalize(self) -> Vec<u8> {
98 let mut out = vec![0u8; 32];
99 self.finalize_into(&mut out);
100 out
101 }
102
103 fn finalize_into(self, out: &mut [u8]) {
104 let mut full = [0u8; 64];
105 self.inner.finalize_into(&mut full);
106 let len = out.len().min(32);
107 out[..len].copy_from_slice(&full[..len]);
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114 use crate::Hasher;
115
116 #[test]
119 fn test_sha512_224_empty() {
120 let digest = Sha512_224::hash(b"");
121 let expected: [u8; 28] = [
122 0x6e, 0xd0, 0xdd, 0x02, 0x80, 0x6f, 0xa8, 0x9e, 0x25, 0xde, 0x06, 0x0c, 0x19, 0xd3, 0xac, 0x86, 0xca, 0xbb,
123 0x87, 0xd6, 0xa0, 0xdd, 0xd0, 0x5c, 0x33, 0x3b, 0x84, 0xf4,
124 ];
125 assert_eq!(&digest[..], &expected[..]);
126 }
127
128 #[test]
129 fn test_sha512_224_abc() {
130 let digest = Sha512_224::hash(b"abc");
131 let expected: [u8; 28] = [
132 0x46, 0x34, 0x27, 0x0F, 0x70, 0x7B, 0x6A, 0x54, 0xDA, 0xAE, 0x75, 0x30, 0x46, 0x08, 0x42, 0xE2, 0x0E, 0x37,
133 0xED, 0x26, 0x5C, 0xEE, 0xE9, 0xA4, 0x3E, 0x89, 0x24, 0xAA,
134 ];
135 assert_eq!(&digest[..], &expected[..]);
136 }
137
138 #[test]
139 fn test_sha512_256_empty() {
140 let digest = Sha512_256::hash(b"");
141 let expected: [u8; 32] = [
142 0xc6, 0x72, 0xb8, 0xd1, 0xef, 0x56, 0xed, 0x28, 0xab, 0x87, 0xc3, 0x62, 0x2c, 0x51, 0x14, 0x06, 0x9b, 0xdd,
143 0x3a, 0xd7, 0xb8, 0xf9, 0x73, 0x74, 0x98, 0xd0, 0xc0, 0x1e, 0xce, 0xf0, 0x96, 0x7a,
144 ];
145 assert_eq!(&digest[..], &expected[..]);
146 }
147
148 #[test]
149 fn test_sha512_256_abc() {
150 let digest = Sha512_256::hash(b"abc");
151 let expected: [u8; 32] = [
152 0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9, 0x9B, 0x2E, 0x29, 0xB7, 0x6B, 0x4C, 0x7D, 0xAB, 0xE4, 0xC2,
153 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46, 0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23,
154 ];
155 assert_eq!(&digest[..], &expected[..]);
156 }
157}