|
1 |
| -//! SHA-2 (256 Bit) |
2 |
| -
|
| 1 | +/// Represents the state of the buffer used in the SHA256 algorithm. |
3 | 2 | struct BufState {
|
| 3 | + // The data to process. |
4 | 4 | data: Vec<u8>,
|
| 5 | + // The length of the data. |
5 | 6 | len: usize,
|
| 7 | + // The total length of the data. |
6 | 8 | total_len: usize,
|
| 9 | + // A flag indicating if the buffer has a single byte. |
7 | 10 | single: bool,
|
| 11 | + // A flag indicating if the buffer has been fully processed. |
8 | 12 | total: bool,
|
9 | 13 | }
|
10 | 14 |
|
| 15 | +/// Computes the SHA256 hash of the given data. |
| 16 | +/// |
| 17 | +/// # Arguments |
| 18 | +/// |
| 19 | +/// * `data` - The input data to compute the hash for. |
| 20 | +/// |
| 21 | +/// # Returns |
| 22 | +/// |
| 23 | +/// The computed SHA256 hash as a fixed-size array of 32 bytes. |
| 24 | +/// |
| 25 | +/// # References |
| 26 | +/// |
| 27 | +/// * [Wikipedia](https://en.wikipedia.org/wiki/SHA-2) |
| 28 | +/// * [NIST FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf) |
| 29 | +/// * [RFC 6234](https://tools.ietf.org/html/rfc6234) |
| 30 | +/// * [SHA-256](https://csrc.nist.gov/csrc/media/publications/fips/180/4/archive/2012-03-06/documents/fips180-4.pdf) |
| 31 | +/// * [SHA-256 Test Vectors](https://www.di-mgt.com.au/sha_testvectors.html) |
| 32 | +/// |
| 33 | +/// # Examples |
| 34 | +/// |
| 35 | +/// ```rust |
| 36 | +/// use rust_algorithms::ciphers::sha256; |
| 37 | +/// |
| 38 | +/// let hash = sha256(b"The quick brown fox jumps over the lazy dog"); |
| 39 | +/// |
| 40 | +/// assert_eq!(hash, |
| 41 | +/// [0xD7, 0xA8, 0xFB, 0xB3, 0x07, 0xD7, 0x80, 0x94, 0x69, 0xCA, 0x9A, 0xBC, 0xB0, 0x08, |
| 42 | +/// 0x2E, 0x4F, 0x8D, 0x56, 0x51, 0xE4, 0x6D, 0x3C, 0xDB, 0x76, 0x2D, 0x02, 0xD0, 0xBF, |
| 43 | +/// 0x37, 0xC9, 0xE5, 0x92,]); |
| 44 | +/// ``` |
11 | 45 | pub fn sha256(data: &[u8]) -> [u8; 32] {
|
12 | 46 | let mut hash: [u8; 32] = [0; 32];
|
13 | 47 |
|
| 48 | + // Initial hash values |
| 49 | + // The first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19 |
| 50 | + // (stored in big-endian format) |
14 | 51 | let mut h: [u32; 8] = [
|
15 | 52 | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
|
16 | 53 | 0x5be0cd19,
|
17 | 54 | ];
|
18 | 55 |
|
| 56 | + // Round constants |
| 57 | + // The first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311 |
| 58 | + // (stored in big-endian format) |
19 | 59 | let k: [u32; 64] = [
|
20 | 60 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
|
21 | 61 | 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
|
@@ -101,6 +141,17 @@ pub fn sha256(data: &[u8]) -> [u8; 32] {
|
101 | 141 | hash
|
102 | 142 | }
|
103 | 143 |
|
| 144 | +/// Calculates the next chunk of data to process in the SHA256 algorithm. |
| 145 | +/// |
| 146 | +/// # Arguments |
| 147 | +/// |
| 148 | +/// * `chunk` - The buffer to store the next chunk of data. |
| 149 | +/// * `state` - The current state of the buffer. |
| 150 | +/// |
| 151 | +/// # Returns |
| 152 | +/// |
| 153 | +/// A boolean indicating whether the next chunk was successfully calculated. |
| 154 | +/// |
104 | 155 | fn calc_chunk(chunk: &mut [u8; 64], state: &mut BufState) -> bool {
|
105 | 156 | if state.total {
|
106 | 157 | return false;
|
@@ -157,18 +208,6 @@ mod tests {
|
157 | 208 | );
|
158 | 209 | }
|
159 | 210 |
|
160 |
| - #[test] |
161 |
| - fn ascii() { |
162 |
| - assert_eq!( |
163 |
| - sha256(&b"The quick brown fox jumps over the lazy dog".to_vec()), |
164 |
| - [ |
165 |
| - 0xD7, 0xA8, 0xFB, 0xB3, 0x07, 0xD7, 0x80, 0x94, 0x69, 0xCA, 0x9A, 0xBC, 0xB0, 0x08, |
166 |
| - 0x2E, 0x4F, 0x8D, 0x56, 0x51, 0xE4, 0x6D, 0x3C, 0xDB, 0x76, 0x2D, 0x02, 0xD0, 0xBF, |
167 |
| - 0x37, 0xC9, 0xE5, 0x92 |
168 |
| - ] |
169 |
| - ) |
170 |
| - } |
171 |
| - |
172 | 211 | #[test]
|
173 | 212 | fn ascii_avalanche() {
|
174 | 213 | assert_eq!(
|
|
0 commit comments