/** * RFC 4226 ยง5.3 โ€” dynamic truncation. * * Given an HMAC output (H) and a target digit width (N), produce the N- * digit OTP: * * 1. offset = H[19] & 0x0f (the low 4 bits of the last byte) * 2. bin = H[offset .. offset+3] (4 bytes big-endian) & 0x7fffffff * 3. code = bin % 10^N (numeric N-digit string, left-padded) * * The mask on the top byte drops the sign bit so we never build a * negative int on platforms where 4-byte reads are signed. This is a * hot path โ€” called once per verify + up to (2*window+1) attempts โ€” * so we keep it allocation-free. * * @param {Buffer} hmac Full HMAC digest (20/32/64 bytes depending on algorithm). * @param {number} digits Target OTP length, 6-10. * @returns {string} Zero-padded N-digit code. */ export function truncate(hmac: Buffer, digits: number): string;