1use alloc::vec::Vec;
2
3const K: [u32; 64] = [
4 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
5 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
6 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
7 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
8 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
9 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
10 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
11 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
12 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
13 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
14 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
15 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
16 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
17 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
18 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
19 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
20];
21
22const H_INIT: [u32; 8] = [
23 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
24 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
25];
26
27#[derive(Clone)]
28pub struct Sha256 {
29 h: [u32; 8],
30 buffer: Vec<u8>,
31 counter: u64,
32}
33
34fn rotr(x: u32, y: u32) -> u32 {
35 (x >> y) | (x << (32 - y))
36}
37
38impl Sha256 {
39 pub fn new() -> Self {
40 Sha256 {
41 h: H_INIT,
42 buffer: Vec::new(),
43 counter: 0,
44 }
45 }
46
47 fn process_block(&mut self, block: &[u8]) {
48 let mut w = [0u32; 64];
49 for i in 0..16 {
50 w[i] = u32::from_be_bytes([
51 block[i * 4],
52 block[i * 4 + 1],
53 block[i * 4 + 2],
54 block[i * 4 + 3],
55 ]);
56 }
57
58 for i in 16..64 {
59 let s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >> 3);
60 let s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >> 10);
61 w[i] = w[i - 16]
62 .wrapping_add(s0)
63 .wrapping_add(w[i - 7])
64 .wrapping_add(s1);
65 }
66
67 let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = self.h;
68
69 for i in 0..64 {
70 let s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
71 let maj = (a & b) ^ (a & c) ^ (b & c);
72 let t2 = s0.wrapping_add(maj);
73 let s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
74 let ch = (e & f) ^ ((!e) & g);
75 let t1 = h
76 .wrapping_add(s1)
77 .wrapping_add(ch)
78 .wrapping_add(K[i])
79 .wrapping_add(w[i]);
80
81 h = g;
82 g = f;
83 f = e;
84 e = d.wrapping_add(t1);
85 d = c;
86 c = b;
87 b = a;
88 a = t1.wrapping_add(t2);
89 }
90
91 self.h[0] = self.h[0].wrapping_add(a);
92 self.h[1] = self.h[1].wrapping_add(b);
93 self.h[2] = self.h[2].wrapping_add(c);
94 self.h[3] = self.h[3].wrapping_add(d);
95 self.h[4] = self.h[4].wrapping_add(e);
96 self.h[5] = self.h[5].wrapping_add(f);
97 self.h[6] = self.h[6].wrapping_add(g);
98 self.h[7] = self.h[7].wrapping_add(h);
99 }
100
101 pub fn update(&mut self, data: &[u8]) {
102 if data.is_empty() {
103 return;
104 }
105 self.buffer.extend_from_slice(data);
106 self.counter += data.len() as u64;
107
108 while self.buffer.len() >= 64 {
109 let block: Vec<u8> = self.buffer.drain(..64).collect();
110 self.process_block(&block);
111 }
112 }
113
114 pub fn digest(&self) -> [u8; 32] {
115 let mut clone = self.clone();
116 let mdi = clone.counter & 0x3F;
117 let length = (clone.counter << 3).to_be_bytes();
118
119 let padlen = if mdi < 56 { 55 - mdi } else { 119 - mdi };
120
121 let mut padding = Vec::with_capacity(padlen as usize + 9);
122 padding.push(0x80);
123 for _ in 0..padlen {
124 padding.push(0x00);
125 }
126 padding.extend_from_slice(&length);
127 clone.update(&padding);
128
129 let mut result = [0u8; 32];
130 for (i, &val) in clone.h.iter().enumerate() {
131 result[i * 4..i * 4 + 4].copy_from_slice(&val.to_be_bytes());
132 }
133 result
134 }
135}
136
137pub fn sha256(data: &[u8]) -> [u8; 32] {
138 let mut hasher = Sha256::new();
139 hasher.update(data);
140 hasher.digest()
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146
147 #[test]
148 fn test_sha256_empty() {
149 let expected = [
150 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
151 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
152 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
153 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
154 ];
155 assert_eq!(sha256(b""), expected);
156 }
157
158 #[test]
159 fn test_sha256_abc() {
160 let expected = [
161 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
162 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
163 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
164 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
165 ];
166 assert_eq!(sha256(b"abc"), expected);
167 }
168
169 #[test]
170 fn test_sha256_long() {
171 let data = [b'a'; 1000];
173 let result = sha256(&data);
174 let expected = [
176 0x41, 0xed, 0xec, 0xe4, 0x2d, 0x63, 0xe8, 0xd9,
177 0xbf, 0x51, 0x5a, 0x9b, 0xa6, 0x93, 0x2e, 0x1c,
178 0x20, 0xcb, 0xc9, 0xf5, 0xa5, 0xd1, 0x34, 0x64,
179 0x5a, 0xdb, 0x5d, 0xb1, 0xb9, 0x73, 0x7e, 0xa3,
180 ];
181 assert_eq!(result, expected);
182 }
183
184 #[test]
185 fn test_sha256_incremental() {
186 let mut hasher = Sha256::new();
187 hasher.update(b"ab");
188 hasher.update(b"c");
189 assert_eq!(hasher.digest(), sha256(b"abc"));
190 }
191}