Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
* [ROT13](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/rot13.rs)
* [RSA Cipher](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/rsa_cipher.rs)
* [Salsa](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/salsa.rs)
* [SHA-256](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/sha256.rs)
* [SHA-2](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/sha2.rs)
* [SHA-3](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/sha3.rs)
* [Tea](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/tea.rs)
* [Theoretical ROT13](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/theoretical_rot13.rs)
Expand Down
46 changes: 12 additions & 34 deletions src/ciphers/hashing_traits.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
pub trait Hasher<const DIGEST_BYTES: usize> {
/// return a new instance with default parameters
/// Return a new instance with default parameters.
fn new_default() -> Self;

/// Add new data
/// Add new data.
fn update(&mut self, data: &[u8]);

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

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

/// Note that `key` must be no longer than `KEY_BYTES`. According to RFC,
/// if it is so, you should replace it with its hash. We do not do this
/// automatically due to fear of `DIGEST_BYTES` not being the same as
/// `KEY_BYTES` or even being longer than it
/// Note that `key` must be no longer than `KEY_BYTES`. According to the
/// RFC, if it is so, you should replace it with its hash. We do not do
/// this automatically due to fear of `DIGEST_BYTES` not being the same as
/// `KEY_BYTES` or even being longer than it.
pub fn add_key(&mut self, key: &[u8]) -> Result<(), &'static str> {
match key.len().cmp(&KEY_BYTES) {
std::cmp::Ordering::Less | std::cmp::Ordering::Equal => {
let mut tmp_key = [0u8; KEY_BYTES];
for (d, s) in tmp_key.iter_mut().zip(key.iter()) {
*d = *s;
}
// key ^ 0x363636.. should be used as inner key
// key XOR 0x363636… is the inner key
for b in tmp_key.iter_mut() {
*b ^= 0x36;
}
self.inner_internal_state.update(&tmp_key);
// key ^ 0x5c5c5c.. should be used as outer key, but the key is
// already XORed with 0x363636.. , so it must now be XORed with
// 0x6a6a6a..
// key XOR 0x5c5c5c… is the outer key; the key is already
// XORed with 0x36, so XOR with 0x6a to get the net 0x5c.
for b in tmp_key.iter_mut() {
*b ^= 0x6a;
}
Expand All @@ -66,24 +65,3 @@ impl<const KEY_BYTES: usize, const DIGEST_BYTES: usize, H: Hasher<DIGEST_BYTES>>
self.outer_internal_state.get_hash()
}
}

#[cfg(test)]
mod tests {
use super::super::sha256::tests::get_hash_string;
use super::super::SHA256;
use super::HMAC;

#[test]
fn sha256_basic() {
// To test this, use the following command on linux:
// echo -n "Hello World" | openssl sha256 -hex -mac HMAC -macopt hexkey:"deadbeef"
let mut hmac: HMAC<64, 32, SHA256> = HMAC::new_default();
hmac.add_key(&[0xde, 0xad, 0xbe, 0xef]).unwrap();
hmac.update(b"Hello World");
let hash = hmac.finalize();
assert_eq!(
get_hash_string(&hash),
"f585fc4536e8e7f378437465b65b6c2eb79036409b18a7d28b6d4c46d3a156f8"
);
}
}
7 changes: 3 additions & 4 deletions src/ciphers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ mod rail_fence;
mod rot13;
mod rsa_cipher;
mod salsa;
mod sha256;
mod sha2;
mod sha3;
mod tea;
mod theoretical_rot13;
Expand All @@ -41,8 +41,7 @@ pub use self::blake2b::blake2b;
pub use self::caesar::caesar;
pub use self::chacha::chacha20;
pub use self::diffie_hellman::DiffieHellman;
pub use self::hashing_traits::Hasher;
pub use self::hashing_traits::HMAC;
pub use self::hashing_traits::{Hasher, HMAC};
pub use self::hill_cipher::HillCipher;
pub use self::kernighan::kernighan;
pub use self::morse_code::{decode, encode};
Expand All @@ -53,7 +52,7 @@ pub use self::rsa_cipher::{
decrypt, decrypt_text, encrypt, encrypt_text, generate_keypair, PrivateKey, PublicKey,
};
pub use self::salsa::salsa20;
pub use self::sha256::SHA256;
pub use self::sha2::{sha224, sha256, sha384, sha512, sha512_224, sha512_256};
pub use self::sha3::{sha3_224, sha3_256, sha3_384, sha3_512};
pub use self::tea::{tea_decrypt, tea_encrypt};
pub use self::theoretical_rot13::theoretical_rot13;
Expand Down
Loading
Loading