sha256_rs/
lib.rs

1//! sha256-rs
2//!
3//! Implementation of the SHA256 hash made using Rust
4
5/// Initializing Variables
6/// First 32 bits of fractional parts of the square roots of the first eight primes
7const 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
16/// Constants table
17/// First 32 bits of the fractional parts of the cube roots of the first 64 primes
18const 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
29/// SHA256 digest bytes
30///
31/// # Example
32///
33/// ```rust
34/// let bytes = b"hello";
35/// let result = sha256_rs::sha256(bytes);
36/// assert_eq!(result, [44, 242, 77, 186, 95, 176, 163, 14, 38, 232, 59, 42, 197, 185, 226, 158, 27, 22, 30, 92, 31, 167, 66, 94, 115, 4, 51, 98, 147, 139, 152, 36])
37/// ```
38///
39pub 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}