Skip to content

Commit 3bad194

Browse files
feat: add SHA-2 family of hash functions (#1032)
1 parent 1c7738e commit 3bad194

File tree

5 files changed

+569
-379
lines changed

5 files changed

+569
-379
lines changed

DIRECTORY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
* [ROT13](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/rot13.rs)
5656
* [RSA Cipher](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/rsa_cipher.rs)
5757
* [Salsa](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/salsa.rs)
58-
* [SHA-256](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/sha256.rs)
58+
* [SHA-2](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/sha2.rs)
5959
* [SHA-3](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/sha3.rs)
6060
* [Tea](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/tea.rs)
6161
* [Theoretical ROT13](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/theoretical_rot13.rs)

src/ciphers/hashing_traits.rs

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
pub trait Hasher<const DIGEST_BYTES: usize> {
2-
/// return a new instance with default parameters
2+
/// Return a new instance with default parameters.
33
fn new_default() -> Self;
44

5-
/// Add new data
5+
/// Add new data.
66
fn update(&mut self, data: &[u8]);
77

8-
/// Returns the hash of current data. If it is necessary does finalization
9-
/// work on the instance, thus it may no longer make sense to do `update`
8+
/// Returns the hash of current data. If necessary does finalization work
9+
/// on the instance, thus it may no longer make sense to call `update`
1010
/// after calling this.
1111
fn get_hash(&mut self) -> [u8; DIGEST_BYTES];
1212
}
1313

14-
/// HMAC based on RFC2104, applicable to many cryptographic hash functions
14+
/// HMAC based on RFC 2104, applicable to many cryptographic hash functions.
1515
pub struct HMAC<const KEY_BYTES: usize, const DIGEST_BYTES: usize, H: Hasher<DIGEST_BYTES>> {
1616
pub inner_internal_state: H,
1717
pub outer_internal_state: H,
@@ -27,25 +27,24 @@ impl<const KEY_BYTES: usize, const DIGEST_BYTES: usize, H: Hasher<DIGEST_BYTES>>
2727
}
2828
}
2929

30-
/// Note that `key` must be no longer than `KEY_BYTES`. According to RFC,
31-
/// if it is so, you should replace it with its hash. We do not do this
32-
/// automatically due to fear of `DIGEST_BYTES` not being the same as
33-
/// `KEY_BYTES` or even being longer than it
30+
/// Note that `key` must be no longer than `KEY_BYTES`. According to the
31+
/// RFC, if it is so, you should replace it with its hash. We do not do
32+
/// this automatically due to fear of `DIGEST_BYTES` not being the same as
33+
/// `KEY_BYTES` or even being longer than it.
3434
pub fn add_key(&mut self, key: &[u8]) -> Result<(), &'static str> {
3535
match key.len().cmp(&KEY_BYTES) {
3636
std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
3737
let mut tmp_key = [0u8; KEY_BYTES];
3838
for (d, s) in tmp_key.iter_mut().zip(key.iter()) {
3939
*d = *s;
4040
}
41-
// key ^ 0x363636.. should be used as inner key
41+
// key XOR 0x363636… is the inner key
4242
for b in tmp_key.iter_mut() {
4343
*b ^= 0x36;
4444
}
4545
self.inner_internal_state.update(&tmp_key);
46-
// key ^ 0x5c5c5c.. should be used as outer key, but the key is
47-
// already XORed with 0x363636.. , so it must now be XORed with
48-
// 0x6a6a6a..
46+
// key XOR 0x5c5c5c… is the outer key; the key is already
47+
// XORed with 0x36, so XOR with 0x6a to get the net 0x5c.
4948
for b in tmp_key.iter_mut() {
5049
*b ^= 0x6a;
5150
}
@@ -66,24 +65,3 @@ impl<const KEY_BYTES: usize, const DIGEST_BYTES: usize, H: Hasher<DIGEST_BYTES>>
6665
self.outer_internal_state.get_hash()
6766
}
6867
}
69-
70-
#[cfg(test)]
71-
mod tests {
72-
use super::super::sha256::tests::get_hash_string;
73-
use super::super::SHA256;
74-
use super::HMAC;
75-
76-
#[test]
77-
fn sha256_basic() {
78-
// To test this, use the following command on linux:
79-
// echo -n "Hello World" | openssl sha256 -hex -mac HMAC -macopt hexkey:"deadbeef"
80-
let mut hmac: HMAC<64, 32, SHA256> = HMAC::new_default();
81-
hmac.add_key(&[0xde, 0xad, 0xbe, 0xef]).unwrap();
82-
hmac.update(b"Hello World");
83-
let hash = hmac.finalize();
84-
assert_eq!(
85-
get_hash_string(&hash),
86-
"f585fc4536e8e7f378437465b65b6c2eb79036409b18a7d28b6d4c46d3a156f8"
87-
);
88-
}
89-
}

src/ciphers/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ mod rail_fence;
1919
mod rot13;
2020
mod rsa_cipher;
2121
mod salsa;
22-
mod sha256;
22+
mod sha2;
2323
mod sha3;
2424
mod tea;
2525
mod theoretical_rot13;
@@ -41,8 +41,7 @@ pub use self::blake2b::blake2b;
4141
pub use self::caesar::caesar;
4242
pub use self::chacha::chacha20;
4343
pub use self::diffie_hellman::DiffieHellman;
44-
pub use self::hashing_traits::Hasher;
45-
pub use self::hashing_traits::HMAC;
44+
pub use self::hashing_traits::{Hasher, HMAC};
4645
pub use self::hill_cipher::HillCipher;
4746
pub use self::kernighan::kernighan;
4847
pub use self::morse_code::{decode, encode};
@@ -53,7 +52,7 @@ pub use self::rsa_cipher::{
5352
decrypt, decrypt_text, encrypt, encrypt_text, generate_keypair, PrivateKey, PublicKey,
5453
};
5554
pub use self::salsa::salsa20;
56-
pub use self::sha256::SHA256;
55+
pub use self::sha2::{sha224, sha256, sha384, sha512, sha512_224, sha512_256};
5756
pub use self::sha3::{sha3_224, sha3_256, sha3_384, sha3_512};
5857
pub use self::tea::{tea_decrypt, tea_encrypt};
5958
pub use self::theoretical_rot13::theoretical_rot13;

0 commit comments

Comments
 (0)