crypto-async-rs 0.1.3

High-performance pure Rust cryptographic library with async streaming support
Documentation
//! Example demonstrating HKDF (HMAC-based Key Derivation Function)
//!
//! This example shows how to use the HKDF implementation for key derivation.

use crypto_async_rs::hkdf;

fn main() {
    println!("HKDF Example");
    println!("============");

    // Test data
    let salt = b"random-salt";
    let ikm = b"input-key-material"; // Initial Key Material
    let info = b"application-info"; // Application-specific information

    println!("Salt: {}", String::from_utf8_lossy(salt));
    println!("IKM (Input Key Material): {}", String::from_utf8_lossy(ikm));
    println!("Info: {}", String::from_utf8_lossy(info));

    println!("\nExtract phase...");
    let prk = hkdf::extract_sha256(salt, ikm);
    println!("PRK (Pseudorandom Key): {:02x?}", prk);
    println!("PRK (hex): {:02x?}", prk);

    println!("\nExpand phase...");
    let encryption_key_len = 32; // 256 bits
    let mac_key_len = 32; // 256 bits
    let iv_len = 16; // 128 bits

    let encryption_key = hkdf::expand_sha256(&prk, b"encryption-key", encryption_key_len);
    let mac_key = hkdf::expand_sha256(&prk, b"mac-key", mac_key_len);
    let iv = hkdf::expand_sha256(&prk, b"initialization-vector", iv_len);

    println!("Encryption key ({} bytes): {:02x?}", encryption_key.len(), &encryption_key);
    println!("MAC key ({} bytes): {:02x?}", mac_key.len(), &mac_key);
    println!("IV ({} bytes): {:02x?}", iv.len(), &iv);

    println!("\nDemonstrating info string sensitivity...");
    let key1 = hkdf::expand_sha256(&prk, b"purpose-1", 32);
    let key2 = hkdf::expand_sha256(&prk, b"purpose-2", 32);
    
    println!("Key for purpose-1: {:02x?}", &key1[..8]);
    println!("Key for purpose-2: {:02x?}", &key2[..8]);
    
    if key1 != key2 {
        println!("✅ Different info strings produce different keys");
    } else {
        println!("❌ Different info strings produce the same key (this should not happen)");
    }

    println!("\nDemonstrating length sensitivity...");
    let short_key = hkdf::expand_sha256(&prk, info, 16);
    let long_key = hkdf::expand_sha256(&prk, info, 64);
    
    println!("Short key (16 bytes): {:02x?}", &short_key);
    println!("Long key (64 bytes): {:02x?}", &long_key[..16]);
    println!("Long key length: {} bytes", long_key.len());

    println!("\nTesting with empty salt...");
    let prk_empty_salt = hkdf::extract_sha256(b"", ikm);
    let key_empty_salt = hkdf::expand_sha256(&prk_empty_salt, info, 32);
    println!("Key with empty salt: {:02x?}", &key_empty_salt[..8]);

    println!("\nTesting with empty info...");
    let key_empty_info = hkdf::expand_sha256(&prk, b"", 32);
    println!("Key with empty info: {:02x?}", &key_empty_info[..8]);

    println!("\nDemonstrating deterministic behavior...");
    let key1_repeat = hkdf::expand_sha256(&prk, info, 32);
    let key2_repeat = hkdf::expand_sha256(&prk, info, 32);
    
    if key1_repeat == key2_repeat {
        println!("✅ HKDF is deterministic - same inputs produce same outputs");
    } else {
        println!("❌ HKDF is not deterministic (this should not happen)");
    }

    println!("\n✅ HKDF example completed successfully!");
}