Estado: ⚠️ Aceptada con limitación documentada Fecha: 2026-05-29 Bloque: Z1f (continuación del debug Argon2id) Bump on-disk: VERSION 30 → 31

🧭 Contexto

Z1e (ADR-0060) shippeó la estructura completa de Argon2id pero el output no matcheaba RFC 9106 §A.3 (primer byte 0xa6 vs esperado 0x0a). Z1f es el primer round de debug.

Tras re-leer RFC 9106 §3.4.1.2 vs libargon2 reference impl (src/ref.c::index_alpha), identifiqué un bug claro: la convención del edge case adjustment para cross-lane referencing.

💡 Bug identificado y corregido

Convención libargon2 (correcta)

Per index_alpha en libargon2:

if (same_lane) {
    reference_area_size = lane_length - segment_length + position->index - 1;
} else {
    reference_area_size = lane_length - segment_length +
                          ((position->index == 0) ? -1 : 0);
}

Para cross-lane reference:

Donde X = slice * sl para pass 0, 3 * sl para pass > 0.

Bug Z1e (invertido)

Mi código tenía:

let same_slice_extra: u64 = if j == slice_start { 0 } else { 1 };

Que da:

Exactamente lo opuesto de la convención correcta.

Fix Z1f

let edge_sub: u64 = if j == slice_start { 1 } else { 0 };

📊 Efecto del fix en el RFC vector

Estado Output (primer byte) Output (32 bytes hex)
Esperado RFC §A.3 0a 0aa4c4248e30e06eff5ee38e71b1ffc7c789e87ea4336fafcda4a34dcb894da5
Z1e (pre-fix) a6 a6d06b41464b6e79c1a2454cfb08644d922670fefe160615d69c5c6787ad0de8
Z1f (post-fix) 0d 0d640df58d78766c08c037a34a8b53c9d01ef0452d75b65eb52520e96b01e659

El fix cambia el output significativamente, confirmando que afecta la indexación. El primer byte pasa de 0xa6 a 0x0d (más cerca del esperado 0x0a pero todavía distinto). Bug(s) adicional(es) restantes.

⛔ Lo que queda pendiente (Z1g)

Bugs candidatos remaining (no he logrado aislar cuál):

Z1g debe aislar el bug restante, probablemente añadiendo trazas paso-a-paso y comparando contra una reference impl Rust externa.

📁 Archivos tocados

🧪 Tests

🔗 Referencias