1const H0: u32 = 0x6a09e667;
8const H1: u32 = 0xbb67ae85;
9const H2: u32 = 0x3c6ef372;
10const H3: u32 = 0xa54ff53a;
11const H4: u32 = 0x510e527f;
12const H5: u32 = 0x9b05688c;
13const H6: u32 = 0x1f83d9ab;
14const H7: u32 = 0x5be0cd19;
15
16const K: [u32; 64] = [
19 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
20 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
21 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
22 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
23 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
24 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
25 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
26 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
27];
28
29pub fn sha256(bytes: &[u8]) -> [u8; 32] {
40 let mut bytes = bytes.to_vec();
41 let bytes_len = bytes.len() * 8;
42 bytes.push(0x80);
43
44 while (bytes.len() % 64) != 56 {
45 bytes.push(0);
46 }
47
48 for i in bytes_len.to_be_bytes().iter() {
49 bytes.push(*i);
50 }
51
52 let mut temp: [u32; 8] = [0u32; 8];
53 temp[0] = H0;
54 temp[1] = H1;
55 temp[2] = H2;
56 temp[3] = H3;
57 temp[4] = H4;
58 temp[5] = H5;
59 temp[6] = H6;
60 temp[7] = H7;
61
62 for chunk in bytes.as_slice().chunks(64) {
63 let mut w = [0; 64];
64
65 for (w, d) in w.iter_mut().zip(chunk.iter().step_by(4)).take(16) {
66 *w = u32::from_be_bytes(unsafe { *(d as *const u8 as *const [u8; 4]) });
67 }
68
69 for i in 16..64 {
70 let s0: u32 = w[i - 15].rotate_right(7) ^ w[i - 15].rotate_right(18) ^ (w[i - 15] >> 3);
71 let s1: u32 = w[i - 2].rotate_right(17) ^ w[i - 2].rotate_right(19) ^ (w[i - 2] >> 10);
72 w[i] = w[i - 16]
73 .wrapping_add(s0)
74 .wrapping_add(w[i - 7])
75 .wrapping_add(s1);
76 }
77
78 let mut a = temp[0];
79 let mut b = temp[1];
80 let mut c = temp[2];
81 let mut d = temp[3];
82 let mut e = temp[4];
83 let mut f = temp[5];
84 let mut g = temp[6];
85 let mut h = temp[7];
86
87 for i in 0..64 {
88 let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25);
89 let ch = (e & f) ^ (!e & g);
90 let temp1 = h
91 .wrapping_add(s1)
92 .wrapping_add(ch)
93 .wrapping_add(K[i])
94 .wrapping_add(w[i]);
95 let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22);
96 let maj = (a & b) ^ (a & c) ^ (b & c);
97 let temp2 = s0.wrapping_add(maj);
98
99 h = g;
100 g = f;
101 f = e;
102 e = d.wrapping_add(temp1);
103 d = c;
104 c = b;
105 b = a;
106 a = temp1.wrapping_add(temp2);
107 }
108
109 temp[0] = temp[0].wrapping_add(a);
110 temp[1] = temp[1].wrapping_add(b);
111 temp[2] = temp[2].wrapping_add(c);
112 temp[3] = temp[3].wrapping_add(d);
113 temp[4] = temp[4].wrapping_add(e);
114 temp[5] = temp[5].wrapping_add(f);
115 temp[6] = temp[6].wrapping_add(g);
116 temp[7] = temp[7].wrapping_add(h);
117 }
118
119 let temp = temp
120 .iter()
121 .map(|x| x.to_be_bytes())
122 .collect::<Vec<[u8; 4]>>()
123 .concat();
124
125 let mut result = [0u8; 32];
126 result.copy_from_slice(temp.as_slice());
127 result
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 fn it_works() {
136 assert_eq!(
137 sha256(b"Test"),
138 [
139 83, 46, 170, 189, 149, 116, 136, 13, 191, 118, 185, 184, 204, 0, 131, 44, 32, 166,
140 236, 17, 61, 104, 34, 153, 85, 13, 122, 110, 15, 52, 94, 37
141 ]
142 );
143
144 assert_eq!(
145 sha256(b"Rust"),
146 [
147 217, 170, 137, 253, 209, 90, 213, 196, 29, 156, 18, 143, 239, 254, 158, 7, 220,
148 130, 139, 131, 248, 82, 150, 247, 244, 43, 218, 80, 104, 33, 48, 14
149 ]
150 );
151
152 assert_eq!(
153 sha256(b"hello world"),
154 [
155 185, 77, 39, 185, 147, 77, 62, 8, 165, 46, 82, 215, 218, 125, 171, 250, 196, 132,
156 239, 227, 122, 83, 128, 238, 144, 136, 247, 172, 226, 239, 205, 233
157 ]
158 );
159
160 assert_eq!(
161 sha256(b"Lorem ipsum dolor sit amet, consectetur adipiscing elit"),
162 [
163 7, 254, 77, 74, 37, 113, 130, 65, 175, 20, 90, 147, 248, 144, 235, 84, 105, 5, 46,
164 37, 29, 25, 157, 23, 59, 211, 189, 80, 195, 187, 77, 162
165 ]
166 );
167
168 assert_eq!(
169 sha256(b"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."),
170 [45, 140, 47, 109, 151, 140, 162, 23, 18, 181, 246, 222, 54, 201, 211, 31, 168, 233, 106, 79, 165, 216, 255, 139, 1, 136, 223, 185, 231, 193, 113, 187]
171 );
172 }
173}