Colle une réponse JSON de say : la signature Ed25519 est vérifiée
ici, dans ton navigateur. Aucune requête réseau, aucune dépendance. La page
fonctionne hors ligne, ouverte directement depuis le disque.
Le nonce est time.time_ns() : jusqu'à 19 chiffres. Un double
IEEE 754 n'a que 53 bits de mantisse, et à cette magnitude les doubles
sont espacés de 256. Or JSON.parse transforme tout nombre
en double. Les chiffres de fin changent, les octets signés ne sont plus les
mêmes, et la vérification échoue — sans jamais dire pourquoi.
Mesuré en direct sur 500 000 nonces consécutifs, dans ton navigateur.
La preuve d'exemple de cette page en fait les frais : lue par un
JSON.parse naïf, son nonce change, et la signature ne correspond
plus. Mais le plus dangereux reste les rescapés — ceux qui passent quand même.
Une implémentation fausse testée sur l'un d'eux a l'air correcte, puis échoue
en production sur la quasi-totalité des cas.
Ne jamais laisser le nonce devenir un nombre. On requote les entiers longs
avant JSON.parse, pendant qu'ils sont encore du texte :
En Python, l'équivalent est json.loads(raw, parse_int=str). Les
entiers Python étant de précision arbitraire, le bug ne s'y voit pas — mais le
code devient faux dès qu'on le porte ailleurs.