Fragments et reçus
Un message ne voyage jamais entier. Il est découpé en fragments qui passent par des nœuds différents, et chaque fragment livré produit un reçu anonyme : la preuve que le travail a été fait, sans dire pour qui.
Reed–Solomon 3 sur 5
Chaque enveloppe complétée est découpée en bandes de k = 3 sur n = 5 avec Reed–Solomon sur GF(256) : sur cinq morceaux, trois quelconques suffisent. Deux nœuds peuvent disparaître, le message arrive quand même.
| Schéma | Encombrement | Probabilité de livraison si chaque route réussit à 95 % |
|---|---|---|
| 4 sur 4, sans redondance | 1,00× | 81,5 % |
| 4 + 1 parité (v1) | 1,25× | 97,7 % |
| 3 sur 5 (v2) | 1,67× | 99,9 % |
La taille du morceau dépend de la taille fixe de l’enveloppe : un tiers, arrondi à 1 Ko, avec un maximum de 24 Ko. Les grandes enveloppes utilisent plusieurs bandes.
Shard = { id, msg, mailbox, stripe, idx, k, n, bucket, data, rh, exp }
id = sha512(msg ‖ stripe ‖ idx)[0..32] msg est aléatoire à chaque envoi
Le morceau ne porte ni la taille réelle du message (elle est dans l’enveloppe, chiffrée) ni rien sur l’expéditeur.
Des boîtes qui changent
Les fragments attendent dans une boîte aux lettres. Chaque appareil a sa graine de boîte, et sa boîte change chaque jour :
boîte(jour) = hex(HMAC-SHA512(mailboxSeed, "day:" + floor(ts / 86 400 000)))[0..40]
L’expéditeur utilise la boîte du jour du destinataire ; le destinataire ouvre celle d’aujourd’hui et celle d’hier. Un nœud ne peut pas relier la boîte du lundi à celle du mardi.
Seul le propriétaire ouvre sa boîte
Ouvrir une boîte ne se signe pas avec l’identité. L’expéditeur ajoute à chaque morceau une marque mbAuth dérivée du secret de boîte du destinataire. Pour ouvrir, le propriétaire présente une preuve signée sur velum/v2/open|<boîte>|<ts>, que le nœud vérifie par rapport à cette marque. Ainsi seul le propriétaire récupère ses morceaux, et le nœud n’apprend pas qui il est.
Preuve de Livraison : le reçu anonyme
Dans l’enveloppe (que seul le destinataire ouvre) se trouve une graine aléatoire rseed. Pour chaque morceau :
secret_i = HMAC-SHA512(rseed, shardId)[0..32]
rh_i = SHA-512(secret_i) ← voyage dans le morceau, en clair
En reconstituant le message, le destinataire révèle chaque secret_i. N’importe qui peut vérifier que SHA-512(secret) == rh, mais personne d’autre ne pouvait connaître le secret : un nœud ne peut pas fabriquer de reçus.
{
"shard": "7a0c…", // shard id
"mailbox": "c2e81f…", // today's rotating mailbox (40 hex)
"rh": "…128 hex…", // sha512(secret), already inside the shard
"secret": "…64 hex…", // HMAC-SHA512(rseed, shardId)[0..32], only the recipient can compute it
"carrier": "vel…", // node that accepted the shard
"courier": "vel…", // node that delivered it
"ts": 1793577600000
}
Le reçu ne porte ni signature ni adresse du destinataire. Chaque reçu donne des crédits :
- 1 crédit au carrier (le nœud qui a accepté le morceau).
- 1 crédit au courier (le nœud qui l’a livré).
- Si c’est le même nœud, 2 crédits.
Des reçus aux réclamations
Avec des milliards de messages par jour, les reçus ne peuvent pas entrer un par un dans les blocs. Chaque nœud regroupe les siens dans un arbre de Merkle (SHA-512) et ne publie que la racine et le total (work.claim). À l’époque suivante, la balise désigne 16 reçus au hasard, et le nœud doit les présenter avec leur secret et leur chemin (work.prove). S’il en manque un, il perd la récompense de l’époque. Détails dans Monter un nœud.
Anti-triche
- Un même morceau ne compte qu’une seule fois.
- Plafond de crédits par époque et par paire (nœud, boîte) : 400.
- Les reçus hors d’une fenêtre de ±15 minutes autour du bloc ne comptent pas.
- Personne ne peut réclamer plus de 1,5 fois ce qui est attendu pour son poids dans le tirage.
- Inventer du trafic ne rapporte rien : pour générer des reçus, il faut ouvrir les enveloppes, ce que seul un vrai destinataire peut faire.
- Les nœuds qui transportent chaque morceau sont issus d’un tirage public de 3 candidats ; le client choisit seulement le plus proche des trois.
Effacement
Dès qu’un nœud voit un reçu valide pour un morceau, il l’efface. Le reçu se propage sur le réseau et tous les nœuds qui en avaient une copie l’effacent aussi. Si personne ne récupère un morceau, il est détruit au bout de 7 jours.