AkurAI Build
Menu

Public repository / master

AkurAI-Framework / crates/crypto/tests/vectors.rs

Latest change 3aae9f4e85241bcb775c31f5c03094becd3da56a - Pure-Rust UI layer: akurai-ui, akurai-crypto, Tailwind-grade akurai-css by Ólafur Búi Ólafsson

//! Known-answer tests from the defining standards.

use akurai_crypto::{from_hex, hex, hmac_sha256, pbkdf2_sha256, sha256, Sha256};

fn unhex(s: &str) -> Vec<u8> {
    from_hex(&s.replace(' ', "")).expect("valid hex in test vector")
}

// ---- SHA-256: FIPS 180-2 ----

#[test]
fn sha256_empty() {
    assert_eq!(
        hex(&sha256(b"")),
        "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    );
}

#[test]
fn sha256_abc() {
    assert_eq!(
        hex(&sha256(b"abc")),
        "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
    );
}

#[test]
fn sha256_448_bit_message() {
    let msg = b"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
    assert_eq!(
        hex(&sha256(msg)),
        "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"
    );
}

#[test]
fn sha256_one_million_a_incremental() {
    let chunk = [b'a'; 1000];
    let mut h = Sha256::new();
    for _ in 0..1000 {
        h.update(&chunk);
    }
    assert_eq!(
        hex(&h.finalize()),
        "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"
    );
}

#[test]
fn sha256_incremental_matches_one_shot_at_odd_splits() {
    let data: Vec<u8> = (0..300u32).map(|i| (i * 7) as u8).collect();
    for split in [0, 1, 55, 56, 63, 64, 65, 127, 128, 299, 300] {
        let mut h = Sha256::new();
        h.update(&data[..split]);
        h.update(&data[split..]);
        assert_eq!(h.finalize(), sha256(&data), "split at {split}");
    }
}

// ---- HMAC-SHA-256: RFC 4231 ----

fn check_hmac(key: &[u8], msg: &[u8], expected: &str) {
    assert_eq!(hex(&hmac_sha256(key, msg)), expected);
}

#[test]
fn hmac_rfc4231_case_1() {
    check_hmac(
        &[0x0b; 20],
        b"Hi There",
        "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
    );
}

#[test]
fn hmac_rfc4231_case_2() {
    check_hmac(
        b"Jefe",
        b"what do ya want for nothing?",
        "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
    );
}

#[test]
fn hmac_rfc4231_case_3() {
    check_hmac(
        &[0xaa; 20],
        &[0xdd; 50],
        "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
    );
}

#[test]
fn hmac_rfc4231_case_4() {
    let key: Vec<u8> = (1..=25).collect();
    check_hmac(
        &key,
        &[0xcd; 50],
        "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
    );
}

#[test]
fn hmac_rfc4231_case_6_long_key() {
    check_hmac(
        &[0xaa; 131],
        b"Test Using Larger Than Block-Size Key - Hash Key First",
        "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
    );
}

#[test]
fn hmac_rfc4231_case_7_long_key_and_data() {
    check_hmac(
        &[0xaa; 131],
        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.",
        "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2",
    );
}

// ---- PBKDF2-HMAC-SHA-256: RFC 7914 §11 ----

#[test]
fn pbkdf2_rfc7914_passwd_salt_1() {
    let mut out = [0u8; 64];
    pbkdf2_sha256(b"passwd", b"salt", 1, &mut out);
    let expected = unhex(
        "55 ac 04 6e 56 e3 08 9f ec 16 91 c2 25 44 b6 05 \
         f9 41 85 21 6d de 04 65 e6 8b 9d 57 c2 0d ac bc \
         49 ca 9c cc f1 79 b6 45 99 16 64 b3 9d 77 ef 31 \
         7c 71 b8 45 b1 e3 0b d5 09 11 20 41 d3 a1 97 83",
    );
    assert_eq!(out.to_vec(), expected);
}

#[test]
fn pbkdf2_rfc7914_password_nacl_80000() {
    let mut out = [0u8; 64];
    pbkdf2_sha256(b"Password", b"NaCl", 80_000, &mut out);
    let expected = unhex(
        "4d dc d8 f6 0b 98 be 21 83 0c ee 5e f2 27 01 f9 \
         64 1a 44 18 d0 4c 04 14 ae ff 08 87 6b 34 ab 56 \
         a1 d4 25 a1 22 58 33 54 9a db 84 1b 51 c9 b3 17 \
         6a 27 2b de bb a1 d0 78 47 8f 62 b3 97 f3 3c 8d",
    );
    assert_eq!(out.to_vec(), expected);
}

#[test]
fn pbkdf2_short_output_is_prefix_of_long_output() {
    let mut long = [0u8; 64];
    let mut short = [0u8; 20];
    pbkdf2_sha256(b"passwd", b"salt", 1, &mut long);
    pbkdf2_sha256(b"passwd", b"salt", 1, &mut short);
    assert_eq!(&long[..20], &short[..]);
}