Engagements de Pedersen
Comment additionner des montants que personne ne voit et vérifier que le solde est équilibré
Un montant v est caché dans le point C = y·G + v·H, où y est un « masque » aléatoire. Les engagements s’additionnent : la somme des engagements engage la somme des montants. Le réseau vérifie que Σ inputs − Σ outputs − fee·H est un engagement à zéro sans apprendre aucun montant.
Ce qu’est un engagement
Un engagement (commitment), c’est une « enveloppe scellée contenant un nombre ». Il a deux propriétés :
- Dissimulation (hiding) : on ne peut pas connaître le nombre à partir de l’enveloppe.
- Contrainte (binding) : on ne peut pas ouvrir l’enveloppe en prétendant qu’elle contient un autre nombre.
Un engagement de Pedersen sur une courbe elliptique :
Sans le masque y, on aurait C = v·H, et le montant serait facile à retrouver par force brute (il n’y a pas tant de montants possibles). Le masque rend C indiscernable d’un point aléatoire.
Pourquoi le second générateur H est important
H est obtenu en hachant G vers un point, si bien que personne ne connaît de k tel que H = k·G. Si quelqu’un connaissait k, il pourrait « rouvrir » un engagement : y·G + v·H = (y + k(v − v'))·G + v'·H — et créer de l’argent à partir de rien. C’est précisément l’ignorance de k qui garantit la contrainte.
Homomorphisme : additionner à l’aveugle
La somme de deux enveloppes est une enveloppe contenant la somme. Le réseau peut donc vérifier la conservation :
Il reste à prouver que la différence est réellement de la forme z·G (et non z·G + quelque chose·H). Il suffit de signer en l’utilisant comme clé publique : la signature ne fonctionne que si l’on connaît z et qu’il n’y a pas de composante H. Les frais sont publics, leur engagement est donc simplement fee·H, sans masque.
Pseudo-sorties : comment cela fonctionne avec les anneaux
Il y a un hic : l’entrée est un anneau de 16 sorties, et on ne peut pas dire quel engagement est le vrai. La solution de RingCT est l’engagement de pseudo-sortie C̃ :
- pour chaque entrée, l’expéditeur crée un nouvel engagement
C̃ = y'·G + v·Havec le même montant mais un nouveau masque ; - les masques sont choisis de sorte que
Σ C̃ = Σ C_out + fee·Hexactement (l’équilibre est vérifié à l’aide des pseudo-sorties) ; - dans CLSAG, pour chaque membre de l’anneau, on prouve que
C_i − C̃est un engagement à zéro pour le membre réel :C_π − C̃ = (y − y')·G.
Ainsi, la signature en anneau prouve à la fois la propriété de la sortie et l’égalité entre le montant de la pseudo-sortie et celui de l’entrée réelle.
Comment le destinataire apprend le montant et le masque
L’expéditeur et le destinataire partagent le secret Hs(8rA ‖ i) (voir adresses à usage unique). Ils en dérivent :
amount_enc = v ⊕ Keccak( "amount" ‖ Hs(8rA ‖ i) )[0..8]
Le montant chiffré (8 octets) se trouve dans la transaction. Le destinataire déchiffre v, calcule y et vérifie que y·G + v·H correspond à C sur la blockchain.
Qu’est-ce qui empêche un montant négatif ?
Tous les calculs se font modulo l. « −1 », c’est l − 1, un nombre énorme. On pourrait créer une sortie de 1000 XMR et une sortie de « −999 XMR », l’équilibre tiendrait, et 999 XMR apparaîtraient de nulle part. Les engagements ne le voient pas. C’est pourquoi chaque sortie est accompagnée d’une preuve d’intervalle.