AkurAI Build
Menu

Public repository / fee5b6c2cde89fa6bf8dc51068af7336b56a88b8

AkurAI-Framework / crates/crypto/src/pbkdf2.rs

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

//! PBKDF2-HMAC-SHA-256 (RFC 8018 §5.2).

use crate::hmac::HmacKey;

/// Derive `out.len()` bytes from `password` and `salt` with `iterations`
/// rounds of HMAC-SHA-256.
pub fn pbkdf2_sha256(password: &[u8], salt: &[u8], iterations: u32, out: &mut [u8]) {
    let key = HmacKey::new(password);
    for (index, chunk) in out.chunks_mut(32).enumerate() {
        let block = derive_block(&key, salt, iterations, index as u32 + 1);
        chunk.copy_from_slice(&block[..chunk.len()]);
    }
}

/// `T_i = U_1 ^ U_2 ^ … ^ U_c` with `U_1 = PRF(P, S || INT(i))`.
fn derive_block(key: &HmacKey, salt: &[u8], iterations: u32, index: u32) -> [u8; 32] {
    let mut first = salt.to_vec();
    first.extend_from_slice(&index.to_be_bytes());
    let mut u = key.mac(&first);
    let mut t = u;
    for _ in 1..iterations {
        u = key.mac(&u);
        t.iter_mut().zip(&u).for_each(|(t, u)| *t ^= u);
    }
    t
}