use crypto_async_rs::hkdf;
fn main() {
println!("HKDF Example");
println!("============");
let salt = b"random-salt";
let ikm = b"input-key-material"; let info = b"application-info";
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; let mac_key_len = 32; let iv_len = 16;
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!");
}