Auditoría forense · remediación · 11 de septiembre de 2026

Auditoría

El dictamen, el sello, los documentos y el recuento. Una sola puerta.

Dictamen

Lo que el código sostiene, y lo que un operador honesto todavía debe declarar. No es un certificado. Es leer lo que corre.

Dictamen actualizado

El operador de la base ya no cruza el voto

  • Integridad del acto (pública). Sostenida. Un voto por identidad, padrón por correo único, nulo del secreto del votante, sello Blake2-256 + híbrido P-256/ML-DSA-65 anclado a las claves de la institución (derivadas del secreto de despliegue, no del org_key en Postgres).
  • Secreto frente a quien tiene la base. Sostenido para el administrador institucional. Recibos indexados por una clave del votante envuelta en AES-256-GCM. Nulo no derivable desde org_key. El camino Merkle y el índice de hoja no se persisten. Quien solo vuelca Postgres no une correo con opción.
  • Cadena y oráculo. Libro append-only (disparadores que rechazan UPDATE/DELETE). Hora del DON obligatoria: sin feed vigente la ventana no abre. Claves del DON ligadas al secreto de despliegue y a una semilla por institución, no a la constante pública anterior.

Amenaza frente a control

Enlace o Excel copiable

Cerrado

Control. OTP de seis dígitos al correo del padrón. Pedido no enumerativo. /i/:token redirige a Votante.

Estado. generateInvites, getInvite y voteByInvite rechazan. El padrón ya no descarga credenciales.

Doble voto / no padronado

Sostenido

Control. election_roster + nulo por secreto del votante + recibo único. Merkle de compromisos.

Estado. OTP y sesión de miembro comparten nulo. Invite retirado. Bien.

Operador lee quién votó qué

Cerrado

Control. Cédula ElGamal en el cliente. Recuento homomórfico: se abre la suma, nunca el voto suelto. Recibo con clave del votante. Sin leaf_index ni merkle_path.

Estado. Quien tiene el secreto de despliegue sigue en el TCB y podría desviar el descifrado. El código solo descifra agregados. Guardianes umbral, después.

Tally alterado

Cerrado

Control. Hash encadenado Blake2-256, sello híbrido, verificar sello, disparadores append-only.

Estado. Un SQL UPDATE sobre ballots o chain_blocks aborta. No hay consenso BFT de varios nodos.

Ventana falseada

Cerrado

Control. Oráculo de hora (OCR 3/5) con claves por institución.

Estado. Sin feed vigente o con feed de más de dos minutos, el voto no entra. Ya no se omite el chequeo.

Computación cuántica

Cerrado

Control. Sello híbrido both-must-verify, claves pinneadas a la institución.

Estado. Las claves se derivan del secreto de despliegue, no del org_key volcado. Un HSM físico sigue siendo el siguiente escalón.

IA / perfilamiento (art. 8 bis)

Sostenido

Control. No hay modelo. El voto es un acto, no una inferencia.

Estado. Sostenido. No hay scoring. La EIPD del 15 ter no se dispara.

Suplantación del buzón

Residual

Control. Llave de acceso (WebAuthn) como segundo factor. OTP de seis dígitos como reserva. 10 min, 5 intentos, 5/hora.

Estado. En visores embebidos la llave a menudo no abre: el código de correo sigue siendo un factor sobre el buzón.

Purga / ARSOP Ley 21.719

Cerrado

Control. Canal del titular en Votante. Purga administrativa cubre padrón, roster, OTP, claves envueltas y bitácora.

Estado. Los sellos y el recuento permanecen, sin titular. Eso es la constancia del acto.

Hallazgos cerrados en el runtime

CerradoSello híbrido

verifyHybrid compara las claves del sello con el anillo de la institución, derivado del secreto de despliegue. Un par P-256 + ML-DSA-65 ajeno firma el mismo mensaje y falla. verifyProof exige el híbrido: sin él, el desafío Fiat–Shamir no basta.

CerradoSecreto del voto

El nulo sale del secreto del votante, no de org_key + memberId. Ese secreto viaja en la sesión y se guarda envuelto (AES-256-GCM) bajo una huella del correo. El libro no guarda leaf_index ni el camino Merkle. Verificar sello no publica cédula ni nombre.

ResidualTCB

Los pallets Padrón, Quórum y Oracle existen en Rust. La mesa que vota hoy usa el runtime web, WASM como hasher y disparadores WORM en Postgres. Quien posee el secreto de despliegue sigue siendo TCB: puede desenvolver claves. Quien solo tiene la base, no. Un nodo Substrate en caliente con BFT es el siguiente escalón, no el actual.

CerradoSecretos de reserva

Si falta BETTER_AUTH_SECRET en un despliegue con proyecto, el proceso aborta. En vista previa el pimiento es local y no sale a producción. El OTP y el JWT del votante ya no caen a una cadena pública.

CerradoCédula cerrada

El voto se cifra en el dispositivo (ElGamal exponencial). La urna suma cifrados y abre el total. Comprobar cédula ocurre en el cliente y no envía el azar. El comprobante muestra un código QRM, no un hash de 64 caracteres. Se puede cambiar el voto mientras la mesa esté abierta: cuenta el último.

Residual que todavía no se afirma

  1. El código de correo sigue siendo reserva. La llave de acceso no abre en todos los visores.
  2. Quien tiene el secreto de despliegue puede desenvolver la clave de urna y el secreto del votante. Eso es TCB de plataforma. El código solo descifra sumas.
  3. No hay consenso BFT entre varios nodos Substrate en caliente. El WORM es de base, no de red. El nulo ya no es WORM: se actualiza el puntero al sello vigente.
  4. La membresía se prueba con compromiso + sello institucional, no con Groth16. El camino no se publica.

Quórum es una mesa institucional donde el administrador de la base no reconstruye la cédula. El recuento es público. El titular tiene canal ARSOP. La ciberseguridad jurídica exige seguir diciendo la diferencia: la ley se crea desde el código solo si el código no miente.