fix: cuadrar el denominador de la nota y ampliar la redondez; dos checks nuevos

El denominador de la nota incluía dos pesos que nunca restan (rbf, peeling) y
excluía uno que sí (input_linkage, hasta 30), así que las deducciones podían
superarlo en 17 puntos y dar negativo. Corregido en ambas direcciones, con los
cortes de banda recalibrados a 79/54 para que ninguna transacción cambie de
banda por el arreglo.

'Redondo' equivalía a 'múltiplo de 0,001 BTC' por dos condiciones redundantes,
y se le escapaban pagos de 10.000 o 50.000 sats. Ahora se mide por ceros
finales y la señal se gradúa.

Dos checks nuevos. El de polvo avisaba de una vinculación futura y nunca
miraba si estaba ocurriendo delante: ahora la detecta cuando el polvo se gasta
junto a monedas normales. Y la consolidación pura (N entradas, 1 salida) no
disparaba el check de inputs innecesarios; ahora se nombra, sin cobrarla dos
veces porque input_linkage ya la penaliza.

tests/test6.js cubre lo nuevo y la coherencia de la nota.
This commit is contained in:
2026-08-08 18:52:40 +02:00
parent 0bfe6dca14
commit 9e7fec873a
5 changed files with 438 additions and 38 deletions
+36 -4
View File
@@ -1,11 +1,26 @@
# Pruebas de la criptografía
# Pruebas
Verifican la derivación watch-only (BIP32, secp256k1, RIPEMD-160, bech32)
contra los **vectores oficiales de los estándares**, no contra resultados
propios. Si un cambio rompe algo, estas pruebas lo dicen.
Dos familias. Las de **criptografía** (test1test4) verifican la derivación
watch-only —BIP32, secp256k1, RIPEMD-160, bech32— contra los **vectores
oficiales de los estándares**, no contra resultados propios. Las de
**heurísticas** (test5test6) comprueban el analizador de privacidad contra
transacciones donde la respuesta se conoce de antemano.
Si un cambio rompe algo, estas pruebas lo dicen.
## Cómo ejecutarlas
Las de heurísticas se ejecutan directamente — se extraen solas del
`dashboard.html`, así que no se desactualizan:
```bash
node tests/test5.js
node tests/test6.js
```
Las de criptografía necesitan una preparación manual (pendiente de
automatizar igual que las otras dos):
Extraer el bloque criptográfico de `dashboard.html` a `crypto.js` (las líneas
que van desde `const B32 = {` hasta el final de `deriveAddresses`), añadir al
principio `const { webcrypto } = require("crypto"); const crypto = webcrypto;`
@@ -33,9 +48,26 @@ Después:
- **test4** — comprueba que esos cuatro siguen cerrados: checksum rota, xpub
truncado, índice endurecido, índice negativo. Y que un `tpub` genera
direcciones de testnet, no de mainnet.
- **test5** — detección del output de cambio. Transacciones donde se sabe de
antemano cuál es el pago y cuál el cambio, más los niveles de "redondez" de
una cifra. Nació de dos fallos de la v1.15.0: una señal que se contaba dos
veces y un índice que podía señalar el pago como si fuera el cambio.
- **test6** — el analizador completo. Coherencia de la nota (que ninguna
transacción pueda puntuar negativo antes del clamp), los dos checks nuevos
—polvo gastado junto a otras monedas y consolidación pura— y que la guardia
de CoinJoin desactive las heurísticas que no aplican dentro de una mezcla.
Las cuatro primeras prueban criptografía; las dos últimas, heurísticas. Se
ejecutan igual: `node tests/testN.js`.
## Lo que estas pruebas NO cubren
Las heurísticas (test5, test6) se comprueban contra transacciones construidas
a mano, no contra la cadena real. Eso demuestra que la lógica hace lo que dice
—y ha bastado para encontrar fallos reales— pero no dice nada sobre cuántas
veces acierta ahí fuera. Medir eso exigiría un conjunto de transacciones reales
con la respuesta conocida de antemano, que es un trabajo distinto y pendiente.
La matemática es correcta, pero eso no es una auditoría. No cubren análisis
formal ni una revisión independiente: quien las escribió conoce la
implementación y comparte sus supuestos, que es justo el sesgo que rompe un