redoubt-hkdf-wycheproof 0.1.0-rc.6

Wycheproof test runners and FIPS vectors for HKDF-SHA256 backends
Documentation
// Copyright (c) 2025-2026 Federico Hoerth <memparanoid@gmail.com>
// SPDX-License-Identifier: GPL-3.0-only
// See LICENSE in the repository root for full license text.

//! SHA-256 compress_block test runners.
//!
//! References:
//! [1] FIPS 180-4: Secure Hash Standard (SHS)
//! [2] Crypto Stack Exchange: SHA-256 compression without padding

use redoubt_hkdf_core::HkdfApi;

/// Run SHA-256 compress_block tests (FIPS 180-4 vectors) against a backend.
pub fn run_sha256_compress_block_tests(backend: &mut impl HkdfApi) {
    test_sha256_compress_abc(backend);
    test_sha256_compress_empty(backend);
    test_sha256_compress_zero_block(backend);
}

fn test_sha256_compress_abc(backend: &mut impl HkdfApi) {
    let mut h: [u32; 8] = [
        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
        0x5be0cd19,
    ];

    #[rustfmt::skip]
    let block: [u8; 64] = [
        0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
    ];

    backend.api_sha256_compress_block(&mut h, &block);

    let expected: [u32; 8] = [
        0xba7816bf, 0x8f01cfea, 0x414140de, 0x5dae2223, 0xb00361a3, 0x96177a9c, 0xb410ff61,
        0xf20015ad,
    ];

    assert_eq!(h, expected, "SHA-256 compression mismatch for 'abc'");
}

fn test_sha256_compress_empty(backend: &mut impl HkdfApi) {
    let mut h: [u32; 8] = [
        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
        0x5be0cd19,
    ];

    #[rustfmt::skip]
    let block: [u8; 64] = [
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ];

    backend.api_sha256_compress_block(&mut h, &block);

    let expected: [u32; 8] = [
        0xe3b0c442, 0x98fc1c14, 0x9afbf4c8, 0x996fb924, 0x27ae41e4, 0x649b934c, 0xa495991b,
        0x7852b855,
    ];

    assert_eq!(
        h, expected,
        "SHA-256 compression mismatch for empty message"
    );
}

fn test_sha256_compress_zero_block(backend: &mut impl HkdfApi) {
    let mut h: [u32; 8] = [
        0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
        0x5be0cd19,
    ];

    let block: [u8; 64] = [0u8; 64];

    backend.api_sha256_compress_block(&mut h, &block);

    let expected: [u32; 8] = [
        0xda5698be, 0x17b9b469, 0x62335799, 0x779fbeca, 0x8ce5d491, 0xc0d26243, 0xbafef9ea,
        0x1837a9d8,
    ];

    assert_eq!(h, expected, "SHA-256 compression mismatch for zero block");
}