Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created October 14, 2025 12:55
Show Gist options
  • Save rust-play/a63a9bea46df904c1e4874bdcf34d311 to your computer and use it in GitHub Desktop.
Save rust-play/a63a9bea46df904c1e4874bdcf34d311 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
//#![no_std]
extern crate alloc;
use alloc::vec::Vec;
/// Placeholder for the real SHA-256 function.
/// It only uses the length of the data to generate a predictable output.
fn sha256_placeholder(data: &[u8]) -> [u8; 32] {
let mut hash = [0u8; 32];
let len_bytes = (data.len() as u32).to_le_bytes();
hash[0..4].copy_from_slice(&len_bytes);
hash
}
const SHA256_BLOCK_SIZE: usize = 64;
const SHA256_OUTPUT_SIZE: usize = 32;
/// Implements the HMAC algorithm structure using the SHA-256 constants
/// and the placeholder hash function.
fn hmac_sha256_std_only(key: &[u8], message: &[u8]) -> [u8; SHA256_OUTPUT_SIZE] {
let mut key_padded: Vec<u8> = key.to_vec();
// 1. Key Pre-processing: Hash long keys down to output size
if key_padded.len() > SHA256_BLOCK_SIZE {
let hashed_key = sha256_placeholder(&key_padded);
key_padded = hashed_key.to_vec();
}
// Pad or truncate key_padded to block size (64 bytes)
key_padded.resize(SHA256_BLOCK_SIZE, 0x00);
// --- Inner Hash (H((K XOR ipad) || M)) ---
let ipad: [u8; SHA256_BLOCK_SIZE] = [0x36; SHA256_BLOCK_SIZE];
// K XOR ipad
let mut inner_key_pad = key_padded.clone();
for (i, &k_byte) in key_padded.iter().enumerate() {
inner_key_pad[i] = k_byte ^ ipad[i];
}
// (K XOR ipad) || M
let mut inner_hash_input = inner_key_pad;
inner_hash_input.extend_from_slice(message);
// H(...)
let inner_hash = sha256_placeholder(&inner_hash_input);
// --- Outer Hash (H((K XOR opad) || Inner Hash)) ---
let opad: [u8; SHA256_BLOCK_SIZE] = [0x5c; SHA256_BLOCK_SIZE];
// K XOR opad
let mut outer_key_pad = key_padded.clone();
for (i, &k_byte) in key_padded.iter().enumerate() {
outer_key_pad[i] = k_byte ^ opad[i];
}
// (K XOR opad) || Inner Hash
let mut outer_hash_input = outer_key_pad;
outer_hash_input.extend_from_slice(&inner_hash);
// Final H(...)
sha256_placeholder(&outer_hash_input)
}
fn main() {
let key = b"my_secret_key";
let message = b"The data to be authenticated by HMAC.";
let hmac_result = hmac_sha256_std_only(key, message);
let _ = hmac_result;
}
// ---------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hmac_placeholder_logic_check() {
let key = b"test_key";
let message = b"hello_world";
let mac1 = hmac_sha256_std_only(key, message);
let mac2 = hmac_sha256_std_only(key, message);
// 1. Core Check: Must generate the same output for the same input
assert_eq!(mac1, mac2, "HMAC must be deterministic.");
// 2. Test key length handling (key longer than block size)
let long_key = b"This is a very long key that is definitely more than 64 bytes for SHA256 block size";
let mac_long_key_a = hmac_sha256_std_only(long_key, message);
let mac_long_key_b = hmac_sha256_std_only(long_key, message);
assert_eq!(mac_long_key_a, mac_long_key_b, "Long key handling must be deterministic.");
// 3. Test key length handling (key shorter than block size)
let short_key = b"short";
let mac_short_key_a = hmac_sha256_std_only(short_key, message);
let mac_short_key_b = hmac_sha256_std_only(short_key, message);
assert_eq!(mac_short_key_a, mac_short_key_b, "Short key handling must be deterministic.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment