Initial import and port from C++ code.

This commit is contained in:
2025-12-28 13:45:13 -07:00
commit ddf44d7e33
13 changed files with 1165 additions and 0 deletions

43
tests/common.rs Normal file
View File

@@ -0,0 +1,43 @@
const LUT: [&str; 256] = [
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a",
"0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15",
"16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20",
"21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b",
"2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36",
"37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41",
"42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c",
"4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57",
"58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62",
"63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d",
"6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78",
"79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83",
"84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e",
"8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
"9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4",
"a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba",
"bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5",
"c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0",
"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db",
"dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6",
"e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1",
"f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc",
"fd", "fe", "ff",
];
pub fn hexstr<const N: usize, const M: usize>(
input: &[u8; N],
output: &mut [u8; M],
) {
assert_eq!(M, N * 2);
let mut i: usize = 0;
let mut o: usize = 0;
while i < N {
let lutc = LUT[input[i] as usize].as_bytes();
output[o] = lutc[0];
output[o + 1] = lutc[1];
o += 2;
i += 1;
}
}

116
tests/hmac.rs Normal file
View File

@@ -0,0 +1,116 @@
mod common;
use common::hexstr;
use emsha::{hmac, sha256, Hash, Result};
#[test]
fn test_hmac_00() -> Result<()> {
let k: [u8; 20] = [
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
];
let input = b"Hi There";
let output = b"b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
hexstr(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_01() -> Result<()> {
let k: [u8; 4] = [0x4a, 0x65, 0x66, 0x65];
let input = b"what do ya want for nothing?";
let output = b"5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
hexstr(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_02() -> Result<()> {
let k: [u8; 20] = [
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
];
let input = &[0xddu8; 50];
let output = b"773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
hexstr(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_03() -> Result<()> {
let k: [u8; 25] = [
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19,
];
let input = &[0xcdu8; 50];
let output = b"82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
hexstr(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_04() -> Result<()> {
let k = [0xaau8; 131];
let input =
b"Test Using Larger Than Block-Size Key - Hash Key First";
let output = b"60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
hexstr(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}
#[test]
fn test_hmac_05() -> Result<()> {
let k = [0xaau8; 131];
let input = b"This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.";
let output = b"9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2";
let mut digest: [u8; sha256::SIZE] = [0; sha256::SIZE];
let mut hdigest: [u8; 64] = [0; 64];
let mut h = hmac::HMAC_SHA256::new(&k)?;
h.update(input)?;
h.finalize(&mut digest)?;
hexstr(&digest, &mut hdigest);
assert_eq!(&hdigest, output);
Ok(())
}

77
tests/sha256.rs Normal file
View File

@@ -0,0 +1,77 @@
mod common;
use common::hexstr;
use emsha::sha256;
use emsha::{Hash, Result};
pub(crate) struct HashTest<'a> {
pub(crate) output: &'a [u8],
pub(crate) input: &'a [u8],
}
impl<'a> HashTest<'a> {
pub fn new(output: &'a [u8], input: &'a [u8]) -> Self {
Self { output, input }
}
}
#[test]
fn test_self_test() -> Result<()> {
sha256::self_test()?;
Ok(())
}
#[test]
fn test_golden_tests() -> Result<()> {
let golden_tests: &[HashTest] = &[
HashTest::new(b"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", b""),
HashTest::new(b"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", b"a"),
HashTest::new(b"fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603", b"ab"),
HashTest::new(b"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", b"abc"),
HashTest::new(b"88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589", b"abcd"),
HashTest::new(b"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c", b"abcde"),
HashTest::new(b"bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721", b"abcdef"),
HashTest::new(b"7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a", b"abcdefg"),
HashTest::new(b"9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab", b"abcdefgh"),
HashTest::new(b"19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f", b"abcdefghi"),
HashTest::new(b"72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0", b"abcdefghij"),
HashTest::new(b"a144061c271f152da4d151034508fed1c138b8c976339de229c3bb6d4bbb4fce", b"Discard medicine more than two years old."),
HashTest::new(b"6dae5caa713a10ad04b46028bf6dad68837c581616a1589a265a11288d4bb5c4", b"He who has a shady past knows that nice guys finish last."),
HashTest::new(b"ae7a702a9509039ddbf29f0765e70d0001177914b86459284dab8b348c2dce3f", b"I wouldn't marry him with a ten foot pole."),
HashTest::new(b"6748450b01c568586715291dfa3ee018da07d36bb7ea6f180c1af6270215c64f", b"Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"),
HashTest::new(b"14b82014ad2b11f661b5ae6a99b75105c2ffac278cd071cd6c05832793635774", b"The days of the digital watch are numbered. -Tom Stoppard"),
HashTest::new(b"7102cfd76e2e324889eece5d6c41921b1e142a4ac5a2692be78803097f6a48d8", b"Nepal premier won't resign."),
HashTest::new(b"23b1018cd81db1d67983c5f7417c44da9deb582459e378d7a068552ea649dc9f", b"For every action there is an equal and opposite government program."),
HashTest::new(b"8001f190dfb527261c4cfcab70c98e8097a7a1922129bc4096950e57c7999a5a", b"His money is twice tainted: 'taint yours and 'taint mine."),
HashTest::new(b"8c87deb65505c3993eb24b7a150c4155e82eee6960cf0c3a8114ff736d69cad5", b"There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"),
HashTest::new(b"bfb0a67a19cdec3646498b2e0f751bddc41bba4b7f30081b0b932aad214d16d7", b"It's a tiny change to the code and not completely disgusting. - Bob Manchek"),
HashTest::new(b"7f9a0b9bf56332e19f5a0ec1ad9c1425a153da1c624868fda44561d6b74daf36", b"size: a.out: bad magic"),
HashTest::new(b"b13f81b8aad9e3666879af19886140904f7f429ef083286195982a7588858cfc", b"The major problem is with sendmail. -Mark Horton"),
HashTest::new(b"b26c38d61519e894480c70c8374ea35aa0ad05b2ae3d6674eec5f52a69305ed4", b"Give me a rock, paper and scissors and I will move the world. CCFestoon"),
HashTest::new(b"049d5e26d4f10222cd841a119e38bd8d2e0d1129728688449575d4ff42b842c1", b"If the enemy is within range, then so are you."),
HashTest::new(b"0e116838e3cc1c1a14cd045397e29b4d087aa11b0853fc69ec82e90330d60949", b"It's well we cannot hear the screams/That we create in others' dreams."),
HashTest::new(b"4f7d8eb5bcf11de2a56b971021a444aa4eafd6ecd0f307b5109e4e776cd0fe46", b"You remind me of a TV show, but that's all right: I watch it anyway."),
HashTest::new(b"61c0cc4c4bd8406d5120b3fb4ebc31ce87667c162f29468b3c779675a85aebce", b"C is as portable as Stonehedge!!"),
HashTest::new(b"1fb2eb3688093c4a3f80cd87a5547e2ce940a4f923243a79a2a1e242220693ac", b"Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"),
HashTest::new(b"395585ce30617b62c80b93e8208ce866d4edc811a177fdb4b82d3911d8696423", b"The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"),
HashTest::new(b"4f9b189a13d030838269dce846b16a1ce9ce81fe63e65de2f636863336a98fe6", b"How can you write a big system without C++? -Paul Glick"),
];
let mut i: usize = 0;
let mut h = sha256::SHA256::default();
let mut d: [u8; 32] = [0; 32];
let mut s: [u8; 64] = [0; 64];
while i < golden_tests.len() {
eprintln!("golden test: {:}", i);
h.update(golden_tests[i].input)?;
h.finalize(&mut d)?;
hexstr(&d, &mut s);
assert_eq!(s, golden_tests[i].output);
h.reset()?;
i += 1;
}
Ok(())
}