# Modelo de seguridad: ZNTRPHY

Este documento describe qué protege esta herramienta, qué NO protege, y
cómo verificar de forma independiente las afirmaciones de seguridad más
importantes. Está escrito para que un usuario técnico (o alguien de su
confianza) pueda auditar el producto antes de usarlo con fondos reales.

## Qué protege

- Genera entropía criptográficamente segura (`secrets.token_bytes`, el
  CSPRNG del sistema operativo) para semillas BIP39 de 12 a 24 palabras.
- Deriva claves BIP32/44/49/84/48 usando `embit`, la misma librería que
  corre dentro de SeedSigner, un hardware wallet air-gapped real y
  auditado.
- Construye output descriptors (BIP-380) para single-sig y multisig
  (`wsh(sortedmulti(...))`), verificados contra vectores oficiales y contra
  el test suite del propio Bitcoin Core.
- Nunca se conecta a internet (ver sección de verificación abajo).
- El archivo de exportación opcional se cifra con Argon2id (64 MiB, 3
  iteraciones, 4 lanes, perfil recomendado de RFC 9106) + AES-256-GCM.
  Nada se escribe a disco salvo que el usuario lo pida explícitamente desde
  la pantalla de exportación.

## Qué NO protege / limitaciones honestas

- **No protege contra un sistema operativo o hardware comprometido.** Si la
  máquina donde corre tiene malware, un keylogger, o firmware
  comprometido, ninguna app de software puede garantizar la seguridad de
  las claves generadas. Recomendación: usar una máquina dedicada, arrancada
  desde un sistema operativo "live" (Tails, Ubuntu en USB) que no persista
  nada más allá de la sesión.
- **El borrado de memoria es "best effort", no una garantía.** Python
  (CPython) no permite borrar de forma determinística objetos `str`/`bytes`
  inmutables; solo se puede sobrescribir un `bytearray` mutable
  (`keygen/util/memory_hygiene.py`), y aun así el recolector de basura, la
  paginación a swap, o copias intermedias creadas por las propias
  librerías pueden dejar restos en memoria que este código no controla.
- **La reproducibilidad de los builds no es bit-a-bit.** PyInstaller no
  produce binarios idénticos byte a byte entre corridas (timestamps,
  rutas embebidas). Lo que sí se garantiza: el build es reproducible
  *funcionalmente* a partir del código fuente siguiendo los pasos
  documentados en `packaging/build_*.sh|ps1`, con dependencias fijadas por
  hash (`packaging/requirements.txt`).
- **No hay firma de código (Authenticode/notarización) en esta versión.**
  Esto significa que Windows SmartScreen / macOS Gatekeeper probablemente
  muestren una advertencia al abrir el ejecutable la primera vez. La
  verificación de integridad recomendada es el hash SHA-256
  (`packaging/SHA256SUMS.txt`), no la firma del proveedor.
- **No se hizo una auditoría de seguridad externa independiente.** El
  desarrollo incluyó tests exhaustivos (vectores oficiales BIP32/39,
  cross-checks contra `bip_utils` y contra Bitcoin Core) y una revisión
  interna que encontró y corrigió varios errores reales durante el
  desarrollo, pero eso no reemplaza una auditoría externa. Se recomienda
  fuertemente conseguir una antes de vender el producto a terceros para
  custodiar fondos reales.
- **La interoperabilidad con Sparrow Wallet y Electrum en testnet no se
  verificó de punta a punta con esas aplicaciones reales** durante este
  desarrollo (paso de QA manual pendiente, requiere esas apps instaladas).
  Los descriptors se verificaron contra vectores oficiales y contra el
  parser del propio Bitcoin Core, que es una fuerte señal de corrección,
  pero no reemplaza la prueba de importar un descriptor real en esas
  wallets.

## Cómo verificar que la app nunca se conecta a internet

No hace falta confiar en esta afirmación: se puede verificar de varias
formas independientes:

1. **Correr con la red desconectada.** Desenchufar el cable de red o
   apagar el wifi antes de abrir la app. Debería funcionar exactamente
   igual (porque nunca intenta usar la red).
2. **Revisar el código fuente.** `tests/test_no_network_static_scan.py`
   escanea (con `ast`, no con expresiones regulares) todo `src/keygen/` y
   falla si aparece un import de `socket`, `ssl`, `http`, `urllib`,
   `requests`, `ftplib`, `smtplib`, u otros módulos de red, incluyendo
   imports dinámicos simples (`importlib.import_module("...")`). Puedes
   correrlo tú mismo:
   ```bash
   python -m pytest tests/test_no_network_static_scan.py -v
   ```
3. **Monitorear la red mientras corre.** Con Wireshark, Little Snitch
   (macOS) u OpenSnitch (Linux) corriendo, abrir la app y usarla
   normalmente: no debería verse ningún intento de conexión saliente.
4. **Sandboxearla sin acceso a red.** Correr el binario en una VM o
   contenedor sin interfaz de red configurada.

## Reportar un problema de seguridad

Si encuentras una vulnerabilidad, repórtala de forma responsable al
desarrollador o vendedor de este producto antes de hacerla pública.
